retold-harness 1.0.4 → 1.0.6

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 (77) hide show
  1. package/.vscode/launch.json +18 -0
  2. package/.vscode/settings.json +19 -0
  3. package/Dockerfile_LUXURYCode +10 -51
  4. package/Dockerfile_Service +51 -0
  5. package/README.md +131 -39
  6. package/docker_scripts/MySQL-Laden-Entry-ServicesOnly.sh +11 -0
  7. package/docker_scripts/Service-Only_docker-entrypoint-combined.sh +35 -0
  8. package/docs/.nojekyll +0 -0
  9. package/docs/README.md +48 -0
  10. package/docs/_coverpage.md +11 -0
  11. package/docs/_sidebar.md +20 -0
  12. package/docs/behavior-injection.md +100 -0
  13. package/docs/configuration.md +107 -0
  14. package/docs/docker.md +78 -0
  15. package/docs/endpoints.md +111 -0
  16. package/docs/entities.md +125 -0
  17. package/docs/filtering.md +103 -0
  18. package/docs/index.html +29 -0
  19. package/docs/luxury-code.md +52 -0
  20. package/docs/quickstart.md +60 -0
  21. package/docs/schema.md +66 -0
  22. package/docs/testing.md +70 -0
  23. package/images/API-Author-Susans.png +0 -0
  24. package/package.json +13 -8
  25. package/source/Retold-Harness.js +4 -20
  26. package/source/configuration-bookstore-serve-api.js +10 -1
  27. package/source/model/MeadowModel-Extended.json +4310 -0
  28. package/source/model/MeadowModel.json +523 -0
  29. package/source/model/ddl/BookStore.ddl +52 -5
  30. package/source/model/{generated_documentation → doc}/Dictionary.md +6 -3
  31. package/source/model/{generated_documentation → doc}/Model-Author.md +6 -5
  32. package/source/model/{generated_documentation → doc}/Model-Book.md +6 -6
  33. package/source/model/{generated_documentation → doc}/Model-BookAuthorJoin.md +4 -4
  34. package/source/model/{generated_documentation → doc}/Model-BookPrice.md +6 -6
  35. package/source/model/doc/Model-BookStore.md +25 -0
  36. package/source/model/doc/Model-BookStoreInventory.md +26 -0
  37. package/source/model/{generated_documentation → doc}/Model-Review.md +9 -8
  38. package/source/model/doc/Model-User.md +18 -0
  39. package/source/model/{generated_documentation → doc}/ModelChangeTracking.md +4 -1
  40. package/source/model/doc/diagrams/Relationships.dot +22 -0
  41. package/source/model/doc/diagrams/Relationships.png +0 -0
  42. package/source/model/doc/diagrams/RelationshipsFull.dot +22 -0
  43. package/source/model/doc/diagrams/RelationshipsFull.png +0 -0
  44. package/source/model/meadow/MeadowSchemaAuthor.json +447 -0
  45. package/source/model/meadow/MeadowSchemaBook.json +527 -0
  46. package/source/model/meadow/MeadowSchemaBookAuthorJoin.json +335 -0
  47. package/source/model/meadow/MeadowSchemaBookPrice.json +511 -0
  48. package/source/model/meadow/MeadowSchemaBookStore.json +511 -0
  49. package/source/model/meadow/MeadowSchemaBookStoreInventory.json +527 -0
  50. package/source/model/meadow/MeadowSchemaReview.json +479 -0
  51. package/source/model/meadow/MeadowSchemaUser.json +399 -0
  52. package/source/model/{sql_create/BookStore-CreateDatabase.mysql.sql → mysql_create/MeadowModel-CreateMySQLDatabase.mysql.sql} +84 -10
  53. package/source/model/{manual_scripts/DropTables.sql → mysql_create/MeadowModel-DropMySQLTables.sql} +2 -1
  54. package/source/model/mysql_create/MeadowModel-PopulateDatabase.sql +28 -0
  55. package/source/model/{manual_scripts/MySQL-Security.sql → mysql_create/MySQL-Configure-Security.sql} +1 -1
  56. package/test/RetoldHarness_tests.js +2229 -0
  57. package/.config/configstore/update-notifier-npm.json +0 -4
  58. package/source/model/Model-Extended.json +0 -915
  59. package/source/model/Model.json +0 -280
  60. package/source/model/bookstore-api-endpoint-exercises.paw +0 -0
  61. package/source/model/generated_diagram/README.md +0 -1
  62. package/source/model/generated_diagram/Stricture_Output.dot +0 -13
  63. package/source/model/generated_diagram/Stricture_Output.png +0 -0
  64. package/source/model/generated_documentation/README.md +0 -1
  65. package/source/model/manual_scripts/MySQL-Laden-Entry.sh +0 -17
  66. package/source/model/manual_scripts/README.md +0 -2
  67. package/source/model/manual_scripts/my.cnf +0 -4
  68. package/source/model/meadow/Model-MeadowSchema-Author.json +0 -220
  69. package/source/model/meadow/Model-MeadowSchema-Book.json +0 -268
  70. package/source/model/meadow/Model-MeadowSchema-BookAuthorJoin.json +0 -172
  71. package/source/model/meadow/Model-MeadowSchema-BookPrice.json +0 -260
  72. package/source/model/meadow/Model-MeadowSchema-Review.json +0 -236
  73. package/source/model/meadow/README.md +0 -1
  74. package/source/model/sql_create/BookStore-DeleteAndRepopulateTables.sql +0 -194
  75. package/source/model/sql_create/MySQL-Security.sql +0 -5
  76. package/source/model/sql_create/README.md +0 -1
  77. /package/source/model/{Model-PICT.json → MeadowModel-PICT.json} +0 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+
