@mongoosejs/studio 0.0.32 → 0.0.33

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.
@@ -19,23 +19,9 @@ module.exports = ({ db }) => async function getDashboard(params) {
19
19
 
20
20
  const dashboard = await Dashboard.findOne({ _id: dashboardId });
21
21
  if (evaluate) {
22
- const context = vm.createContext({ db });
23
22
  let result = null;
24
23
  try {
25
- result = await vm.runInContext(formatFunction(dashboard.code), context);
26
- if (result.$document?.model) {
27
- let schemaPaths = {};
28
- const Model = Dashboard.db.model(result.$document?.model);
29
- for (const path of Object.keys(Model.schema.paths)) {
30
- schemaPaths[path] = {
31
- instance: Model.schema.paths[path].instance,
32
- path,
33
- ref: Model.schema.paths[path].options?.ref,
34
- required: Model.schema.paths[path].options?.required
35
- };
36
- }
37
- result.$document.schemaPaths = schemaPaths;
38
- }
24
+ result = await dashboard.evaluate();
39
25
  } catch (error) {
40
26
  return { dashboard, error: { message: error.message } };
41
27
  }
@@ -44,8 +30,4 @@ module.exports = ({ db }) => async function getDashboard(params) {
44
30
  }
45
31
 
46
32
  return { dashboard };
47
- };
48
-
49
- const formatFunction = code => `(async function() {
50
- ${code}
51
- })();`
33
+ };
@@ -3,23 +3,30 @@
3
3
  const Archetype = require('archetype');
4
4
 
5
5
  const UpdateDashboardParams = new Archetype({
6
- dashboardId: {
7
- $type: 'string',
8
- $required: true
9
- },
10
- code: {
11
- $type: 'string',
12
- $required: true
13
- }
14
- }).compile('UpdateDashboardParams');
15
-
16
- module.exports = ({ db }) => async function updateDashboard(params) {
17
- const { dashboardId, code } = new UpdateDashboardParams(params);
6
+ dashboardId: {
7
+ $type: 'string',
8
+ $required: true
9
+ },
10
+ code: {
11
+ $type: 'string',
12
+ $required: true
13
+ }
14
+ }).compile('UpdateDashboardParams');
15
+
16
+ module.exports = ({ db }) => async function updateDashboard(params) {
17
+ const { dashboardId, code } = new UpdateDashboardParams(params);
18
+
19
+ const Dashboard = db.models[`__Studio_Dashboard`];
20
+
21
+ const doc = await Dashboard.
22
+ findByIdAndUpdate(dashboardId, { code }, { sanitizeFilter: true, returnDocument: 'after', overwriteImmutable: true });
18
23
 
19
- const Dashboard = db.models[`__Studio_Dashboard`];
20
-
21
- const doc = await Dashboard.
22
- findByIdAndUpdate(dashboardId, { code }, { sanitizeFilter: true, returnDocument: 'after', overwriteImmutable: true });
23
-
24
- return { doc };
25
- };
24
+ let result = null;
25
+ try {
26
+ result = await doc.evaluate();
27
+ } catch (error) {
28
+ return { doc, error: { message: error.message } };
29
+ }
30
+
31
+ return { doc, result };
32
+ };
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const mongoose = require('mongoose');
4
+ const vm = require('vm');
4
5
 
