@vulkano/core 1.20.1 → 1.22.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.
Files changed (31) hide show
  1. package/README.md +380 -70
  2. package/controllers/controllers.js +36 -8
  3. package/database/mongodb.js +11 -4
  4. package/examples/config/express/cookies.js +15 -0
  5. package/examples/config/express/cors.js +23 -0
  6. package/examples/config/express/csp.js +74 -0
  7. package/examples/config/express/helmet.js +19 -0
  8. package/examples/config/express/json.js +14 -0
  9. package/examples/config/express/jwt.js +39 -0
  10. package/examples/config/express/permissionPolicy.js +24 -0
  11. package/examples/config/express/settings.js +25 -0
  12. package/examples/config/middlewares/auth.js +38 -0
  13. package/examples/config/sockets/adapters/mongodb.js +12 -0
  14. package/examples/config/sockets/adapters/redis.js +9 -0
  15. package/examples/config/sockets/config.js +50 -0
  16. package/examples/config/sockets/cors.js +32 -0
  17. package/examples/config/sockets/events.js +12 -0
  18. package/examples/config/sockets/middlewares/auth.js +20 -0
  19. package/examples/config/views/config.js +8 -0
  20. package/examples/config/views/filters/example.js +6 -0
  21. package/examples/config/views/helpers/strpad.js +51 -0
  22. package/examples/controllers/ExampleController.js +22 -0
  23. package/examples/controllers/RestExampleController.js +78 -0
  24. package/examples/controllers/RestScaffoldController.js +18 -0
  25. package/examples/models/Example.js +238 -0
  26. package/examples/models/ExampleWithScaffold.js +51 -0
  27. package/examples/routes.js +55 -0
  28. package/examples/views/_shared/templates/default.html +20 -0
  29. package/examples/views/index.html +7 -0
  30. package/package.json +1 -1
  31. package/pnpm-workspace.yaml +7 -1
