meadow 2.0.16 → 2.0.18

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,4 +1,4 @@
1
1
  {
2
2
  "optOut": false,
3
- "lastUpdateCheck": 1699195015190
3
+ "lastUpdateCheck": 1761078031905
4
4
  }
@@ -26,47 +26,6 @@ RUN ( sudo mysqld_safe --skip-grant-tables --skip-networking & ) && sleep 5 &&
26
26
  # Import the initial database
27
27
  RUN sudo service mariadb restart && sleep 5 && mysql -u root -p"123456789" -e "CREATE DATABASE FableTest;"
28
28
 
29
- RUN echo "...installing vscode extensions..."
30
- # Mocha unit testing in the sidebar
31
- RUN code-server --install-extension hbenl.vscode-mocha-test-adapter
32
- RUN code-server --install-extension hbenl.test-adapter-converter
33
- RUN code-server --install-extension hbenl.vscode-test-explorer
34
-
35
- # Magic indentation rainbow
36
- RUN code-server --install-extension oderwat.indent-rainbow
37
- RUN code-server --install-extension dbaeumer.vscode-eslint
38
-
39
- # Contextual git
40
- RUN code-server --install-extension eamodio.gitlens
41
-
42
- # Other extensions (uncomment them to have them automagic, or run this from a terminal to install in the container):
43
-
44
- # SQL Tools
45
- RUN code-server --install-extension mtxr.sqltools
46
- RUN code-server --install-extension mtxr.sqltools-driver-mysql
47
-
48
- # Microsoft's AI code completion
49
- # RUN code-server --install-extension VisualStudioExptTeam.vscodeintellicode
50
-
51
- # Live server -- make sure to open up the port on the docker image
52
- # RUN code-server --install-extension ritwickdey.LiveServer
53
-
54
- # Quick link to required modules' documentation
55
- # RUN code-server --install-extension bengreenier.vscode-node-readme
56
-
57
- # Switch up fonts
58
- # RUN code-server --install-extension evan-buss.font-switcher
59
-
60
- # Icons
61
- # RUN code-server --install-extension vscode-icons-team.vscode-icons
62
- # RUN code-server --install-extension PKief.material-icon-theme
63
-
64
- # Hover over CSS colors to see them previewed
65
- # RUN code-server --install-extension bierner.color-info
66
-
67
- # An easy on the eyes color theme
68
- # RUN code-server --install-extension daylerees.rainglow
69
-
70
29
  SHELL ["/bin/bash", "-c"]
71
30
  USER coder
72
31
 
@@ -88,4 +47,4 @@ RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm alias default 14
88
47
 
89
48
  WORKDIR /home/coder/meadow
90
49
 
91
- ENTRYPOINT ["/usr/bin/MySQL-Laden-Entry.sh"]
50
+ ENTRYPOINT ["/usr/bin/MySQL-Laden-Entry.sh"]
package/README.md CHANGED
@@ -1,153 +1,215 @@
1
- Meadow
2
- ======
1
+ # Meadow
3
2
 
4
- A Javascript Data Broker.
3
+ > A data access layer providing magic where you want it, programmability where you don't
5
4
 
6
- Who doesn't love writing the same code over and over again? Good question. Anybody who doesn't probably wants something to do simple data access stuff. And some of the complicated interactions as well. Meadow aims to provide a simple “magic where you want it, programmability where you don't” pattern.
5
+ Meadow is a JavaScript data broker that handles repetitive CRUD operations through a consistent, provider-agnostic interface. It doesn't care whether your data lives in MySQL, MSSQL, SQLite, or an in-browser IndexedDB store -- Meadow provides the schema management, query building, and data marshalling while you provide the business logic.
7
6
 
8
- ## Install
7
+ ## Features
9
8
 
