@mongoosejs/studio 0.1.19 → 0.1.20
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.
- package/backend/actions/Model/getDocument.js +2 -1
- package/backend/actions/Model/getDocuments.js +3 -2
- package/backend/actions/Model/getDocumentsStream.js +3 -2
- package/backend/helpers/getRefFromSchemaType.js +5 -0
- package/frontend/public/app.js +31 -6
- package/frontend/src/list-json/json-node.html +1 -1
- package/frontend/src/list-json/list-json.js +28 -3
- package/frontend/src/models/models.js +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Archetype = require('archetype');
|
|
4
|
+
const getRefFromSchemaType = require('../../helpers/getRefFromSchemaType');
|
|
4
5
|
const removeSpecifiedPaths = require('../../helpers/removeSpecifiedPaths');
|
|
5
6
|
const authorize = require('../../authorize');
|
|
6
7
|
|
|
@@ -37,7 +38,7 @@ module.exports = ({ db }) => async function getDocument(params) {
|
|
|
37
38
|
schemaPaths[path] = {
|
|
38
39
|
instance: Model.schema.paths[path].instance,
|
|
39
40
|
path,
|
|
40
|
-
ref: Model.schema.paths[path]
|
|
41
|
+
ref: getRefFromSchemaType(Model.schema.paths[path]),
|
|
41
42
|
required: Model.schema.paths[path].options?.required,
|
|
42
43
|
enum: Model.schema.paths[path].options?.enum
|
|
43
44
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const Archetype = require('archetype');
|
|
4
4
|
const removeSpecifiedPaths = require('../../helpers/removeSpecifiedPaths');
|
|
5
5
|
const evaluateFilter = require('../../helpers/evaluateFilter');
|
|
6
|
+
const getRefFromSchemaType = require('../../helpers/getRefFromSchemaType');
|
|
6
7
|
const authorize = require('../../authorize');
|
|
7
8
|
|
|
8
9
|
const GetDocumentsParams = new Archetype({
|
|
@@ -77,7 +78,7 @@ module.exports = ({ db }) => async function getDocuments(params) {
|
|
|
77
78
|
schemaPaths[path] = {
|
|
78
79
|
instance: schemaType.instance,
|
|
79
80
|
path,
|
|
80
|
-
ref: schemaType
|
|
81
|
+
ref: getRefFromSchemaType(schemaType),
|
|
81
82
|
required: schemaType.options?.required,
|
|
82
83
|
enum: schemaType.options?.enum
|
|
83
84
|
};
|
|
@@ -87,7 +88,7 @@ module.exports = ({ db }) => async function getDocuments(params) {
|
|
|
87
88
|
schemaPaths[path].schema[subpath] = {
|
|
88
89
|
instance: schemaType.schema.paths[subpath].instance,
|
|
89
90
|
path: subpath,
|
|
90
|
-
ref: schemaType.schema.paths[subpath]
|
|
91
|
+
ref: getRefFromSchemaType(schemaType.schema.paths[subpath]),
|
|
91
92
|
required: schemaType.schema.paths[subpath].options?.required,
|
|
92
93
|
enum: schemaType.schema.paths[subpath].options?.enum
|
|
93
94
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const Archetype = require('archetype');
|
|
4
4
|
const removeSpecifiedPaths = require('../../helpers/removeSpecifiedPaths');
|
|
5
5
|
const evaluateFilter = require('../../helpers/evaluateFilter');
|
|
6
|
+
const getRefFromSchemaType = require('../../helpers/getRefFromSchemaType');
|
|
6
7
|
const authorize = require('../../authorize');
|
|
7
8
|
|
|
8
9
|
const GetDocumentsParams = new Archetype({
|
|
@@ -67,7 +68,7 @@ module.exports = ({ db }) => async function* getDocumentsStream(params) {
|
|
|
67
68
|
schemaPaths[path] = {
|
|
68
69
|
instance: schemaType.instance,
|
|
69
70
|
path,
|
|
70
|
-
ref: schemaType
|
|
71
|
+
ref: getRefFromSchemaType(schemaType),
|
|
71
72
|
required: schemaType.options?.required,
|
|
72
73
|
enum: schemaType.options?.enum
|
|
73
74
|
};
|
|
@@ -77,7 +78,7 @@ module.exports = ({ db }) => async function* getDocumentsStream(params) {
|
|
|
77
78
|
schemaPaths[path].schema[subpath] = {
|
|
78
79
|
instance: schemaType.schema.paths[subpath].instance,
|
|
79
80
|
path: subpath,
|
|
80
|
-
ref: schemaType.schema.paths[subpath]
|
|
81
|
+
ref: getRefFromSchemaType(schemaType.schema.paths[subpath]),
|
|
81
82
|
required: schemaType.schema.paths[subpath].options?.required,
|
|
82
83
|
enum: schemaType.schema.paths[subpath].options?.enum
|
|
83
84
|
};
|
package/frontend/public/app.js
CHANGED
|
@@ -4349,7 +4349,7 @@ module.exports = app => app.component('list-default', {
|
|
|
4349
4349
|
(module) {
|
|
4350
4350
|
|
|
4351
4351
|
"use strict";
|
|
4352
|
-
module.exports = "<div>\n <div class=\"flex items-baseline whitespace-pre\" :style=\"indentStyle\">\n <button\n v-if=\"showToggle\"\n type=\"button\"\n class=\"w-4 h-4 mr-1 inline-flex items-center justify-center leading-none text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-slate-400 cursor-pointer\"\n @click.stop=\"handleToggle\"\n >\n {{ isCollapsedNode ? '+' : '-' }}\n </button>\n <span v-else class=\"w-4 h-4 mr-1 inline-flex items-center justify-center invisible flex-shrink-0\"></span>\n <template v-if=\"hasKey\">\n <span class=\"text-blue-600\">\"{{ nodeKey }}\"</span><span>: </span>\n </template>\n <template v-if=\"isComplex\">\n <template v-if=\"hasChildren\">\n <span>{{ openingBracket }}</span>\n <span v-if=\"isCollapsedNode\" class=\"mx-1\">…</span>\n <span v-if=\"isCollapsedNode\">{{ closingBracket }}{{ comma }}</span>\n </template>\n <template v-else>\n <span>{{ openingBracket }}{{ closingBracket }}{{ comma }}</span>\n </template>\n </template>\n <template v-else>\n <!--\n If value is a string and overflows its container (i.e. goes over one line), show an ellipsis.\n This is done via CSS ellipsis strategy.\n -->\n <span\n v-if=\"shouldShowReferenceLink\"\n class=\"inline-flex items-baseline group\"\n >\n <span\n :class=\"[...valueClasses, 'underline', 'decoration-dotted', 'underline-offset-2']\"\n :style=\"typeof value === 'string'\n ? {\n display: 'inline-block',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom'\n }\n : {}\"\n :title=\"typeof value === 'string' && $el && $el.scrollWidth > $el.clientWidth ? value : undefined\"\n >\n {{ formattedValue }}\n </span>\n <span>\n {{ comma }}\n </span>\n <a\n href=\"#\"\n class=\"ml-1 text-sm text-sky-700 opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity\"\n @click.stop.prevent=\"goToReference(
|
|
4352
|
+
module.exports = "<div>\n <div class=\"flex items-baseline whitespace-pre\" :style=\"indentStyle\">\n <button\n v-if=\"showToggle\"\n type=\"button\"\n class=\"w-4 h-4 mr-1 inline-flex items-center justify-center leading-none text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-slate-400 cursor-pointer\"\n @click.stop=\"handleToggle\"\n >\n {{ isCollapsedNode ? '+' : '-' }}\n </button>\n <span v-else class=\"w-4 h-4 mr-1 inline-flex items-center justify-center invisible flex-shrink-0\"></span>\n <template v-if=\"hasKey\">\n <span class=\"text-blue-600\">\"{{ nodeKey }}\"</span><span>: </span>\n </template>\n <template v-if=\"isComplex\">\n <template v-if=\"hasChildren\">\n <span>{{ openingBracket }}</span>\n <span v-if=\"isCollapsedNode\" class=\"mx-1\">…</span>\n <span v-if=\"isCollapsedNode\">{{ closingBracket }}{{ comma }}</span>\n </template>\n <template v-else>\n <span>{{ openingBracket }}{{ closingBracket }}{{ comma }}</span>\n </template>\n </template>\n <template v-else>\n <!--\n If value is a string and overflows its container (i.e. goes over one line), show an ellipsis.\n This is done via CSS ellipsis strategy.\n -->\n <span\n v-if=\"shouldShowReferenceLink\"\n class=\"inline-flex items-baseline group\"\n >\n <span\n :class=\"[...valueClasses, 'underline', 'decoration-dotted', 'underline-offset-2']\"\n :style=\"typeof value === 'string'\n ? {\n display: 'inline-block',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom'\n }\n : {}\"\n :title=\"typeof value === 'string' && $el && $el.scrollWidth > $el.clientWidth ? value : undefined\"\n >\n {{ formattedValue }}\n </span>\n <span>\n {{ comma }}\n </span>\n <a\n href=\"#\"\n class=\"ml-1 text-sm text-sky-700 opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity\"\n @click.stop.prevent=\"goToReference()\"\n >\n View Document\n </a>\n </span>\n <span\n v-else\n :class=\"valueClasses\"\n :style=\"typeof value === 'string'\n ? {\n display: 'inline-block',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom'\n }\n : {}\"\n :title=\"typeof value === 'string' && $el && $el.scrollWidth > $el.clientWidth ? value : undefined\"\n >\n {{ formattedValue }}{{ comma }}\n </span>\n </template>\n </div>\n <template v-if=\"isComplex && hasChildren && !isCollapsedNode\">\n <json-node\n v-for=\"child in children\"\n :key=\"child.path\"\n :node-key=\"child.displayKey\"\n :value=\"child.value\"\n :level=\"level + 1\"\n :is-last=\"child.isLast\"\n :path=\"child.path\"\n :toggle-collapse=\"toggleCollapse\"\n :is-collapsed=\"isCollapsed\"\n :create-child-path=\"createChildPath\"\n :indent-size=\"indentSize\"\n :max-top-level-fields=\"maxTopLevelFields\"\n :top-level-expanded=\"topLevelExpanded\"\n :expand-top-level=\"expandTopLevel\"\n :references=\"references\"\n ></json-node>\n <div\n v-if=\"hasHiddenRootChildren\"\n class=\"flex items-baseline whitespace-pre\"\n :style=\"indentStyle\"\n >\n <span class=\"w-4 h-4 mr-1 inline-flex items-center justify-center invisible\"></span>\n <button\n type=\"button\"\n class=\"text-xs inline-flex items-center gap-1 ml-4 text-slate-500 hover:text-slate-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-slate-400\"\n :title=\"hiddenChildrenTooltip\"\n @click.stop=\"handleExpandTopLevel\"\n >\n <span aria-hidden=\"true\">{{hiddenChildrenLabel}}…</span>\n </button>\n </div>\n <div class=\"flex items-baseline whitespace-pre\" :style=\"indentStyle\">\n <span class=\"w-4 h-4 mr-1 inline-flex items-center justify-center invisible\"></span>\n <span>{{ closingBracket }}{{ comma }}</span>\n </div>\n </template>\n</div>\n";
|
|
4353
4353
|
|
|
4354
4354
|
/***/ },
|
|
4355
4355
|
|
|
@@ -4650,7 +4650,31 @@ module.exports = app => app.component('list-json', {
|
|
|
4650
4650
|
return this.references[this.normalizedPath] || null;
|
|
4651
4651
|
},
|
|
4652
4652
|
shouldShowReferenceLink() {
|
|
4653
|
-
return
|
|
4653
|
+
return this.referenceId != null;
|
|
4654
|
+
},
|
|
4655
|
+
referenceId() {
|
|
4656
|
+
if (!this.referenceModel) {
|
|
4657
|
+
return null;
|
|
4658
|
+
}
|
|
4659
|
+
if (this.value == null) {
|
|
4660
|
+
return null;
|
|
4661
|
+
}
|
|
4662
|
+
const type = typeof this.value;
|
|
4663
|
+
if (type === 'string' || type === 'number' || type === 'bigint') {
|
|
4664
|
+
return String(this.value);
|
|
4665
|
+
}
|
|
4666
|
+
if (type === 'object') {
|
|
4667
|
+
if (this.value._id != null) {
|
|
4668
|
+
return String(this.value._id);
|
|
4669
|
+
}
|
|
4670
|
+
if (typeof this.value.toString === 'function') {
|
|
4671
|
+
const stringified = this.value.toString();
|
|
4672
|
+
if (typeof stringified === 'string' && stringified !== '[object Object]') {
|
|
4673
|
+
return stringified;
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4677
|
+
return null;
|
|
4654
4678
|
}
|
|
4655
4679
|
},
|
|
4656
4680
|
methods: {
|
|
@@ -4676,8 +4700,9 @@ module.exports = app => app.component('list-json', {
|
|
|
4676
4700
|
this.expandTopLevel();
|
|
4677
4701
|
}
|
|
4678
4702
|
},
|
|
4679
|
-
goToReference(
|
|
4680
|
-
|
|
4703
|
+
goToReference() {
|
|
4704
|
+
const id = this.referenceId;
|
|
4705
|
+
if (!this.referenceModel || id == null) {
|
|
4681
4706
|
return;
|
|
4682
4707
|
}
|
|
4683
4708
|
this.$router.push({ path: `/model/${this.referenceModel}/document/${id}` });
|
|
@@ -5298,7 +5323,7 @@ module.exports = app => app.component('models', {
|
|
|
5298
5323
|
this.error = 'No models found and Mongoose is not connected. Check our documentation for more information.';
|
|
5299
5324
|
}
|
|
5300
5325
|
}
|
|
5301
|
-
|
|
5326
|
+
|
|
5302
5327
|
await this.initSearchFromUrl();
|
|
5303
5328
|
},
|
|
5304
5329
|
computed: {
|
|
@@ -31935,7 +31960,7 @@ const compile = () => {
|
|
|
31935
31960
|
(module) {
|
|
31936
31961
|
|
|
31937
31962
|
"use strict";
|
|
31938
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.1.
|
|
31963
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.1.20","description":"A sleek, powerful MongoDB UI with built-in dashboarding and auth, seamlessly integrated with your Express, Vercel, or Netlify app.","homepage":"https://mongoosestudio.app/","repository":{"type":"git","url":"https://github.com/mongoosejs/studio"},"license":"Apache-2.0","dependencies":{"@ai-sdk/anthropic":"2.x","@ai-sdk/google":"2.x","@ai-sdk/openai":"2.x","ai":"5.x","archetype":"0.13.1","csv-stringify":"6.3.0","ejson":"^2.2.3","extrovert":"^0.2.0","marked":"15.0.12","node-inspect-extracted":"3.x","tailwindcss":"3.4.0","vue":"3.x","vue-toastification":"^2.0.0-rc.5","webpack":"5.x"},"peerDependencies":{"mongoose":"7.x || 8.x || ^9.0.0"},"devDependencies":{"@masteringjs/eslint-config":"0.1.1","axios":"1.2.2","dedent":"^1.6.0","eslint":"9.30.0","express":"4.x","mocha":"10.2.0","mongoose":"9.x"},"scripts":{"lint":"eslint .","tailwind":"tailwindcss -o ./frontend/public/tw.css","tailwind:watch":"tailwindcss -o ./frontend/public/tw.css --watch","test":"mocha test/*.test.js"}}');
|
|
31939
31964
|
|
|
31940
31965
|
/***/ }
|
|
31941
31966
|
|
|
@@ -277,7 +277,31 @@ module.exports = app => app.component('list-json', {
|
|
|
277
277
|
return this.references[this.normalizedPath] || null;
|
|
278
278
|
},
|
|
279
279
|
shouldShowReferenceLink() {
|
|
280
|
-
return
|
|
280
|
+
return this.referenceId != null;
|
|
281
|
+
},
|
|
282
|
+
referenceId() {
|
|
283
|
+
if (!this.referenceModel) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
if (this.value == null) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
const type = typeof this.value;
|
|
290
|
+
if (type === 'string' || type === 'number' || type === 'bigint') {
|
|
291
|
+
return String(this.value);
|
|
292
|
+
}
|
|
293
|
+
if (type === 'object') {
|
|
294
|
+
if (this.value._id != null) {
|
|
295
|
+
return String(this.value._id);
|
|
296
|
+
}
|
|
297
|
+
if (typeof this.value.toString === 'function') {
|
|
298
|
+
const stringified = this.value.toString();
|
|
299
|
+
if (typeof stringified === 'string' && stringified !== '[object Object]') {
|
|
300
|
+
return stringified;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
281
305
|
}
|
|
282
306
|
},
|
|
283
307
|
methods: {
|
|
@@ -303,8 +327,9 @@ module.exports = app => app.component('list-json', {
|
|
|
303
327
|
this.expandTopLevel();
|
|
304
328
|
}
|
|
305
329
|
},
|
|
306
|
-
goToReference(
|
|
307
|
-
|
|
330
|
+
goToReference() {
|
|
331
|
+
const id = this.referenceId;
|
|
332
|
+
if (!this.referenceModel || id == null) {
|
|
308
333
|
return;
|
|
309
334
|
}
|
|
310
335
|
this.$router.push({ path: `/model/${this.referenceModel}/document/${id}` });
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "A sleek, powerful MongoDB UI with built-in dashboarding and auth, seamlessly integrated with your Express, Vercel, or Netlify app.",
|
|
5
|
-
"homepage": "https://
|
|
5
|
+
"homepage": "https://mongoosestudio.app/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/mongoosejs/studio"
|