Skip to content

Commit 1a17dbd

Browse files
committed
- more documentation
- implemented cors - slight config changes
1 parent 849361f commit 1a17dbd

File tree

20 files changed

+433
-203
lines changed

20 files changed

+433
-203
lines changed

docs/docs/getting-started/_category_.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"position": 2,
44
"link": {
55
"type": "generated-index",
6-
"description": "5 minutes to learn the most important Docusaurus concepts."
6+
"description": "getting started with exa.js"
77
}
88
}

docs/docs/getting-started/project-structure.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,39 @@ sidebar_position: 2
44

55
# project structure
66

7-
this is an overview of each directory in the project and what it is for. this is also the directories present after initialization.
7+
this is an overview of each directory in the project and what it is for. this is also the directories present after initialization. everything here is documented in sections under modules.
88

99
## directories
1010

11-
### config
12-
contains a `master.js` configuration file. this is used for project level configuration. for environment level configuration, it's recommended to use a `.env` file in the root and transfer relevant env using `process.env` in `master.js`.
11+
### config ([/modules/configuration](/modules/configuration))
12+
contains configuration files for your exa.js project
1313

14-
### console
15-
contains console scripts that can be invoked with `npm run console <script name>`. see docs for proper format.
14+
### console ([/modules/console](/modules/console))
15+
contains console scripts that are intended to be ran in a terminal directly or via cron job.
1616

17-
### http
18-
contains api logic organized in one or more files. each file contains route definitions, middleware, and handlers. see docs for proper format.
17+
### http ([/modules/http](/modules/http))
18+
contains api logic organized in one or more files. each file contains route definitions, middleware, and handlers.
1919

2020
### library
21-
contains user defined library files. this is generally relevant js files for your project that don't fit anywhere else.
21+
contains user defined library files. this is generally relevant js files for your project that don't fit anywhere else. what exists in this folder is not processed or seen by exa.js at all.
2222

23-
### middleware
24-
contains express.js compatible middleware. middleware is configured for use in api logic. see docs for proper format.
23+
### middleware ([/modules/http#middleware](/modules/http#middleware))
24+
contains express.js compatible middleware. middleware is configured for use in api logic.
2525