10
- ```sh
11
- $ npm install meadow
9
+ - **Provider-Agnostic Design** - Pluggable database backends through a consistent interface
10
+ - **Schema-Driven** - Define your data model once, get validation, default objects, and audit tracking for free
11
+ - **FoxHound Query DSL** - Fluent query builder that generates dialect-specific SQL
12
+ - **Automatic Audit Tracking** - Auto-populated create/update/delete timestamps and user stamps
13
+ - **Soft Deletes** - Built-in logical deletion with automatic query filtering
14
+ - **GUID Uniqueness** - Automatic GUID generation and uniqueness enforcement on create
15
+ - **Raw Query Overrides** - Escape hatch for custom SQL when the DSL isn't enough
16
+ - **Fable Integration** - First-class service in the Fable ecosystem with logging and configuration
17
+
18
+ ## Quick Start
19
+
20
+ ```javascript
21
+ const libFable = require('fable').new();
22
+ const libMeadow = require('meadow');
23
+
24
+ // Create a Meadow DAL for the "Book" entity
25
+ const meadow = libMeadow.new(libFable, 'Book')
26
+ .setProvider('MySQL')
27
+ .setDefaultIdentifier('IDBook')
28
+ .setSchema([
29
+ { Column: 'IDBook', Type: 'AutoIdentity' },
30
+ { Column: 'GUIDBook', Type: 'AutoGUID' },
31
+ { Column: 'Title', Type: 'String', Size: '255' },
32
+ { Column: 'Author', Type: 'String', Size: '128' },
33
+ { Column: 'CreateDate', Type: 'CreateDate' },
34
+ { Column: 'CreatingIDUser', Type: 'CreateIDUser' },
35
+ { Column: 'UpdateDate', Type: 'UpdateDate' },
36
+ { Column: 'UpdatingIDUser', Type: 'UpdateIDUser' },
37
+ { Column: 'DeleteDate', Type: 'DeleteDate' },
38
+ { Column: 'DeletingIDUser', Type: 'DeleteIDUser' },
39
+ { Column: 'Deleted', Type: 'Deleted' }
40
+ ]);
41
+
42
+ // Read a single record
43
+ meadow.doRead(meadow.query.addFilter('IDBook', 42),
44
+ (pError, pQuery, pBook) =>
45
+ {
46
+ if (pError)
47
+ {
48
+ return console.log('Error reading book:', pError);
49
+ }
50
+ console.log('Found:', pBook.Title, 'by', pBook.Author);
51
+ });
12
52
  ```
13
53
 
14
- Because meadow requires the [fable](https://github.com/stevenvelozo/fable) library, you will also need to install that dependency:
54
+ ## Installation
15
55
 
16
- ```sh
17
- $ npm install fable
56
+ ```bash
57
+ npm install meadow
18
58
  ```
19
59
 
20
- ## Quick Start
60
+ ## How It Works
21
61
 
22
- It is pretty easy to perform CRUD access on your database. And facilities are there to go crazy with custom queries and stored procedures.
62
+ Meadow follows the Fable service provider pattern. You create a DAL instance for each entity in your data model, configure its schema and provider, then use the CRUD methods to interact with your database. Meadow handles query generation, data marshalling, schema validation, and audit stamping automatically.
23
63
 