8
+ {
9
+ "type": "node",
10
+ "request": "launch",
11
+ "name": "Launch Program",
12
+ "skipFiles": [
13
+ "<node_internals>/**"
14
+ ],
15
+ "program": "${workspaceFolder}/source/Retold-Harness.js"
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "sqltools.connections": [
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 server",
14
+ "database": "bookstore",
15
+ "username": "root",
16
+ "password": "123456789"
17
+ }
18
+ ]
19
+ }
@@ -11,61 +11,20 @@ RUN sudo apt install vim curl tmux -y
11
11
 
12
12
  RUN echo "Building development image..."
13
13
 
14
- RUN echo "...installing vscode extensions..."
15
-
16
- # Mocha unit testing in the sidebar
17
- RUN code-server --install-extension hbenl.vscode-mocha-test-adapter
18
- RUN code-server --install-extension hbenl.test-adapter-converter
19
- RUN code-server --install-extension hbenl.vscode-test-explorer
20
-
21
- # Magic indentation rainbow
22
- RUN code-server --install-extension oderwat.indent-rainbow
23
- RUN code-server --install-extension dbaeumer.vscode-eslint
24
-
25
- # Contextual git
26
- RUN code-server --install-extension eamodio.gitlens
27
-
28
- # Other extensions (uncomment them to have them automagic, or run this from a terminal to install in the container):
29
-
30
- # SQL Tools
31
- RUN code-server --install-extension mtxr.sqltools
32
- RUN code-server --install-extension mtxr.sqltools-driver-mysql
33
-
34
- # Microsoft's AI code completion
35
- # RUN code-server --install-extension VisualStudioExptTeam.vscodeintellicode
36
-
37
- # Live server -- make sure to open up the port on the docker image
38
- # RUN code-server --install-extension ritwickdey.LiveServer
39
-
40
- # Quick link to required modules' documentation
41
- # RUN code-server --install-extension bengreenier.vscode-node-readme
42
-
43
- # Switch up fonts
44
- # RUN code-server --install-extension evan-buss.font-switcher
45
-
46
- # Icons
47
- # RUN code-server --install-extension vscode-icons-team.vscode-icons
48
- # RUN code-server --install-extension PKief.material-icon-theme
49
-
50
- # Hover over CSS colors to see them previewed
51
- # RUN code-server --install-extension bierner.color-info
52
-
53
- # An easy on the eyes color theme
54
- # RUN code-server --install-extension daylerees.rainglow
55
-
56
14
  RUN echo "...configuring mariadb (mysql) server...."
57
15
  RUN sudo apt install default-mysql-server default-mysql-client -y
58
16
  RUN sudo sed -i "s|bind-address|#bind-address|g" /etc/mysql/mariadb.conf.d/50-server.cnf
59
- ADD ./source/model/sql_create/MySQL-Security.sql /home/coder/MySQL-Configure-Security.sql
17
+ ADD ./source/model/mysql_create/MySQL-Configure-Security.sql /home/coder/MySQL-Configure-Security.sql
60
18
  ADD ./docker_scripts/MySQL-Laden-Entry.sh /usr/bin/MySQL-Laden-Entry.sh
61
19
  RUN ( sudo mysqld_safe --skip-grant-tables --skip-networking & ) && sleep 5 && mysql -u root < /home/coder/MySQL-Configure-Security.sql