26-
### migrations
27-
contains [jmig](https://github.com/realtux/jmig) compatible database migrations files. these are used to apply and rollback changes to a database. please see the jmig readme for usage specifics.
26+
### migrations ([/modules/migrations](/modules/migrations))
27+
contains [jmig](https://github.com/realtux/jmig) compatible database migrations files. these are used to apply and rollback changes to a database.
2828

29-
### models
29+
### models ([/modules/database](/modules/database))
3030
contains sequelize.js compatible database model files. to use a different database orm, set `database.use = false` in `config/master.js` which will disable automatic initialization of the `models` directory. see docs for proper format.
3131

3232
### public
33-
contains publicly available static files. in development, this is served with `express.static()` at base url `/public`. in production, this should be served with a normal web server.
33+
contains publicly available static files.
3434

3535
### var
36-
contains variable static data, use this to store files that aren't directly used in your project, such as docs, sql files, notes, etc.
36+
contains variable static data, use this to store files that aren't directly used in your project, such as docs, sql files, notes, etc. as with library, what exists in this folder is not processed or seen by exa.js at all.
3737

38-
### views
38+
### views ([/modules/views](/modules/views))
3939
contains view templates for traditional non-async frontends. use `res.render(path, variables)` instead of `res.send()` in your api logic.
4040

41-
### websocket
41+
### websocket ([/modules/websockets](/modules/websockets))
4242
contains files that represent websocket connection entrypoints. see docs for proper format.

docs/docs/modules/_category_.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"position": 3,
44
"link": {
55
"type": "generated-index",
6-
"description": "5 minutes to learn the most important Docusaurus concepts."
6+
"description": "exa.js modules"
77
}
88
}

docs/docs/modules/configuration.md

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ configuration is intended to exist in two locations, one for your base configura
1010

1111
## base configuration
1212

13-
this file allows for base configuration. this is intended to have some hard coded configuration and also some dynamic configuration by referencing environment variables with `process.env`.
13+
this file allows for base configuration. this is intended to have some hard coded configuration and also some dynamic configuration by referencing environment variables with `process.env`. the values below are also the default values. all values in this file are deep merged with the exa.js internal configuration, this means that you're free to only specify configuration that differs from the exa.js defaults. for instance, you could only supply `http.host` and the rest of the object would fall back to defaults.
1414

1515
```js title="config/master.js"
1616
export default {
@@ -25,7 +25,15 @@ export default {
2525
host: '0.0.0.0',
2626
port: 8118,
2727
base_url: 'http://127.0.0.1:8118',
28-
websocket: true,
28+
cors: {
29+
origins: '*',
30+
methods: '*',
31+
headers: '*',
32+
}
33+
},
34+
35+
websocket: {
36+
use: true,
2937
},
3038

3139
database: {
@@ -37,6 +45,7 @@ export default {
3745
name: process.env.DATABASE_NAME,
3846
host: process.env.DATABASE_HOST,
3947
port: process.env.DATABASE_PORT,
48+
timezone: 'UTC',
4049
},
4150

4251
console: {
@@ -73,32 +82,42 @@ don't put secrets in `config/master.js`, use `.env` instead and reference with `
7382

7483
### environment
7584

76-
- `development` [`bool`] - sets development mode on or off. by default this checks the value of `process.env.EXAENV` and resolves to `false` if it receives any other value than `development`.it could also be hardcoded `true` or `false` if desired.
85+
- `development` (`bool`, default: `false`) - sets development mode on or off
86+
* by default this checks the value of `process.env.EXAENV` and resolves to `false` if it receives any other value than `development`. it could also be hardcoded `true` or `false` if desired.
7787

7888
### http
7989

80-
this section is used to configure settings for the http and websockets module. because the http server is created using express.js, some settings here may reflect this.
90+
this section is used to configure settings for the http module. because the http server is created using express.js, some settings here may reflect this.
91+
92+
- `use` (`bool`, default: `true`) - whether or not to start an http server
93+
- `host` (`string`, default: `0.0.0.0`) - host to listen on. use `0.0.0.0` to listen to all hosts
94+
- `port` (`number`, default: `8118`) - port to listen on
95+
- `base_url` (`string`, default: `http://127.0.0.1:8118`) - base url for the http server
96+
- `cors` (`object`)
97+
* `origins` (`string|array`, default: `*`) - allowed origins, internally sets `Access-Control-Allow-Origin` header
98+
* `methods` (`string|array`, default: `*`) - allowed methods, internally sets `Access-Control-Allow-Methods` header
99+
* `headers` (`string|array`, default: `*`) - allowed headers, internally sets `Access-Control-Allow-Headers` header
100+
101+
### websocket
102+
103+
this section is used to configure settings for the websockets module. this module requires the http module to be enabled as websocket connections are upgraded from http connections.
81104

82-
- `use` [`bool`] - whether or not to start an http server
83-
- `host` [`string`] - host to listen on
84-
* use `0.0.0.0` to listen to all hosts
85-
- `port` [`number`] - post to listen on
86-
- `base_url` [`string`] - base url for the http server
87-
- `websocket` [`bool`] - whether or not to enable the websocket module
105+
- `use` (`bool`, default: `true`) - whether or not to start a websocket server
88106
* setting this to `false` will cause files in `websocket/*` to be ignored
89107

90108
### database
91109

92110
this section is used to configure settings for the database module. the built-in database support is through the very great [sequelize.js](https://sequelize.org/) project. there's absolutely nothing stopping developers from using something else though.
93111

94-
- `use` [`bool`] - whether or not to process models in `models/*`
95-
- `dialect` [`dialect`] - this is passed directly to sequelize.js
112+
- `use` (`bool`, default: `true`) - whether or not to process models in `models/*`
113+
- `dialect` (`string`, default: `mysql`) - this is passed directly to sequelize.js
96114
* sequelize.js supports many dialects, please [click here](https://sequelize.org/docs/v6/getting-started/) for more information
97-
- `username` [`string`] - database username
98-
- `password` [`string`] - database password
99-
- `name` [`string`] - database name
100-
- `host` [`string`] - database host
101-
- `port` [`number`] - databse port
115+
- `username` (`string`, default: `''`) - database username
116+
- `password` (`string`, default: `''`) - database password
117+
- `name` (`string`, default: `''`) - database name
118+
- `host` (`string`, default: `127.0.0.1`) - database connection host
119+
- `port` (`number`, default: `3306`) - database connection port
120+
- `timezone` (`string`, default: `UTC`) - timezone to set the database to
102121

103122
:::tip[Tip]
104123
use `process.env.*` for these values. besides not putting secrets in your config, you'll also need these values for the migrations module.
@@ -108,26 +127,26 @@ use `process.env.*` for these values. besides not putting secrets in your config
108127

109128
this section is used to configure console script runner settings.
110129

111-
- `use` [`bool`] - whether or not to register console scripts in `console/*`
130+
- `use` (`bool`, default: `true`) - whether or not to register console scripts in `console/*`
112131
* setting this to `false` will disallow console scripts from being ran
113-
- `quiet` [`bool`] - whether or not to suppress exa.js related output
132+
- `quiet` (`bool`, default: `true`) - whether or not to suppress exa.js related output
114133
* exa.js usually has script start-up information, such as version, time, and other information. setting this to `false` will suppress all this so console command output is only from the developer.
115134

116135
### views
117136

118137
this section is used to configure settings for views and templates.
119138

120-
- `use` [`bool`] - whether or not to enable views
121-
- `engine` [`string`] - which templating engine to use
139+
- `use` (`bool`, default: `true`) - whether or not to enable views
140+
- `engine` (`string`, default: `nunjucks`) - which templating engine to use
122141
* currently supported engines are
123142
- nunjucks
124143

125144
### public
126145

127146
this secion is used to configure static asset serving. internally this uses express.js.
128147

129-
- `use` [`bool`] - whether or not to serve static assets
130-
- `base_url` [`string`] - base url that static assets should be available on
148+
- `use` (`bool`, default: `true`) - whether or not to serve static assets
149+
- `base_url` (`string`, default: `/public`) - base url that static assets should be available on
131150
* this value is passed to `express.static(path)` internally
132151

133152
### user defined configuration
@@ -156,3 +175,9 @@ DATABASE_NAME=yourdb
156175

157176
COMPOSE_PROJECT_NAME=exajs
158177
```
178+
179+
:::warning[Warning]
180+
181+
don't check `.env` into source control or you'll likely be checking in secrets. the exa.js template has `.env` in `.gitignore` on purpose to prevent this.
182+
183+
:::

docs/docs/modules/console.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 3
2+
sidebar_position: 6
33
---
44

55
# console
@@ -29,15 +29,13 @@ export default new class {
2929

3030
all the following examples assume a script called `sample` is located at `console/sample.js`.
3131

32-
### from root directory
32+
### bare metal
3333

3434
```bash
35+
# from root directory
3536
npm run sample
36-
```
37-
38-
### via a cronjob
3937

40-
```bash
38+
# via cronjob
4139
npm --prefix /path/to/app run sample
4240
```
4341

docs/docs/modules/database.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
sidebar_position: 4
3+
---
4+
5+
# database
6+
7+
the database module facilitates connecting exa.js to an external database. this module is a thin wrapper around the great and powerful [sequelize.js](https://sequelize.org/) project. the main purpose is to expose and configure models in a slightly more intutitive way.
8+
9+
## anatomy of a model
10+
11+
each model represents a table in the database and is created in the `models` directory. in this example, we'll create a new model to represent a `users` table at `models/users.js`. this example also references an `orgs` model. you'll have to pretend that it exists for now.
12+
13+
```js title="models/users.js"
14+
import { Model, DataTypes } from '@exajs/core/system/sequelize';
15+
import util from '#app/library/util.js';
16+
17+
class users extends Model {
18+
19+
static table_name = 'users'
20+
21+
static fields = {
22+
user_id: {
23+
type: DataTypes.INTEGER,
24+
primaryKey: true,
25+
autoIncrement: true
26+
},
27+
org_id: DataTypes.INTEGER,
28+
name: DataTypes.STRING,
29+
email: DataTypes.STRING,
30+
content: DataTypes.DESCRIPTION,
31+
created_at: DataTypes.DATE,
32+
}
33+
34+
static associate(models) {
35+
// associate users to orgs (orgs model must exist obviously)
36+
models.users
37+
.belongsTo(models.orgs, {
38+
as: 'orgs',
39+
foreignKey: 'org_id',
40+
});
41+
}
42+
43+
static hooks = {
44+
async beforeCreate(instance) {
45+
instance.created_at = util.now();
46+
}
47+
}
48+
49+
static options = {
50+
// sequelize specific options
51+
}
52+
53+
static model_method() {
54+
// method available at users.model_method();
55+
}
56+
57+
}
58+
59+
export default users;
60+
```
61+
62+
### table_name
63+
64+
specify the name of the table here, pretty straight forward. this will be mapped onto `options.modelName` for sequelize internally.
65+
66+
### fields
67+
68+
defines all fields of a database and their associated types (https://sequelize.org/docs/v6/core-concepts/model-basics/#data-types). this is necessary for proper mapping of mysql types to javascript types. this will be supplied directly to the sequelize `model.init()` function.
69+
70+
### associate
71+
72+
this is a function that will be called (if it exists) after all models have been initialized. the `models` variable will be an object containing all initialized models from the `models/*` directory. sequelize supports associations (https://sequelize.org/docs/v6/core-concepts/assocs/) to perform eager loading in queries and this is a perfect place to organize these associations.
73+
74+
note that although sequelize documents associations being as simple as `A.belongsTo(B)`, in practice this only works when taking advantage of sequelize's conventions which sometimes have bad side effects. this module aims to remove these conventions in favor of more developer control.
75+
76+
what this means is associations in exa.js will require the use of `as` and `foreignKey` almost always, since the alias and foreign key won't be inferred for you. although this is a little extra work, it removes to possibility of encountering convention related problems later.
77+
78+
### hooks
79+
80+
sequelize supports a number of lifecycle hooks (https://sequelize.org/docs/v6/other-topics/hooks/) that can be used to run code at various key points. this will be mapped onto `options.hooks` for sequelize internally.
81+
82+
## options
83+
84+
anything in this object is merged in with the model options for sequelize. this can be used to supply other options or configuration that isn't exposed with the exa.js wrapper.
85+
86+
### other methods
87+
88+
any other static methods created in the model will also be available statically when including the model in your application.
89+
90+
## using a model
91+
92+
so now you have a model, time to use it. say you wanted to create an http route to return all users. to do this, create an http file `http/api/users.js`
93+
94+
```js title="http/api/users.js"
95+
import { models } from '@exajs/core/database';
96+
97+
export default new class {
98+
99+
routes = {
100+
'get /api/users': 'all',
101+
}
102+
103+
async all(req, res) {
104+
let users = await models.users
105+
.findAll();
106+
107+
return res
108+
.status(200)
109+
.send(users);
110+
}
111+
112+
};
113+
```
114+
115+
:::tip[Tip]
116+
models can also be imported directly such as `import users from '#app/models/users.js';`. we find this unnecessarily reserves important variables (`users` in this case) and probably should be avoided, but know that it is an option.
117+
:::

docs/docs/modules/migrations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 10
2+
sidebar_position: 5
33
---
44

55
# migrations

0 commit comments

Comments
 (0)