24
- ```js
25
- // These settings are read automatically from the fable.settings object by meadow
26
- var databaseSettings = {
27
- MySQL:
28
- {
29
- Server: "localhost",
30
- Port: 3306,
31
- User: "root",
32
- Password: "",
33
- Database: "sales_data",
34
- ConnectionPoolLimit: 20
35
- }
36
- };
64
+ ```
65
+ Fable (Core)
66
+ └── Meadow (Data Access Layer)
67
+ ├── Schema (Column definitions, validation, defaults)
68
+ ├── FoxHound Query DSL (Dialect-specific SQL generation)
69
+ ├── Behaviors (Create, Read, Reads, Update, Delete, Count, Undelete)
70
+ └── Provider (MySQL, MSSQL, SQLite, ALASQL, MeadowEndpoints, None)
71
+ └── Database Connection
72
+ ```
37
73
 
38
- var fable = require('fable').new();
74
+ ## CRUD Operations
39
75
 
40
- // Create a MySQL connection pool (assuming MySQL is the provider you are using)
41
- var libMySQL = require('mysql2');
42
- fable.MeadowMySQLConnectionPool = libMySQL.createPool
43
- (
44
- {
45
- connectionLimit: _Fable.settings.MySQL.ConnectionPoolLimit,
46
- host: _Fable.settings.MySQL.Server,
47
- port: _Fable.settings.MySQL.Port,
48
- user: _Fable.settings.MySQL.User,
49
- password: _Fable.settings.MySQL.Password,
50
- database: _Fable.settings.MySQL.Database,
51
- namedPlaceholders: true
52
- }
53
- );
76
+ All operations follow an async waterfall pattern with a consistent callback signature.
54
77
 
78
+ ### Create
55
79
 
56
- // Create a new meadow DAL object for the "Customers" data set
57
- var meadow = require('meadow').new(fable, 'Customers')
58
- .setProvider('MySQL')
59
- .setDefaultIdentifier('customerID');
80
+ ```javascript
81
+ const tmpQuery = meadow.query.addRecord({ Title: 'Dune', Author: 'Frank Herbert' });
82
+ meadow.doCreate(tmpQuery,
83
+ (pError, pCreateQuery, pReadQuery, pRecord) =>
84
+ {
85
+ console.log('Created book with ID:', pRecord.IDBook);
86
+ });
87
+ ```
60
88
 
61
- // Construct a query, filtering to a specific customer, number 17
62
- var queryDescription = meadow.query.addFilter('customerID', 17);
89
+ ### Read
90
+
91
+ ```javascript
92
+ // Single record
93
+ meadow.doRead(meadow.query.addFilter('IDBook', 1),
94
+ (pError, pQuery, pRecord) =>
95
+ {
96
+ console.log('Book:', pRecord.Title);
97
+ });
98
+
99
+ // Multiple records with pagination
100
+ meadow.doReads(meadow.query.setCap(25).setBegin(0),
101
+ (pError, pQuery, pRecords) =>
102
+ {
103
+ console.log('Found', pRecords.length, 'books');
104
+ });
105
+ ```
63
106
 
64
- // Now pass the read query into the customer DAL, with a callback
65
- meadow.doRead(queryDescription,
66
- function(error, query, customer)
67
- {
68
- // The customer parameter will contain a javascript object if there is:
69
- // 1) a record with customerID = 17
70
- // 2) in the customers table
71
- // 3) in the sales_data database
72
- if (error)
73
- {
74
- return console.log('Error querying customer data: '+error);
75
- }
76
- console.log('Found customer ID '+customer.customerID+' who is named '+customer.name);
77
- }
78
- );
107
+ ### Update
108
+
109
+ ```javascript
110
+ const tmpQuery = meadow.query
111
+ .addFilter('IDBook', 1)
112
+ .addRecord({ Title: 'Updated Title' });
113
+ meadow.doUpdate(tmpQuery,
114
+ (pError, pUpdateQuery, pReadQuery, pRecord) =>
115
+ {
116
+ console.log('Updated:', pRecord.Title);
117
+ });
79
118
  ```
80
119
 
81
- ## You can also use the ALASQL persistence engine
120
+ ### Delete and Count
121
+
122
+ ```javascript
123
+ // Delete (soft delete if schema supports it)
124
+ meadow.doDelete(meadow.query.addFilter('IDBook', 1),
125
+ (pError, pQuery, pResult) =>
126
+ {
127
+ console.log('Deleted:', pResult, 'record(s)');
128
+ });
129
+
130
+ // Count records
131
+ meadow.doCount(meadow.query,
132
+ (pError, pQuery, pCount) =>
133
+ {
134
+ console.log('Total books:', pCount);
135
+ });
136
+ ```
82
137
 
83
- ```js
84
- // These settings are read automatically from the fable.settings object by meadow
85
- var fable = require('fable').new();
138
+ ## Schema
86
139
 
87
- // Create the IndexdDB database [example], attach and use it
88
- var libALASQL = require('alasql');
89
- libALASQL('CREATE INDEXEDDB DATABASE IF NOT EXISTS example;');
90
- libALASQL('ATTACH INDEXEDDB DATABASE example;');
91
- libALASQL('USE example;');
92
- fable.ALASQL = libALASQL;
140
+ Meadow schemas define your data model with special column types that enable automatic behavior:
93
141
 
142
+ | Type | Description |
143
+ |------|-------------|
144
+ | `AutoIdentity` | Auto-increment primary key |
145
+ | `AutoGUID` | Automatically generated GUID |
146
+ | `CreateDate` / `CreateIDUser` | Auto-populated on create |
147
+ | `UpdateDate` / `UpdateIDUser` | Auto-populated on update |
148
+ | `DeleteDate` / `DeleteIDUser` | Auto-populated on delete |
149
+ | `Deleted` | Soft delete flag |
150
+ | `String`, `Text`, `Numeric`, `Decimal`, `Boolean`, `DateTime` | Standard data types |
94
151
 
152
+ ## Providers
95
153
 