62
20
 
63
21
  # Import the initial database
64
- COPY ./source/model/sql_create/BookStore-CreateDatabase.mysql.sql /home/coder/MySQL-Create-Databases.sql
65
- COPY ./source/model/sql_create/BookStore-DeleteAndRepopulateTables.sql /home/coder/MySQL-Repopulate-Databases.sql
22
+ COPY ./source/model/mysql_create/MeadowModel-CreateMySQLDatabase.mysql.sql /home/coder/MeadowModel-CreateMySQLDatabase.mysql.sql
23
+ COPY ./source/model/mysql_create/MeadowModel-PopulateDatabase.sql /home/coder/MeadowModel-PopulateDatabase.sql
24
+
66
25
  RUN sudo service mariadb restart && sleep 5 && mysql -u root -p"123456789" -e "CREATE DATABASE bookstore;"
67
- RUN sudo service mariadb restart && sleep 5 && mysql -u root -p"123456789" bookstore < /home/coder/MySQL-Create-Databases.sql
68
- RUN sudo service mariadb restart && sleep 5 && mysql -u root -p"123456789" bookstore < /home/coder/MySQL-Repopulate-Databases.sql
26
+ RUN sudo service mariadb restart && sleep 5 && mysql -u root -p"123456789" bookstore < /home/coder/MeadowModel-CreateMySQLDatabase.mysql.sql
27
+ RUN sudo service mariadb restart && sleep 5 && mysql -u root -p"123456789" bookstore < /home/coder/MeadowModel-PopulateDatabase.sql
69
28
 
70
29
  RUN echo "...mapping library specific volumes..."
71
30
 
@@ -81,10 +40,10 @@ RUN touch ~/.bashrc && chmod +x ~/.bashrc
81
40
  RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
82
41
  RUN chmod +x ~/.nvm/nvm.sh
83
42
 
84
- RUN echo "...installing node version 14 as the default..."
85
- RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm install 14
86
- RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm alias default 14
43
+ RUN echo "...installing node version 20 as the default..."
44
+ RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm install 20
45
+ RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm alias default 20
87
46
 
88
47
  WORKDIR /home/coder/retold-harness
89
48
 
90
- ENTRYPOINT ["/usr/bin/MySQL-Laden-Entry.sh"]
49
+ ENTRYPOINT ["/usr/bin/MySQL-Laden-Entry.sh"]
@@ -0,0 +1,51 @@
1
+ FROM debian:latest
2
+ MAINTAINER steven velozo
3
+
4
+ RUN echo "...installing debian dependencies..."
5
+ RUN apt update
6
+ RUN apt install vim curl tmux -y
7
+
8
+ RUN echo "Building service image..."
9
+
10
+ RUN echo "...configuring mariadb (mysql) server...."
11
+ RUN apt install default-mysql-server default-mysql-client -y
12
+ RUN sed -i "s|bind-address|#bind-address|g" /etc/mysql/mariadb.conf.d/50-server.cnf
13
+ ADD ./source/model/mysql_create/MySQL-Configure-Security.sql /home/coder/MySQL-Configure-Security.sql
14
+ ADD ./docker_scripts/MySQL-Laden-Entry.sh /usr/bin/MySQL-Laden-Entry.sh
15
+ RUN ( mysqld_safe --skip-grant-tables --skip-networking & ) && sleep 5 && mysql -u root < /home/coder/MySQL-Configure-Security.sql
16
+
17
+ # Import the initial database
18
+ COPY ./source/model/mysql_create/MeadowModel-CreateMySQLDatabase.mysql.sql /home/coder/MeadowModel-CreateMySQLDatabase.mysql.sql
19
+ COPY ./source/model/mysql_create/MeadowModel-PopulateDatabase.sql /home/coder/MeadowModel-PopulateDatabase.sql
20
+
21
+ RUN service mariadb restart && sleep 5 && mysql -u root -p"123456789" -e "CREATE DATABASE bookstore;"
22
+ RUN service mariadb restart && sleep 5 && mysql -u root -p"123456789" bookstore < /home/coder/MeadowModel-CreateMySQLDatabase.mysql.sql
23
+ RUN service mariadb restart && sleep 5 && mysql -u root -p"123456789" bookstore < /home/coder/MeadowModel-PopulateDatabase.sql
24
+
25
+ RUN echo "...mapping library specific volumes..."
26
+
27
+ VOLUME /retold-harness
28
+
29
+ SHELL ["/bin/bash", "-c"]
30
+
31
+ RUN echo "...installing node version manager..."
32
+
33
+ # Because there is a .bashrc chicken/egg problem, we will create one here to simulate logging in. This is not great.
34
+ RUN touch /root/.bashrc && chmod +x /root/.bashrc
35
+ RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
36
+
37
+ ENV NODE_VERSION=20
38
+ ENV NVM_DIR=/root/.nvm
39
+ RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
40
+ RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
41
+ RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
42
+ ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
43
+ RUN . /root/.nvm/nvm.sh && source /root/.bashrc && node --version
44
+ RUN . /root/.nvm/nvm.sh && npm --version
45
+
46
+ WORKDIR /retold-harness
47
+
48
+ RUN echo "...configuring entrypoint..."
49
+
50
+ COPY ./docker_scripts/MySQL-Laden-Entry-ServicesOnly.sh /root/MySQL-Laden-Entry-ServicesOnly.sh
51
+ ENTRYPOINT ["/root/MySQL-Laden-Entry-ServicesOnly.sh"]
package/README.md CHANGED
@@ -1,77 +1,127 @@
1
1
  # Retold Harness