5
6
  const dashboardSchema = new mongoose.Schema({
6
7
  title: {
@@ -16,4 +17,29 @@ const dashboardSchema = new mongoose.Schema({
16
17
  }
17
18
  });
18
19
 
19
- module.exports = dashboardSchema;
20
+ dashboardSchema.methods.evaluate = async function evaluate() {
21
+ const context = vm.createContext({ db: this.constructor.db });
22
+ let result = null;
23
+ result = await vm.runInContext(formatFunction(this.code), context);
24
+ if (result.$document?.model) {
25
+ let schemaPaths = {};
26
+ const Model = this.constructor.db.model(result.$document?.model);
27
+ for (const path of Object.keys(Model.schema.paths)) {
28
+ schemaPaths[path] = {
29
+ instance: Model.schema.paths[path].instance,
30
+ path,
31
+ ref: Model.schema.paths[path].options?.ref,
32
+ required: Model.schema.paths[path].options?.required
33
+ };
34
+ }
35
+ result.$document.schemaPaths = schemaPaths;
36
+ }
37
+
38
+ return result;
39
+ };
40
+
41
+ module.exports = dashboardSchema;
42
+
43
+ const formatFunction = code => `(async function() {
44
+ ${code}
45
+ })();`
@@ -462,6 +462,7 @@ const template = __webpack_require__(/*! ./dashboard.html */ "./frontend/src/das
462
462
 
463
463
  module.exports = app => app.component('dashboard', {
464
464
  template: template,
465
+ props: ['dashboardId'],
465
466
  data: function() {
466
467
  return {
467
468
  status: 'loading',
@@ -476,12 +477,12 @@ module.exports = app => app.component('dashboard', {
476
477
  this.showEditor = !this.showEditor;
477
478
  },
478
479
  async updateCode(update) {
479
- this.code = update;
480
+ this.code = update.doc.code;
481
+ this.result = update.result;
480
482
  }
481
483
  },
482
484
  mounted: async function() {
483
- const dashboardId = this.$route.query.dashboardId;
484
- const { dashboard, result } = await api.Dashboard.getDashboard({ dashboardId: dashboardId, evaluate: true });
485
+ const { dashboard, result } = await api.Dashboard.getDashboard({ dashboardId: this.dashboardId, evaluate: true });
485
486
  if (!dashboard) {
486
487
  return;
487
488
  }
@@ -521,8 +522,11 @@ module.exports = app => app.component('edit-dashboard', {
521
522
  this.$emit('close')
522
523
  },
523
524
  async updateCode() {
524
- const { doc } = await api.Dashboard.updateDashboard({ dashboardId: this.dashboardId, code: this.editor.getValue() });
525
- this.$emit('update', doc.code);
525
+ const { doc, result } = await api.Dashboard.updateDashboard({
526
+ dashboardId: this.dashboardId,
527
+ code: this.editor.getValue()
528
+ });
529
+ this.$emit('update', { doc, result });
526
530
  this.editor.setValue(doc.code);
527
531
  this.closeEditor();
528
532
  }
@@ -1775,7 +1779,7 @@ module.exports = [
1775
1779
  component: 'dashboards'
1776
1780
  },
1777
1781
  {
1778
- path: '/dashboard',
1782
+ path: '/dashboard/:dashboardId',
1779
1783
  name: 'dashboard',
1780
1784
  component: 'dashboard'
1781
1785
  }
@@ -2500,7 +2504,7 @@ module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=
2500
2504
  /***/ ((module) => {
2501
2505
 
2502
2506
  "use strict";
2503
- module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"dashboard\" class=\"max-w-5xl mx-auto\">\n <div class=\"flex items-center w-full\">\n <h2 class=\"mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink\">{{dashboard.title}}</h2>\n <div>\n <button\n v-if=\"!showEditor\"\n @click=\"showEditor = true\"\n type=\"button\"\n class=\"rounded-md bg-teal-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <img src=\"images/edit.svg\" class=\"inline h-[1em]\" /> Edit\n </button>\n </div>\n </div>\n <div v-if=\"!showEditor\" class=\"mt-4 mb-4\">\n <dashboard-result :result=\"result\"></dashboard-result>\n </div>\n <div v-if=\"showEditor\">\n <edit-dashboard :dashboardId=\"dashboard._id\" :code=\"code\" @close=\"showEditor=false;\" @update=\"updateCode\"></edit-dashboard>\n </div>\n \n </div>\n <div v-if=\"!dashboard && status === 'loaded'\">\n No dashboard with the given id could be found.\n </div>\n</div>";
2507
+ module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"dashboard\" class=\"max-w-5xl mx-auto\">\n <div class=\"flex items-center w-full\">\n <h2 class=\"mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink\">{{dashboard.title}}</h2>\n <div>\n <button\n v-if=\"!showEditor\"\n @click=\"showEditor = true\"\n type=\"button\"\n class=\"rounded-md bg-teal-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <img src=\"images/edit.svg\" class=\"inline h-[1em]\" /> Edit\n </button>\n </div>\n </div>\n <div v-if=\"!showEditor\" class=\"mt-4 mb-4\">\n <dashboard-result :result=\"result\"></dashboard-result>\n </div>\n <div v-if=\"showEditor\">\n <edit-dashboard\n :dashboardId=\"dashboard._id\"\n :code=\"code\"\n @close=\"showEditor=false;\"\n @update=\"updateCode\"></edit-dashboard>\n </div>\n \n </div>\n <div v-if=\"!dashboard && status === 'loaded'\">\n No dashboard with the given id could be found.\n </div>\n</div>";
2504
2508
 
2505
2509
  /***/ }),
2506
2510
 
@@ -2522,7 +2526,7 @@ module.exports = "<div>\n <textarea ref=\"codeEditor\">{{code}}</textarea>\n
2522
2526
  /***/ ((module) => {
2523
2527
 
2524
2528
  "use strict";
2525
- module.exports = "<div class=\"dashboards max-w-5xl mx-auto mt-8\">\n <div v-if=\"status === 'loaded' && dashboards.length === 0\">\n <div class=\"text-center\">\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No dashboards yet</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Get started by creating a new dashboard.</p>\n <div class=\"mt-6\">\n <button type=\"button\" class=\"inline-flex items-center rounded-md bg-teal-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Dashboard\n </button>\n </div>\n </div>\n </div>\n\n\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-base font-semibold leading-6 text-gray-900\">Dashboards</h1>\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showCreateDashboardModal = true\"\n class=\"block rounded-md bg-teal-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">Create New Dashboard</button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\">\n <div class=\"-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"inline-block min-w-full py-2 align-middle\">\n <table class=\"min-w-full divide-y divide-gray-300\">\n <thead>\n <tr>\n <th scope=\"col\" class=\"py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8\">Title</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]\">Description</th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"dashboard in dashboards\">\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8\">{{dashboard.title}}</td>\n <td class=\"whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]\">{{dashboard.description}}</td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'dashboard?edit=true&dashboardId=' + dashboard._id\"\n class=\"text-teal-600 hover:text-teal-900\">\n Edit\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'dashboard?edit=true&dashboardId=' + dashboard._id\"\n class=\"text-teal-600 hover:text-teal-900\">\n View\n </router-link>\n </td>\n </tr>\n \n <!-- More people... -->\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showCreateDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false;\">&times;</div>\n \n <create-dashboard></create-dashboard>\n </template>\n </modal>\n</div>";
2529
+ module.exports = "<div class=\"dashboards max-w-5xl mx-auto mt-8\">\n <div v-if=\"status === 'loaded' && dashboards.length === 0\">\n <div class=\"text-center\">\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No dashboards yet</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Get started by creating a new dashboard.</p>\n <div class=\"mt-6\">\n <button type=\"button\" class=\"inline-flex items-center rounded-md bg-teal-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Dashboard\n </button>\n </div>\n </div>\n </div>\n\n\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-base font-semibold leading-6 text-gray-900\">Dashboards</h1>\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showCreateDashboardModal = true\"\n class=\"block rounded-md bg-teal-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">Create New Dashboard</button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\">\n <div class=\"-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"inline-block min-w-full py-2 align-middle\">\n <table class=\"min-w-full divide-y divide-gray-300\">\n <thead>\n <tr>\n <th scope=\"col\" class=\"py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8\">Title</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]\">Description</th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"dashboard in dashboards\">\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8\">{{dashboard.title}}</td>\n <td class=\"whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]\">{{dashboard.description}}</td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id + '?edit=true'\"\n class=\"text-teal-600 hover:text-teal-900\">\n Edit\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id\"\n class=\"text-teal-600 hover:text-teal-900\">\n View\n </router-link>\n </td>\n </tr>\n \n <!-- More people... -->\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showCreateDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false;\">&times;</div>\n \n <create-dashboard></create-dashboard>\n </template>\n </modal>\n</div>";
2526
2530
 
2527
2531
  /***/ }),
2528
2532
 
@@ -16,7 +16,11 @@
16
16
  <dashboard-result :result="result"></dashboard-result>
17
17
  </div>
18
18
  <div v-if="showEditor">
19
- <edit-dashboard :dashboardId="dashboard._id" :code="code" @close="showEditor=false;" @update="updateCode"></edit-dashboard>
19
+ <edit-dashboard
20
+ :dashboardId="dashboard._id"
21
+ :code="code"
22
+ @close="showEditor=false;"
23
+ @update="updateCode"></edit-dashboard>
20
24
  </div>
21
25
 
22
26
  </div>
@@ -5,6 +5,7 @@ const template = require('./dashboard.html');
5
5
 
6
6
  module.exports = app => app.component('dashboard', {
7
7
  template: template,
8
+ props: ['dashboardId'],
8
9
  data: function() {
9
10
  return {
10
11
  status: 'loading',
@@ -19,12 +20,12 @@ module.exports = app => app.component('dashboard', {
19
20
  this.showEditor = !this.showEditor;
20
21
  },
21
22
  async updateCode(update) {
22
- this.code = update;
23
+ this.code = update.doc.code;
24
+ this.result = update.result;
23
25
  }
24
26
  },
25
27
  mounted: async function() {
26
- const dashboardId = this.$route.query.dashboardId;
27
- const { dashboard, result } = await api.Dashboard.getDashboard({ dashboardId: dashboardId, evaluate: true });
28
+ const { dashboard, result } = await api.Dashboard.getDashboard({ dashboardId: this.dashboardId, evaluate: true });
28
29
  if (!dashboard) {
29
30
  return;
30
31
  }
@@ -17,8 +17,11 @@ module.exports = app => app.component('edit-dashboard', {
17
17
  this.$emit('close')
18
18
  },
19
19
  async updateCode() {
20
- const { doc } = await api.Dashboard.updateDashboard({ dashboardId: this.dashboardId, code: this.editor.getValue() });
21
- this.$emit('update', doc.code);
20
+ const { doc, result } = await api.Dashboard.updateDashboard({
21
+ dashboardId: this.dashboardId,
22
+ code: this.editor.getValue()
23
+ });
24
+ this.$emit('update', { doc, result });
22
25
  this.editor.setValue(doc.code);
23
26
  this.closeEditor();
24
27
  }
@@ -47,14 +47,14 @@
47
47
  <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]">{{dashboard.description}}</td>
48
48
  <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
49
49
  <router-link
50
- :to="'dashboard?edit=true&dashboardId=' + dashboard._id"
50
+ :to="'/dashboard/' + dashboard._id + '?edit=true'"
51
51
  class="text-teal-600 hover:text-teal-900">
52
52
  Edit
53
53
  </router-link>
54
54
  </td>
55
55
  <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
56
56
  <router-link
57
- :to="'dashboard?edit=true&dashboardId=' + dashboard._id"
57
+ :to="'/dashboard/' + dashboard._id"
58
58
  class="text-teal-600 hover:text-teal-900">
59
59
  View
60
60
  </router-link>
@@ -27,7 +27,7 @@ module.exports = [
27
27
  component: 'dashboards'
28
28
  },
29
29
  {
30
- path: '/dashboard',
30
+ path: '/dashboard/:dashboardId',
31
31
  name: 'dashboard',
32
32
  component: 'dashboard'
33
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mongoosejs/studio",
3
- "version": "0.0.32",
3
+ "version": "0.0.33",
4
4
  "dependencies": {
5
5
  "archetype": "0.13.0",
6
6
  "csv-stringify": "6.3.0",