96
- // Create a new meadow DAL object for the "Customers" data set
97
- var meadow = require('meadow').new(fable, 'Customers')
98
- .setProvider('ALASQL')
99
- .setDefaultIdentifier('customerID');
154
+ | Provider | Description |
155
+ |----------|-------------|
156
+ | `MySQL` | MySQL/MariaDB via mysql2 |
157
+ | `MSSQL` | Microsoft SQL Server with prepared statements |
158
+ | `SQLite` | SQLite via meadow-connection-sqlite |
159
+ | `ALASQL` | In-browser IndexedDB via ALASQL |
160
+ | `MeadowEndpoints` | REST proxy to remote Meadow API |
161
+ | `None` | Null provider for testing |
100
162
 
101
- // Construct a query, filtering to a specific customer, number 17
102
- var queryDescription = meadow.query.addFilter('customerID', 17);
163
+ ## ALASQL Provider Example
103
164
 
104
- // Now pass the read query into the customer DAL, with a callback
105
- meadow.doRead(queryDescription,
106
- function(error, query, customer)
107
- {
108
- // The customer parameter will contain a javascript object if there is:
109
- // 1) a record with customerID = 17
110
- // 2) in the customers table
111
- // 3) in the sales_data database
112
- if (error)
113
- {
114
- return console.log('Error querying customer data: '+error);
115
- }
116
- console.log('Found customer ID '+customer.customerID+' who is named '+customer.name);
117
- }
118
- );
119
- ```
165
+ ```javascript
166
+ const libFable = require('fable').new();
167
+ const libALASQL = require('alasql');
168
+
169
+ libALASQL('CREATE INDEXEDDB DATABASE IF NOT EXISTS example;');
170
+ libALASQL('ATTACH INDEXEDDB DATABASE example;');
171
+ libALASQL('USE example;');
172
+ libFable.ALASQL = libALASQL;
120
173
 
174
+ const meadow = require('meadow').new(libFable, 'Customers')
175
+ .setProvider('ALASQL')
176
+ .setDefaultIdentifier('customerID');
177
+ ```
121
178
 
122
179
  ## MSSQL Docker Image
123
180
 
124
- To run the Microsoft SQL Server tests, you can use the free image on dockerhub.
181
+ To run Microsoft SQL Server tests locally:
125
182
 
126
- ```
127
- docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=1234567890abc." -p 14333:1433 --name meadow-mssql-test --hostname meadowsqltest -d mcr.microsoft.com/mssql/server:2022-latest
183
+ ```bash
184
+ docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=1234567890abc." \
185
+ -p 14333:1433 --name meadow-mssql-test --hostname meadowsqltest \
186
+ -d mcr.microsoft.com/mssql/server:2022-latest
187
+
188
+ docker exec meadow-mssql-test sh -c \
189
+ "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P '1234567890abc.' -Q 'CREATE DATABASE bookstore;'"
128
190
  ```
129
191
 
130
- Then you need to create the test database:
192
+ ## Testing
131
193
 
132
- ```
133
- docker exec meadow-mssql-test sh -c "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P '1234567890abc.' -Q 'CREATE DATABASE bookstore;'"
194
+ ```bash
195
+ npm test
134
196
  ```
135
197
 
136
- ### Docker Development Environment
198
+ ## Documentation
137
199
 
200
+ Detailed documentation is available in the `docs/` folder and can be served locally:
138
201
 
139
- 1. Run this command to build this image:
140
- ```
141
- docker build ./ -t retold/meadow:local
202
+ ```bash
203
+ npx docsify-cli serve docs
142
204
  ```
143
205
 
144
- 2. Run this command to build the local container:
145
- ```
146
- docker run -it --name meadow-dev -p 127.0.0.1:12342:8080 -v "$PWD/.config:/home/coder/.config" -v "$PWD:/home/coder/meadow" -u "$(id -u):$(id -g)" -e "DOCKER_USER=$USER" retold/meadow:local
147
- ```
148
-
149
- 3. Go to http://localhost:12342/ in a web browser
150
-
151
- 4. The password is "retold"
206
+ ## Related Packages
152
207
 