2
2
 
3
- A basic set of API endpoints that contains Books, Authors, Joins and links to
4
- images for the cover of each book. Useful for more complex harnesses.
3
+ > A self-contained REST API harness for the Retold framework
5
4
 
6
- Entirely self-contained.
5
+ Retold Harness brings together the full Retold stack into a running bookstore application. Point a browser at `http://localhost:8086/1.0/Books/0/100` and you have a working REST API backed by 10,000+ book records, author joins, pricing, store inventory, and reviews -- all auto-generated from a Stricture DDL.
7
6
 
8
- ## Getting up and Running
7
+ ## Features
9
8
 
10
- This package requires Docker to be installed on your workstation. You can get
11
- things running by typing the following commands:
9
+ - **8-Entity Bookstore Model** - Users, Books, Authors, Joins, Prices, Stores, Inventory, and Reviews
10
+ - **Auto-Generated CRUD** - Every entity gets Create, Read, Reads, Update, Delete, Count, Schema, and New endpoints
11
+ - **Author Enrichment** - Single Book reads include an Authors array via behavior injection
12
+ - **Pre-Loaded Data** - 10,000+ book records with associated authors for realistic testing
13
+ - **Docker Containerized** - MariaDB database and API server in a single container
14
+ - **Luxury Code IDE** - Browser-based VS Code for in-container development
15
+ - **SQLite Testing** - In-memory test suite requires no external database
12
16
 
13
- ### 1) Clone the code from github:
17
+ ## Quick Start (Docker)
14
18
 
15
- ```
19
+ ```bash
16
20
  git clone https://github.com/stevenvelozo/retold-harness
21
+ cd retold-harness
22
+ npm run docker-dev-build
23
+ npm run docker-dev-run
17
24
  ```
18
25
 
26
+ The REST API is now at `http://localhost:8086`.
19
27
 
20
- ### 2) Build the docker image:
28
+ ![Building the docker image](./images/Docker-Build-Image.png)
21
29
 
22
- _This can take a bit of time, depending on your connection speed and resources._
30
+ ## Quick Start (Manual)
23
31
 
24
- ```
25
- npm run docker-dev-build
32
+ ```bash
33
+ # Start a MariaDB container
34
+ docker run -d --name mariadb -p 3306:3306 \
35
+ -e MARIADB_ROOT_PASSWORD=123456789 \
36
+ -e MARIADB_DATABASE=bookstore \
37
+ mariadb:latest
38
+
39
+ # Create the tables
40
+ cat ./source/model/mysql_create/MeadowModel-CreateMySQLDatabase.mysql.sql \
41
+ | docker exec -i mariadb mariadb -u root -p123456789 bookstore
42
+
43
+ # Install and start
44
+ npm install
45
+ npm start
26
46
  ```
27
47
 
28
- ![Building the docker image](./images/Docker-Build-Image.png)
48
+ Alternatively, if using a true MySQL image:
29
49
 
30
- ### 3) Create and launch the docker container:
50
+ ```bash
51
+ cat ./source/model/mysql_create/MeadowModel-CreateMySQLDatabase.mysql.sql \
52
+ | docker exec -i mariadb mysql -u root -p123456789 bookstore
53
+ ```
31
54
 
32
- _This can also take a bit of time....._
55
+ ## Architecture
33
56
 
34
57
  ```