@@ -0,0 +1,238 @@
1
+ /* global Example */
2
+
3
+ /**
4
+ * Example.js
5
+ */
6
+
7
+ // This is an example for a simple model that provides CRUD operations.
8
+ // Provide a flexible way to implement business logic in the model, which is a good practice
9
+ // to keep the controller thin and focused on handling requests and responses.
10
+
11
+ module.exports = {
12
+
13
+ /**
14
+ * Fields
15
+ */
16
+ attributes: {
17
+ name: {
18
+ type: String,
19
+ required: true
20
+ },
21
+ age: {
22
+ type: Number,
23
+ required: false,
24
+ validate: {
25
+ validator: (value) => {
26
+ const isValid = (value >= 21) ? true : false;
27
+ return isValid;
28
+ },
29
+ message: 'Invalid Age: Must be +21.',
30
+ }
31
+ }
32
+ // the fields:
33
+ // active, createdAt, updatedAt
34
+ // was created automatically
35
+ },
36
+
37
+ // Custom Index
38
+ indexes: [
39
+ {
40
+ name: 'text'
41
+ }
42
+ ],
43
+
44
+ /**
45
+ * Method to get all records by page
46
+ *
47
+ * @param {Object} props (page, perPage, search, sort)
48
+ * @returns {Promise}
49
+ */
50
+ getAll(props) {
51
+
52
+ // Props to Query
53
+ const defaultProps = {
54
+ sort: 'createdAt|DESC',
55
+ searchBy: ['name'],
56
+ fields: ['name', 'age', 'active', 'createdAt', 'updatedAt'],
57
+ filter: {
58
+ active: true
59
+ },
60
+ };
61
+
62
+ // Populate
63
+ const populate = [];
64
+
65
+ // Query to Run
66
+ const query = Paginate.serializeQuery(defaultProps, props);
67
+
68
+ // Pagination
69
+ return Paginate.get(Example, query, populate);
70
+
71
+ },
72
+
73
+ /**
74
+ * Method to get a record by id
75
+ *
76
+ * @param {ObjectID} id
77
+ * @returns {Promise}
78
+ */
79
+ getExample(_id) {
80
+
81
+ // This is to prevent error while run the findOne
82
+ if (!(/^[a-fA-F0-9]{24}$/).test(_id)) {
83
+ return VSError.reject('Invalid ID. Record not found', 404);
84
+ }
85
+
86
+ return Example.findOne({ _id })
87
+ .then( (r) => {
88
+
89
+ if (!r) {
90
+ return VSError.notFound();
91
+ }
92
+
93
+ return r.toObject({ transform: true });
94
+
95
+ });
96
+
97
+ },
98
+
99
+ /**
100
+ * Method to create a new record
101
+ * @param {Promise} data
102
+ */
103
+ create(data) {
104
+
105
+ const obj = new Example(data);
106
+ return obj.save();
107
+
108
+ },
109
+
110
+ /**
111
+ * Method to update a record
112
+ * @param {ObjectID} id
113
+ * @param {Object} data
114
+ * @returns {Promise}
115
+ */
116
+ update(_id, data) {
117
+
118
+ return Example.getExample(_id)
119
+ .then( (record) => {
120
+
121
+ // Merge current info with incoming values
122
+ const merged = { ...record, ...data };
123
+
124
+ return Example
125
+ .findOneAndUpdate({ _id }, merged, { new: true })
126
+ .then( (r) => {
127
+
128
+ const tmp = r.toObject({ transform: true });
129
+ return tmp;
130
+
131
+ });
132
+
133
+ });
134
+
135
+ },
136
+
137
+ /**
138
+ * Method to delete a record
139
+ * @param {ObjectID} id
140
+ * @returns {Promise}
141
+ */
142
+ delete(id) {
143
+
144
+ // Soft delete
145
+ return this.update(id, { active: false });
146
+
147
+ },
148
+
149
+ /**
150
+ * Before validate callback — runs before beforeSave, as part of obj.save()
151
+ * (create() above). Does NOT run for update()/delete(): Mongoose's update
152
+ * validators (runValidators) validate each changed path directly and never
153
+ * go through this callback, even when a validator rejects the value.
154
+ * @param {Callback} cb
155
+ */
156
+ beforeValidate(cb) {
157
+
158
+ console.log('Running callback before validate');
159
+
160
+ // All good!
161
+ cb();
162
+
163
+ },
164
+
165
+ /**
166
+ * Callback after validate
167
+ * @param {Callback} cb
168
+ */
169
+ afterValidate(cb) {
170
+
171
+ console.log('Running callback after validate');
172
+
173
+ // All good!
174
+ cb();
175
+
176
+ },
177
+
178
+ /**
179
+ * Before save callback
180
+ * @param {Callback} cb
181
+ */
182
+ beforeSave(cb) {
183
+
184
+ const doc = this;
185
+
186
+ console.log('Running callback before save');
187
+ console.log(doc);
188
+
189
+ // All good!
190
+ cb();
191
+
192
+ },
193
+
194
+ /**
195
+ * Callback after save
196
+ * @param {Callback} cb
197
+ */
198
+ afterSave(doc, cb) {
199
+
200
+ console.log('Running callback after save');
201
+ console.log(doc);
202
+
203
+ // All good!
204
+ cb();
205
+
206
+ },
207
+
208
+ /**
209
+ * Before findOneAndUpdate callback — runs on update() and delete() above,
210
+ * since both call Example.findOneAndUpdate() directly. `this` is the Query,
211
+ * not the document.
212
+ * @param {Callback} cb
213
+ */
214
+ beforeFindOneAndUpdate(cb) {
215
+
216
+ console.log('Running callback before findOneAndUpdate');
217
+
218
+ // All good!
219
+ cb();
220
+
221
+ },
222
+
223
+ /**
224
+ * Callback after findOneAndUpdate
225
+ * @param {Object} doc Updated document
226
+ * @param {Callback} cb
227
+ */
228
+ afterFindOneAndUpdate(doc, cb) {
229
+
230
+ console.log('Running callback after findOneAndUpdate');
231
+ console.log(doc);
232
+
233
+ // All good!
234
+ cb();
235
+
236
+ },
237
+
238
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * ExampleWithScaffold.js
3
+ */
4
+
5
+ // This is an example for a simple model that provides CRUD operations with a scaffold.
6
+ // Provide a flexible way to implement business logic in the model, which is a good practice
7
+ // to keep the controller thin and focused on handling requests and responses.
8
+
9
+ // Scaffold (Model name: ExampleWithScaffold) - Allowed Methods:
10
+ // ExampleWidthScaffold.getAllExampleWidthScaffold(props) { page, perPage, search, sort }
11
+ // ExampleWidthScaffold.getAll(props) (alias to getAllModelName)
12
+ // ExampleWidthScaffold.create(payload) { name, age }
13
+ // ExampleWidthScaffold.getByField(email, 'email') (alias)
14
+ // ExampleWidthScaffold.getExampleWidthScaffold(id)
15
+ // ExampleWidthScaffold.update(id, payload)
16
+ // ExampleWidthScaffold.delete(id)
17
+
18
+ module.exports = {
19
+
20
+ /**
21
+ * Fillable fields for the update method
22
+ * to prevent update of non-allowed fields like createdAt, updatedAt, etc.
23
+ * @type Array
24
+ */
25
+ fillable: ['name', 'age'],
26
+
27
+ /**
28
+ * Fields
29
+ */
30
+ attributes: {
31
+ name: {
32
+ type: String,
33
+ required: true
34
+ },
35
+ age: {
36
+ type: Number,
37
+ required: false,
38
+ validate: {
39
+ validator: (value) => {
40
+ const isValid = (value >= 21) ? true : false;
41
+ return isValid;
42
+ },
43
+ message: 'Invalid Age: Must be +21.',
44
+ }
45
+ },
46
+ // the fields:
47
+ // active, createdAt, updatedAt
48
+ // was created automatically
49
+ }
50
+
51
+ };
@@ -0,0 +1,55 @@
1
+ /* global app */
2
+
3
+ /**
4
+ * Alias Route Mappings
5
+ *
6
+ * Your routes map URLs to views and controllers.
7
+ *
8
+ * Notes: Vulkano automatically matches the URL to a controller
9
+ * and HTTP method (get, post, put, delete) ;)
10
+ *
11
+ * Example:
12
+ * - GET /users/ -> File: UsersController, Method: 'get': (req, res) => {}
13
+ * - GET /users/123 -> File: UsersController, Method: 'get :id': (req, res) => {}
14
+ * - POST /users/ -> File: UsersController, Method: 'post': (req, res) => {}
15
+ * - PUT /users/123 -> File: UsersController, Method: 'put :id': (req, res) => {}
16
+ * - DELETE /users/123 -> File: UsersController, Method: 'delete :id': (req, res) => {}
17
+ *
18
+ * With nested folders, the same rules apply:
19
+ * - GET /api/users/123 -> Folder: api -> File: UsersController, Method: 'get :id': (req, res) => {}
20
+ *
21
+ * But you can write your own routes manually :P
22
+ *
23
+ */
24
+
25
+ module.exports = {
26
+
27
+ // Routes as string - Simple and easy to use
28
+ '/about-me': 'AboutController.get',
29
+
30
+ // Catch-all for React/Vue Router (SPA)
31
+ '/admin*': 'AdminController.get',
32
+
33
+ // Routes as definition - Most flexible
34
+ '/test': (req, res) => {
35
+ res.json({ message: 'Hello, world!' });
36
+ },
37
+
38
+ // Routes as method - More Advanced
39
+ custom() {
40
+
41
+ app.vulkano.get('/test', (req, res) => {
42
+ res.json({ hello: 'world' });
43
+ });
44
+
45
+ app.vulkano.get('/test2', (req, res) => {
46
+ res.json({ hello: 'world2' });
47
+ });
48
+
49
+ app.vulkano.get('/test3', (req, res) => {
50
+ res.json({ hello: 'world3' });
51
+ });
52
+
53
+ }
54
+
55
+ };
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE HTML>
2
+ <html lang="en">
3
+ <head>
4
+ <title>{{ title }}</title>
5
+ <meta charset=UTF-8 >
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <link rel="shortcut icon" type="image/png" href="/favicon.png?v={{ app.pkg.version }}" />
9
+
10
+ {{ vite({ entry: 'app', type: 'style' }) | safe }}
11
+
12
+ </head>
13
+ <body>
14
+
15
+ <div id="app">{% block content %}{% endblock %}</div>
16
+
17
+ {{ vite({ entry: 'app', type: 'script' }) | safe }}
18
+
19
+ </body>
20
+ </html>
@@ -0,0 +1,7 @@
1
+ {% extends "_shared/templates/default.html" %}
2
+
3
+ {% block content %}
4
+
5
+ Your content goes here.
6
+
7
+ {% endblock %}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vulkano/core",
3
- "version": "1.20.1",
3
+ "version": "1.22.0",
4
4
  "description": "A MVC framework using Express 4",
5
5
  "license": "MIT",
6
6
  "author": "Vulkano Team",
@@ -4,10 +4,16 @@ allowBuilds:
4
4
  catalog:
5
5
  vite: npm:@voidzero-dev/vite-plus-core@latest
6
6
  vitest: npm:@voidzero-dev/vite-plus-test@latest
7
- vite-plus: latest
7
+ vite-plus: ^0.2.4
8
8
  overrides:
9
9
  vite: "catalog:"
10
10
  vitest: "catalog:"
11
+ # Safety floor for the real "vite" package pnpm auto-installs to satisfy
12
+ # @voidzero-dev/vite-plus-test / @vitest/mocker's peerDependency (they
13
+ # require actual vite, not the vite-plus-core alias). Keeps it above the
14
+ # server.fs.deny bypass (GHSA-v6wh-96g9-6wx3), fixed in 8.0.16.
15
+ "@vitest/mocker>vite": ^8.1.4
16
+ "@voidzero-dev/vite-plus-test>vite": ^8.1.4
11
17
  peerDependencyRules:
12
18
  allowAny:
13
19
  - vite