153
- 5. Right now you (may) need to delete the `node_modules` folders and regenerate it for Linux.
208
+ - [foxhound](https://github.com/stevenvelozo/foxhound) - Query DSL for SQL generation
209
+ - [stricture](https://github.com/stevenvelozo/stricture) - Schema definition language
210
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Automatic REST endpoint generation
211
+ - [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) - MySQL connection provider
212
+ - [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) - MSSQL connection provider
213
+ - [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) - SQLite connection provider
214
+ - [fable](https://github.com/stevenvelozo/fable) - Service provider framework
215
+ - [orator](https://github.com/stevenvelozo/orator) - API server abstraction
package/docs/README.md ADDED
@@ -0,0 +1,276 @@
1
+ # Meadow
2
+
3
+ > A data access layer providing magic where you want it, programmability where you don't
4
+
5
+ Meadow is a JavaScript data broker that handles repetitive CRUD operations through a consistent, provider-agnostic interface. It doesn't care whether your data lives in MySQL, MSSQL, SQLite, or an in-browser IndexedDB store -- Meadow provides the schema management, query building, and data marshalling while you provide the business logic.
6
+
7
+ ## Features
8
+
9
+ - **Provider-Agnostic Design** - Pluggable database backends through a consistent interface
10
+ - **Schema-Driven** - Define your data model once, get validation, default objects, and audit tracking for free
11
+ - **FoxHound Query DSL** - Fluent query builder that generates dialect-specific SQL
12
+ - **Automatic Audit Tracking** - Auto-populated create/update/delete timestamps and user stamps
13
+ - **Soft Deletes** - Built-in logical deletion with automatic query filtering
14
+ - **GUID Uniqueness** - Automatic GUID generation and uniqueness enforcement on create
15
+ - **Raw Query Overrides** - Escape hatch for custom SQL when the DSL isn't enough
16
+ - **Fable Integration** - First-class service in the Fable ecosystem with logging and configuration
17
+
18
+ ## Quick Start
19
+
20
+ ```javascript
21
+ const libFable = require('fable').new();
22
+ const libMeadow = require('meadow');
23
+
24
+ // Create a Meadow DAL for the "Book" entity
25
+ const meadow = libMeadow.new(libFable, 'Book')
26
+ .setProvider('MySQL')
27
+ .setDefaultIdentifier('IDBook')
28
+ .setSchema([
29
+ { Column: 'IDBook', Type: 'AutoIdentity' },
30
+ { Column: 'GUIDBook', Type: 'AutoGUID' },
31
+ { Column: 'Title', Type: 'String', Size: '255' },
32
+ { Column: 'Author', Type: 'String', Size: '128' },
33
+ { Column: 'CreateDate', Type: 'CreateDate' },
34
+ { Column: 'CreatingIDUser', Type: 'CreateIDUser' },
35
+ { Column: 'UpdateDate', Type: 'UpdateDate' },
36
+ { Column: 'UpdatingIDUser', Type: 'UpdateIDUser' },
37
+ { Column: 'DeleteDate', Type: 'DeleteDate' },
38
+ { Column: 'DeletingIDUser', Type: 'DeleteIDUser' },
39
+ { Column: 'Deleted', Type: 'Deleted' }
40
+ ]);
41
+
42
+ // Read a single record
43
+ meadow.doRead(meadow.query.addFilter('IDBook', 42),
44
+ (pError, pQuery, pBook) =>
45
+ {
46
+ if (pError)
47
+ {
48
+ return console.log('Error reading book:', pError);
49
+ }
50
+ console.log('Found:', pBook.Title, 'by', pBook.Author);
51
+ });
52
+ ```
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ npm install meadow
58
+ ```
59
+
60
+ ## How It Works
61
+
62
+ Meadow follows the Fable service provider pattern. You create a DAL instance for each entity in your data model, configure its schema and provider, then use the CRUD methods to interact with your database. Meadow handles query generation, data marshalling, schema validation, and audit stamping automatically.
63
+
64
+ ```
65
+ Fable (Core)
66
+ └── Meadow (Data Access Layer)
67
+ ├── Schema (Column definitions, validation, defaults)
68
+ ├── FoxHound Query DSL (Dialect-specific SQL generation)
69
+ ├── Behaviors (Create, Read, Reads, Update, Delete, Count, Undelete)
70
+ └── Provider (MySQL, MSSQL, SQLite, ALASQL, MeadowEndpoints, None)
71
+ └── Database Connection
72
+ ```
73
+
74
+ ## CRUD Operations
75
+
76
+ All operations follow an async waterfall pattern with a consistent callback signature.
77
+
78
+ ### Create
79
+
80
+ ```javascript
81
+ const tmpQuery = meadow.query.addRecord({ Title: 'Dune', Author: 'Frank Herbert' });
82
+ meadow.doCreate(tmpQuery,
83
+ (pError, pCreateQuery, pReadQuery, pRecord) =>
84
+ {
85
+ console.log('Created book with ID:', pRecord.IDBook);
86
+ });
87
+ ```
88
+
89
+ ### Read
90
+
91
+ ```javascript
92
+ // Single record
93
+ meadow.doRead(meadow.query.addFilter('IDBook', 1),
94
+ (pError, pQuery, pRecord) =>
95
+ {
96
+ console.log('Book:', pRecord.Title);
97
+ });
98
+
99
+ // Multiple records
100
+ meadow.doReads(meadow.query.setCap(25).setBegin(0),
101
+ (pError, pQuery, pRecords) =>
102
+ {
103
+ console.log('Found', pRecords.length, 'books');
104
+ });
105
+ ```
106
+
107
+ ### Update
108
+
109
+ ```javascript
110
+ const tmpQuery = meadow.query
111
+ .addFilter('IDBook', 1)
112
+ .addRecord({ Title: 'Updated Title' });
113
+ meadow.doUpdate(tmpQuery,
114
+ (pError, pUpdateQuery, pReadQuery, pRecord) =>
115
+ {
116
+ console.log('Updated:', pRecord.Title);
117
+ });
118
+ ```
119
+
120
+ ### Delete
121
+
122
+ ```javascript
123
+ meadow.doDelete(meadow.query.addFilter('IDBook', 1),
124
+ (pError, pQuery, pResult) =>
125
+ {
126
+ console.log('Deleted:', pResult, 'record(s)');
127
+ });
128
+ ```
129
+
130
+ ### Count
131
+
132
+ ```javascript
133
+ meadow.doCount(meadow.query,
134
+ (pError, pQuery, pCount) =>
135
+ {
136
+ console.log('Total books:', pCount);
137
+ });
138
+ ```
139
+
140
+ ## Schema
141
+
142
+ Meadow schemas define your data model with special column types that enable automatic behavior.
143
+
144
+ ### Column Types
145
+
146
+ | Type | Description |
147
+ |------|-------------|
148
+ | `AutoIdentity` | Auto-increment primary key |
149
+ | `AutoGUID` | Automatically generated GUID |
150
+ | `CreateDate` | Auto-populated timestamp on create |
151
+ | `CreateIDUser` | Auto-populated user ID on create |
152
+ | `UpdateDate` | Auto-populated timestamp on update |
153
+ | `UpdateIDUser` | Auto-populated user ID on update |
154
+ | `DeleteDate` | Auto-populated timestamp on delete |
155
+ | `DeleteIDUser` | Auto-populated user ID on delete |
156
+ | `Deleted` | Soft delete flag (enables logical deletion) |
157
+ | `String` | String field with optional `Size` |
158
+ | `Text` | Long text field |
159
+ | `Numeric` | Integer field |
160
+ | `Decimal` | Decimal field with `Size` as `"precision,scale"` |
161
+ | `Boolean` | Boolean field |
162
+ | `DateTime` | Date/time field |
163
+
164
+ ### JSON Schema Validation
165
+
166
+ Meadow also supports JSON Schema (v4) for object validation:
167
+
168
+ ```javascript
169
+ meadow.setJsonSchema({
170
+ title: 'Book',
171
+ type: 'object',
172
+ properties:
173
+ {
174
+ IDBook: { type: 'integer' },
175
+ Title: { type: 'string' },
176
+ Author: { type: 'string' }
177
+ },
178
+ required: ['Title']
179
+ });
180
+
181
+ const result = meadow.schemaFull.validateObject({ Title: 'Dune' });
182
+ // { Valid: true, Errors: [] }
183
+ ```
184
+
185
+ ## Configuration
186
+
187
+ Meadow reads database configuration from the Fable settings object:
188
+
189
+ ```json
190
+ {
191
+ "Product": "MyApp",
192
+ "ProductVersion": "1.0.0",
193
+ "MySQL": {
194
+ "Server": "localhost",
195
+ "Port": 3306,
196
+ "User": "root",
197
+ "Password": "",
198
+ "Database": "myapp",
199
+ "ConnectionPoolLimit": 20
200
+ },
201
+ "QueryThresholdWarnTime": 200
202
+ }
203
+ ```
204
+
205
+ | Setting | Type | Default | Description |
206
+ |---------|------|---------|-------------|
207
+ | `MySQL` | object | - | MySQL connection settings |
208
+ | `QueryThresholdWarnTime` | number | `200` | Slow query warning threshold (ms) |
209
+ | `MeadowProvider` | string | - | Default provider name |
210
+ | `MeadowRoleNames` | array | `['Unauthenticated', 'User', 'Manager', 'Director', 'Executive', 'Administrator']` | Role name mapping |
211
+
212
+ ## Providers
213
+
214
+ Meadow supports multiple database backends through its provider system.
215
+
216
+ | Provider | Description | Connection |
217
+ |----------|-------------|------------|
218
+ | `MySQL` | MySQL/MariaDB via mysql2 | `fable.MeadowMySQLConnectionPool` or `fable.MeadowMySQLProvider` |
219
+ | `MSSQL` | Microsoft SQL Server | `fable.MeadowMSSQLProvider` |
220
+ | `SQLite` | SQLite database | Via meadow-connection-sqlite |
221
+ | `ALASQL` | In-browser IndexedDB | `fable.ALASQL` |
222
+ | `MeadowEndpoints` | REST proxy to remote Meadow API | Via `MeadowEndpoints` settings |
223
+ | `None` | Null provider for testing | No connection required |
224
+
225
+ ## Raw Query Overrides
226
+
227
+ For complex queries that exceed the DSL capabilities:
228
+
229
+ ```javascript
230
+ // Set a custom query for Read operations
231
+ meadow.rawQueries.setQuery('Read',
232
+ 'SELECT b.*, a.Name AS AuthorName FROM Book b JOIN Author a ON b.IDAuthor = a.IDAuthor WHERE b.IDBook = :IDBook');
233
+
234
+ // Load from file
235
+ meadow.rawQueries.loadQuery('CustomReport', './queries/book-report.sql');
236
+
237
+ // Check and use
238
+ if (meadow.rawQueries.checkQuery('CustomReport'))
239
+ {
240
+ const sql = meadow.rawQueries.getQuery('CustomReport');
241
+ }
242
+ ```
243
+
244
+ ## Testing
245
+
246
+ ```bash
247
+ npm test
248
+ ```
249
+
250
+ ## Documentation
251
+
252
+ - [Architecture](architecture.md) - System architecture and design patterns
253
+ - [Schema](schema/README.md) - Column definitions, JSON Schema validation, default objects, authorization
254
+ - [Query DSL](query-dsl.md) - FoxHound query building
255
+ - [Query Operations](query/README.md) - Query object overview and CRUD operations
256
+ - [Create](query/create.md) - Insert new records
257
+ - [Read](query/read.md) - Retrieve single and multiple records
258
+ - [Update](query/update.md) - Modify existing records
259
+ - [Delete](query/delete.md) - Soft delete and undelete records
260
+ - [Count](query/count.md) - Count records matching criteria
261
+ - [Providers](providers/README.md) - Database provider system
262
+ - [MySQL](providers/mysql.md) - Connection pooling, named placeholders
263
+ - [MSSQL](providers/mssql.md) - Prepared statements, type mapping
264
+ - [SQLite](providers/sqlite.md) - Embedded database
265
+ - [ALASQL](providers/alasql.md) - In-memory SQL, browser support
266
+
267
+ ## Related Packages
268
+
269
+ - [foxhound](https://github.com/stevenvelozo/foxhound) - Query DSL for SQL generation
270
+ - [stricture](https://github.com/stevenvelozo/stricture) - Schema definition language
271
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Automatic REST endpoint generation
272
+ - [meadow-connection-mysql](https://github.com/stevenvelozo/meadow-connection-mysql) - MySQL connection provider
273
+ - [meadow-connection-mssql](https://github.com/stevenvelozo/meadow-connection-mssql) - MSSQL connection provider
274
+ - [meadow-connection-sqlite](https://github.com/stevenvelozo/meadow-connection-sqlite) - SQLite connection provider
275
+ - [fable](https://github.com/stevenvelozo/fable) - Service provider framework
276
+ - [orator](https://github.com/stevenvelozo/orator) - API server abstraction