35
- npm run docker-dev-run
58
+ Retold Harness
59
+ ├── Retold Data Service
60
+ │ ├── Orator + Restify (HTTP Server, port 8086)
61
+ │ ├── Meadow (DAL for each entity)
62
+ │ │ └── Provider (MySQL / SQLite)
63
+ │ └── Meadow Endpoints (REST Routes)
64
+ │ └── Behavior Injection (Author enrichment)
65
+ ├── Data Model (8 entities from Stricture DDL)
66
+ └── Docker Environment
67
+ ├── MariaDB (pre-loaded bookstore database)
68
+ └── Luxury Code (browser VS Code, port 20001)
36
69
  ```
37
70
 
38
- ![Launching the docker container](./images/Docker-Run-Container.png)
71
+ ## REST API Examples
39
72
 
40
- ![The launched container in the Docker UI](./images/Docker-Container-Launched.png)
73
+ ### List the first 100 books: `http://localhost:8086/1.0/Books/0/100`
41
74
 
75
+ ![The first 100 Books](./images/API-Book-List.png)
42
76
 
43
- ## After the docker container is running there is quite a bit available:
77
+ ### Get a single book with authors: `http://localhost:8086/1.0/Book/1`
44
78
 
45
- * a REST web API serving JSON on port 8086
46
- * a browser-based visual studio code environment ready to run node applications
47
- * a mariadb instance, preloaded with 10,000 Book records joined to their Author records
48
- * a partridge
49
- * a pear tree
79
+ When fetching a single book, the response includes an `Authors` array populated via the behavior injection hook in `source/Retold-Harness.js`. In the multi-record list, the array is not included because the hook is only on the singular Read endpoint.
50
80
 
51
- ### This all fits in less than 500 meg of RAM, and uses virtually no processor power
81
+ ![Book 1](./images/API-Book-First.png)
52
82
 
53
- ![Docker statistics after a few minutes of running](./images/Docker-Container-Resources.png)
83
+ ### Filter authors by name: `http://localhost:8086/1.0/Authors/FilteredTo/FBV~Name~LK~Susan%25/0/10`
54
84
 
55
- ## Some REST API Examples
85
+ ![The first 10 Susans](./images/API-Author-Susans.png)
56
86
 
57
- The REST endpoints are provided by the [meadow-endpoints](https://www.npmjs.com/package/meadow-endpoints) library on NPM. Some examples of queries you can make:
87
+ ### Count books by genre
58
88
 
59
- ### List the first 100 Books in the database: (http://localhost:8086/1.0/Books/0/100)
89
+ ```
90
+ GET http://localhost:8086/1.0/Books/Count/FilteredTo/FBV~Genre~EQ~Science Fiction
91
+ ```
60
92
 
61
- ![The first 100 Books](./images/API-Book-List.png)
62
- ### Get the book with `IDBook` 1: (http://localhost:8086/1.0/Book/1)
93
+ ## Data Model
63
94
 
64
- You will notice that when requesting a single book, there is an `Authors` array populated with the connected authors for the particular book. But in the list, the array was not filled out. This is because in meadow-endpoints there is a post-operation behavior hook only attached to the read single record endpoint. This is reflected in the `/source/Retold-Harness.js` code file in lines 14-41.
95
+ | Entity | Columns | Description |
96
+ |--------|---------|-------------|
97
+ | User | 8 | System user accounts |
98
+ | Book | 16 | Books with title, genre, ISBN, language, cover image |
99
+ | Author | 11 | Authors with name and optional user link |
100
+ | BookAuthorJoin | 4 | Many-to-many join between Books and Authors |
101
+ | BookPrice | 15 | Pricing periods with discount and coupon support |
102
+ | BookStore | 15 | Physical store locations with address |
103
+ | BookStoreInventory | 16 | Stock levels per book per store |
104
+ | Review | 13 | User reviews with text and rating |
65
105
 
66
- ![Book 1](./images/API-Book-First.png)
106
+ ## Docker Services
67
107
 
68
- ### List the first 10 Authors in the database whose name begins with `Susan`: (http://localhost:8086/1.0/Authors/FilteredTo/FBV~Name~LK~Susan%25/0/10)
108
+ | Port | Service |
109
+ |------|---------|
110
+ | 8086 | REST API |
111
+ | 31306 | MariaDB (mapped from 3306) |
112
+ | 20001 | Luxury Code (VS Code in browser) |
69
113
 
70
- ![The first 10 Susans](./images/API-Author-Susans.png)
114
+ ### Database Credentials
115
+
116
+ | Setting | Value |
117
+ |---------|-------|
118
+ | User | `root` |
119
+ | Password | `123456789` |
120
+ | Database | `bookstore` |
71
121
 
72
122
  ## Luxury Code
73
123
 
74
- Luxury code is a set of tools to provide easy debugging and test running regardless of environment. These tools leverage the code-server browser implementation of the Visual Studio Code editor. The first time you launch the browser editor, you will be asked for a password. The password is: `luxury`
124
+ Luxury Code provides a browser-based VS Code environment inside the Docker container. Open `http://localhost:20001` after launching the container. Password: `luxury`
75
125
 
76
126
  ![Launching Luxury Code requires a Password: luxury](./images/vscode-Login.png)
77
127
 
@@ -79,12 +129,54 @@ Luxury code is a set of tools to provide easy debugging and test running regardl
79
129
 
80
130
  ## MySQL
81
131
 
82
- The docker image also exposes a MySQL server (it's actually MariaDB but nobody is the wiser). You can connect to and query this database directly from your tool of choice or other applications. The user is: `root`, the port is `3306` and the password is: `123456789`
132
+ The Docker image exposes a MariaDB server. Connect with your tool of choice using the credentials above.
83
133
 
84
134
  ![MySQL Connection Info](./images/SQL-Connection.png)
85
135
 
86
136
  ![MySQL Query](./images/SQL-Query.png)
87
137
 
88
- ## Customizing your Environment
138
+ ## Source Code
139
+
140
+ The harness is intentionally minimal:
141
+
142
+ - `source/Retold-Harness.js` (47 lines) -- Initializes Fable, creates the data service, installs the Author enrichment hook
143
+ - `source/configuration-bookstore-serve-api.js` (41 lines) -- Configuration with MySQL connection details and server port
144
+ - `source/model/` -- Compiled Stricture model, DDL source, SQL scripts, and sample data
145
+
146
+ ## Building the Model
147
+
148
+ To recompile the DDL after schema changes:
149
+
150
+ ```bash
151
+ npm run build-model
152
+ ```
153
+
154
+ ## Testing
155
+
156
+ ```bash
157
+ npm test
158
+ ```
159
+
160
+ The test suite contains 90 tests covering all 8 entities, behavior injection, DAL access, filtering, pagination, and soft deletes. Tests use in-memory SQLite and require no external database.
161
+
162
+ ## Documentation
163
+
164
+ Detailed documentation is available in the `docs/` folder and can be served locally:
165
+
166
+ ```bash
167
+ npx docsify-cli serve docs
168
+ ```
169
+
170
+ ## Customizing
171
+
172
+ All ports, passwords, and configuration are in `source/configuration-bookstore-serve-api.js` and `package.json`. Docker port mappings are in the npm scripts.
173
+
174
+ ## Related Packages
89
175
 
90
- If you dislike the ports, passwords or anything else about this configuration all the code is readily available. In the `package.json` file, the two convenience docker spin-up commands are there. This is where you would change the port mapping for the API server, SQL server and other services. Remember.... you broke it, you bought it.
176
+ - [retold-data-service](https://github.com/stevenvelozo/retold-data-service) - All-in-one data service
177
+ - [meadow](https://github.com/stevenvelozo/meadow) - Data access layer and ORM
178
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Automatic REST endpoint generation
179
+ - [foxhound](https://github.com/stevenvelozo/foxhound) - Query DSL for SQL generation
180
+ - [stricture](https://github.com/stevenvelozo/stricture) - Schema definition language
181
+ - [orator](https://github.com/stevenvelozo/orator) - API server abstraction
182
+ - [fable](https://github.com/stevenvelozo/fable) - Service provider framework
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ service mariadb restart
4
+
5
+ sleep 2
6
+
7
+ source /root/.bashrc
8
+ npm install
9
+ npm start
10
+
11
+ node ./source/Retold-Harness.js
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # This script will:
5
+ # 1. Start MariaDB (via the official entrypoint) in the background
6
+ # 2. Wait until MariaDB is ready
7
+ # 3. Start the Node app using pm2-runtime
8
+
9
+ # If first argument looks like an option, assume it's for mysqld (same behavior as official entrypoint)
10
+ if [ "${1:0:1}" = '-' ]; then
11
+ set -- mysqld "$@"
12
+ fi
13
+
14
+ # Start MariaDB using the original entrypoint in the background
15
+ # The official MariaDB image's entrypoint is still at this path
16
+ /usr/local/bin/docker-entrypoint.sh mysqld "$@" &
17
+
18
+ # Wait for MariaDB to be ready
19
+ echo "Waiting for MariaDB to be ready..."
20
+ until mariadb-admin ping -h "127.0.0.1" --silent; do
21
+ sleep 1
22
+ done
23
+ echo "MariaDB is up."
24
+
25
+ # Load nvm and use Node 22
26
+ export NVM_DIR=/usr/local/nvm
27
+ # shellcheck disable=SC1091
28
+ . "$NVM_DIR/nvm.sh"
29
+
30
+ # Move to app directory
31
+ cd /usr/src/app
32
+
33
+ echo "Starting Node app with pm2-runtime..."
34
+ # pm2-runtime keeps the process in the foreground (PID 1) for Docker
35
+ exec pm2-runtime ecosystem.config.js
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Retold Harness
2
+
3
+ A self-contained REST API harness for the [Retold](https://github.com/stevenvelozo/retold) framework. It serves a complete bookstore data model with auto-generated CRUD endpoints, pre-loaded sample data, and a containerized development environment.
4
+
5
+ ## What It Does
6
+
7
+ Retold Harness brings together several Retold modules into a running application:
8
+
9
+ - **[Retold Data Service](https://github.com/stevenvelozo/retold-data-service)** orchestrates the stack
10
+ - **[Meadow](https://github.com/stevenvelozo/meadow)** provides the data access layer
11
+ - **[Meadow Endpoints](https://github.com/stevenvelozo/meadow-endpoints)** generates REST routes
12
+ - **[Orator](https://github.com/stevenvelozo/orator)** serves the HTTP API
13
+ - **[Stricture](https://github.com/stevenvelozo/stricture)** defines the schema
14
+
15
+ ## Features
16
+
17
+ - **8-Entity Bookstore Model** -- Users, Books, Authors, Joins, Prices, Stores, Inventory, and Reviews
18
+ - **Auto-Generated CRUD** -- Every entity gets Create, Read, Reads, Update, Delete, Count, Schema, and New endpoints
19
+ - **Author Enrichment** -- Single Book reads are enriched with related Author data via behavior injection
20
+ - **Pre-Loaded Data** -- 10,000+ book records with associated authors for realistic testing
21
+ - **Docker Containerized** -- MariaDB database and API server in a single container
22
+ - **Luxury Code IDE** -- Browser-based VS Code for in-container development
23
+
24
+ ## Architecture
25
+
26
+ ```
27
+ Retold Harness
28
+ ├── Retold Data Service
29
+ │ ├── Orator + Restify (HTTP Server, port 8086)
30
+ │ ├── Meadow (DAL for each entity)
31
+ │ │ └── Provider (MySQL / SQLite)
32
+ │ └── Meadow Endpoints (REST Routes)
33
+ │ └── Behavior Injection (Author enrichment)
34
+ ├── Data Model (8 entities from Stricture DDL)
35
+ └── Docker Environment
36
+ ├── MariaDB (pre-loaded bookstore database)
37
+ └── Luxury Code (browser VS Code, port 20001)
38
+ ```
39
+
40
+ ## Related Packages
41
+
42
+ - [retold-data-service](https://github.com/stevenvelozo/retold-data-service) -- All-in-one data service
43
+ - [meadow](https://github.com/stevenvelozo/meadow) -- Data access layer
44
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) -- REST endpoint generation
45
+ - [foxhound](https://github.com/stevenvelozo/foxhound) -- Query DSL
46
+ - [stricture](https://github.com/stevenvelozo/stricture) -- Schema definition language
47
+ - [orator](https://github.com/stevenvelozo/orator) -- API server abstraction
48
+ - [fable](https://github.com/stevenvelozo/fable) -- Service provider framework
@@ -0,0 +1,11 @@
1
+ # Retold Harness <small>1.0</small>
2
+
3
+ > A self-contained REST API harness for the Retold framework
4
+
5
+ - Fully containerized bookstore REST API
6
+ - 8 entities with 10,000+ pre-loaded records
7
+ - Author enrichment via behavior injection
8
+ - Browser-based VS Code development environment
9
+
10
+ [Getting Started](#retold-harness)
11
+ [GitHub](https://github.com/stevenvelozo/retold-harness)
@@ -0,0 +1,20 @@
1
+ - Getting Started
2
+ - [Overview](/)
3
+ - [Quick Start](quickstart.md)
4
+ - [Docker Setup](docker.md)
5
+
6
+ - Data Model
7
+ - [Schema Overview](schema.md)
8
+ - [Entity Reference](entities.md)
9
+
10
+ - API
11
+ - [REST Endpoints](endpoints.md)
12
+ - [Filtering & Pagination](filtering.md)
13
+
14
+ - Customization
15
+ - [Behavior Injection](behavior-injection.md)
16
+ - [Configuration](configuration.md)
17
+
18
+ - Development
19
+ - [Testing](testing.md)
20
+ - [Luxury Code IDE](luxury-code.md)
@@ -0,0 +1,100 @@
1
+ # Behavior Injection
2
+
3
+ The harness demonstrates behavior injection by enriching single Book reads with Author data. This is the core customization pattern for Meadow Endpoints.
4
+
5
+ ## How It Works
6
+
7
+ In `source/Retold-Harness.js`, a `Read-PostOperation` hook is installed on the Book endpoint after initialization:
8
+
9
+ ```javascript
10
+ _Fable.MeadowEndpoints.Book.controller.BehaviorInjection.setBehavior('Read-PostOperation',
11
+ (pRequest, pRequestState, fRequestComplete) =>
12
+ {
13
+ // 1. Find join records for this book
14
+ _Fable.DAL.BookAuthorJoin.doReads(
15
+ _Fable.DAL.BookAuthorJoin.query.addFilter('IDBook', pRequestState.Record.IDBook),
16
+ (pJoinError, pJoinQuery, pJoinRecords) =>
17
+ {
18
+ // 2. Collect author IDs from the join records
19
+ let tmpAuthorList = pJoinRecords.map(j => j.IDAuthor);
20
+
21
+ if (tmpAuthorList.length < 1)
22
+ {
23
+ pRequestState.Record.Authors = [];
24
+ return fRequestComplete();
25
+ }
26
+
27
+ // 3. Load the actual Author records
28
+ _Fable.DAL.Author.doReads(
29
+ _Fable.DAL.Author.query.addFilter('IDAuthor', tmpAuthorList, 'IN'),
30
+ (pError, pQuery, pAuthors) =>
31
+ {
32
+ // 4. Attach to the response record
33
+ pRequestState.Record.Authors = pAuthors;
34
+ return fRequestComplete();
35
+ });
36
+ });
37
+ });
38
+ ```
39
+
40
+ ## Result
41
+
42
+ When you fetch a single book:
43
+
44
+ ```
45
+ GET /1.0/Book/1
46
+ ```
47
+
48
+ The response includes an `Authors` array:
49
+
50
+ ```json
51
+ {
52
+ "IDBook": 1,
53
+ "Title": "Dune",
54
+ "Genre": "Science Fiction",
55
+ "Authors": [
56
+ {
57
+ "IDAuthor": 42,
58
+ "Name": "Frank Herbert"
59
+ }
60
+ ]
61
+ }
62
+ ```
63
+
64
+ When you fetch multiple books (`/1.0/Books/0/10`), the Authors array is **not** included because the hook is only on the singular Read, not the plural Reads.
65
+
66
+ ## Available Hook Points
67
+
68
+ Each entity supports pre- and post-operation hooks:
69
+
70
+ | Hook | When |
71
+ |------|------|
72
+ | `Create-PreOperation` | Before a record is created |
73
+ | `Create-PostOperation` | After a record is created |
74
+ | `Read-PreOperation` | Before a single record read |
75
+ | `Read-PostOperation` | After a single record read |
76
+ | `Reads-PreOperation` | Before a multi-record read |
77
+ | `Reads-PostOperation` | After a multi-record read |
78
+ | `Update-PreOperation` | Before a record is updated |
79
+ | `Update-PostOperation` | After a record is updated |
80
+ | `Delete-PreOperation` | Before a record is deleted |
81
+ | `Delete-PostOperation` | After a record is deleted |
82
+ | `Count-PreOperation` | Before a count query |
83
+ | `Count-PostOperation` | After a count query |
84
+
85
+ ## Accessing Request State
86
+
87
+ The callback receives three arguments:
88
+
89
+ | Argument | Description |
90
+ |----------|-------------|
91
+ | `pRequest` | The HTTP request object |
92
+ | `pRequestState` | Contains `Record`, `RecordToCreate`, `Query`, `SessionData` |
93
+ | `fRequestComplete` | Callback: pass `false` to continue, `true` to signal an error |
94
+
95
+ ## Removing a Behavior
96
+
97
+ ```javascript
98
+ delete _Fable.MeadowEndpoints.Book.controller
99
+ .BehaviorInjection._BehaviorFunctions['Read-PostOperation'];
100
+ ```