@abi-software/scaffoldvuer 0.4.0-vue3.7 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/scaffoldvuer",
3
- "version": "0.4.0-vue3.7",
3
+ "version": "1.0.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,14 +10,16 @@
10
10
  "serve": "vite --host --force",
11
11
  "build-bundle": "vite build",
12
12
  "build-static": "vite build -c vite.static-build.js",
13
- "vuese-gen": "vuese gen",
13
+ "vuese-gen": "node vuese-generator.js",
14
+ "vuese-watch": "node vuese-generator.js watch",
14
15
  "changelog": "auto-changelog -p --output CHANGELOG.md --template keepachangelog",
15
16
  "version": "npm run build-bundle;npm run changelog; git add CHANGELOG.md",
16
17
  "release:beta": "npm version prerelease --preid=beta; npm publish --tag beta",
17
18
  "release:minor": "npm version minor; npm publish",
18
19
  "release:patch": "npm version patch; npm publish",
19
- "docs:dev": "vuese gen;vitepress dev docs",
20
- "docs:build": "vuese gen;vitepress build docs",
20
+ "docs:dev": "vitepress dev docs",
21
+ "docs:watch": "concurrently \"npm run vuese-watch\" \"npm run docs:dev\"",
22
+ "docs:build": "npm run vuese-gen; vitepress build docs",
21
23
  "docs:preview": "vitepress preview docs"
22
24
  },
23
25
  "type": "module",
@@ -39,30 +41,31 @@
39
41
  "*.js"
40
42
  ],
41
43
  "dependencies": {
42
- "@abi-software/flatmapvuer": "^0.6.0-vue3.2",
43
- "@abi-software/svg-sprite": "^0.4.0-vue3-beta.0",
44
+ "@abi-software/flatmapvuer": "^1.0.0",
45
+ "@abi-software/svg-sprite": "^1.0.0",
44
46
  "@element-plus/icons-vue": "^2.3.1",
45
47
  "@vue/compat": "^3.4.15",
46
- "axios": "^0.21.2",
47
48
  "core-js": "^3.22.5",
48
- "current-script-polyfill": "^1.0.0",
49
49
  "element-plus": "^2.4.4",
50
50
  "minisearch": "^6.0.1",
51
- "query-string": "^6.11.1",
51
+ "pinia": "^2.1.7",
52
52
  "simple-dropzone": "^0.8.3",
53
53
  "unplugin-vue-components": "^0.26.0",
54
54
  "vue": "^3.4.15",
55
55
  "vue-router": "^4.2.5",
56
56
  "vue3-component-svg-sprite": "^0.0.1",
57
- "zincjs": "^1.3.3"
57
+ "zincjs": "^1.5.1-beta.1"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@vitejs/plugin-vue": "^4.6.2",
61
- "@vuese/cli": "^2.14.3",
61
+ "@vuese/markdown-render": "^2.11.3",
62
+ "@vuese/parser": "^2.10.3",
62
63
  "auto-changelog": "^2.4.0",
63
64
  "babel-eslint": "^10.1.0",
64
65
  "babel-plugin-component": "^1.1.1",
65
66
  "base64-inline-loader": "^2.0.1",
67
+ "chokidar": "^3.6.0",
68
+ "concurrently": "^8.2.2",
66
69
  "eslint": "^8.56.0",
67
70
  "eslint-plugin-vue": "^9.19.2",
68
71
  "sass": "^1.69.5",
@@ -88,12 +91,5 @@
88
91
  "browserslist": [
89
92
  "> 1%",
90
93
  "last 2 versions"
91
- ],
92
- "vuese": {
93
- "include": [
94
- "src/components/ScaffoldVuer.vue"
95
- ],
96
- "genType": "markdown",
97
- "outDir": "docs"
98
- }
94
+ ]
99
95
  }
package/src/App.vue CHANGED
@@ -115,6 +115,12 @@
115
115
  Arm slides
116
116
  </el-button>
117
117
  <el-switch v-model="onClickMarkers" active-text="Markers On Selection" active-color="#8300bf" />
118
+ <el-switch
119
+ v-model="wireframe"
120
+ active-text="wireframe"
121
+ active-color="#8300bf"
122
+ @change="wireframeChanged"
123
+ />
118
124
  </el-row>
119
125
  <el-row :gutter="20">
120
126
  <el-input v-model="input" type="textarea" autosize placeholder="Please input"
@@ -204,6 +210,7 @@ export default {
204
210
  helpMode: false,
205
211
  displayMarkers: false,
206
212
  onClickMarkers: false,
213
+ wireframe: false,
207
214
  syncMode: false,
208
215
  currentTime: 0,
209
216
  displayMinimap: false,
@@ -260,6 +267,9 @@ export default {
260
267
  created: function () {
261
268
  texture_prefix = import.meta.env.VITE_TEXTURE_FOOT_PREFIX;
262
269
  },
270
+ unmounted: function () {
271
+ this.$refs.dropzone.revokeURLs();
272
+ },
263
273
  methods: {
264
274
  exportGLTF: function () {
265
275
  this.$refs.scaffold.exportGLTF(false).then((data) => {
@@ -287,9 +297,12 @@ export default {
287
297
  });
288
298
  },
289
299
  objectAdded: function (zincObject) {
290
- if (this._objects.length === 0)
300
+ if (this._objects.length === 0) {
291
301
  zincObject.setMarkerMode("on");
292
- console.log(zincObject);
302
+ }
303
+ if (zincObject.isGeometry) {
304
+ zincObject._lod._material.wireframe = this.wireframe;
305
+ }
293
306
  this._objects.push(zincObject);
294
307
  },
295
308
  openMap: function (map) {
@@ -406,10 +419,14 @@ export default {
406
419
  cameracontrol.stopAutoTumble();
407
420
  }
408
421
  },
422
+ wireframeChanged: function (value) {
423
+ this._objects.forEach((zincObject) => {
424
+ if (zincObject.isGeometry) {
425
+ zincObject._lod._material.wireframe = value;
426
+ }
427
+ });
428
+ },
409
429
  onReady: function () {
410
- console.log("ready");
411
- //window.scaffoldvuer = this.$refs.scaffold;
412
- this.$refs.dropzone.revokeURLs();
413
430
  if (this.readyCallback) {
414
431
  this.readyCallback(this.$refs.scaffold, texture_prefix);
415
432
  this.readyCallback = undefined;
@@ -16,6 +16,12 @@
16
16
  import { SimpleDropzone } from "simple-dropzone";
17
17
  import path from "path";
18
18
 
19
+ const getJSON = async (URL) => {
20
+ return fetch(URL)
21
+ .then((response) => response.json())
22
+ .then((responseJson) => {return responseJson});
23
+ }
24
+
19
25
  export default {
20
26
  name: "DropZone",
21
27
  data: function () {
@@ -33,7 +39,25 @@ export default {
33
39
  });
34
40
  },
35
41
  methods: {
36
- createMetadataObjectURLs: function (text, list) {
42
+ processTextureFile: function(textureData, flatarray) {
43
+ if (textureData && textureData.images && textureData.images.source) {
44
+ const images = textureData.images.source;
45
+ for (let i = 0; i < images.length; i++) {
46
+ const index = flatarray.findIndex(element => {
47
+ return element[0].includes(images[i]);
48
+ });
49
+ if (index > -1) {
50
+ const objectURL = URL.createObjectURL(flatarray[index][1]);
51
+ this.objectURLs.push(objectURL);
52
+ textureData.images.source[i] = objectURL;
53
+ }
54
+ }
55
+ const content = JSON.stringify(textureData);
56
+ let blob = new Blob([content], { type: "application/json" });
57
+ return URL.createObjectURL(blob);
58
+ }
59
+ },
60
+ createMetadataObjectURLs: async function (text, list, flatarray) {
37
61
  let content = text;
38
62
  for (const [key, file] of Object.entries(list)) {
39
63
  if (content.includes(key)) {
@@ -43,7 +67,19 @@ export default {
43
67
  this.objectURLs.push(objectURL);
44
68
  }
45
69
  }
46
- let blob = new Blob([content], { type: "application/json" });
70
+ const data = JSON.parse(content);
71
+ for (let i = 0; i < data.length; i++) {
72
+ if (data[i] && data[i].Type) {
73
+ if (data[i].Type === "Texture") {
74
+ const textureData = await getJSON(data[i].URL);
75
+ URL.revokeObjectURL(data[i].URL);
76
+ const newURL = this.processTextureFile(textureData, flatarray)
77
+ data[i].URL = newURL;
78
+ }
79
+ }
80
+ }
81
+ let newContent = JSON.stringify(data);
82
+ let blob = new Blob([newContent], { type: "application/json" });
47
83
  const metaURL = URL.createObjectURL(blob);
48
84
  this.objectURLs.push(metaURL);
49
85
  this.$emit("files-drop", { url: metaURL, format : "metadata" } );
@@ -60,6 +96,7 @@ export default {
60
96
  this.objectURLs = [];
61
97
  },
62
98
  localDrop: function (fileMap) {
99
+ this.revokeURLs();
63
100
  const dataMaps = {};
64
101
  let list = {};
65
102
  let metadata = undefined;
@@ -94,7 +131,7 @@ export default {
94
131
  const metaFileURL = URL.createObjectURL(metadata.file);
95
132
  fetch(metaFileURL)
96
133
  .then((response) => response.text())
97
- .then((text) => this.createMetadataObjectURLs(text, list));
134
+ .then((text) => this.createMetadataObjectURLs(text, list, flatarray));
98
135
  URL.revokeObjectURL(metaFileURL);
99
136
  }
100
137
  if (gltf) {
@@ -44,7 +44,7 @@ export const testVolume = async (scaffoldVuer, texture_prefix) => {
44
44
  const material = texture.getMaterial(options);
45
45
  zincObject.createMesh(cube, material, meshOptions);
46
46
  scaffoldVuer.addZincObject(zincObject);
47
- zincObject.morph.matrix.set(
47
+ zincObject.getMorph().matrix.set(
48
48
  -100,
49
49
  0,
50
50
  0,
@@ -62,7 +62,6 @@ export const testVolume = async (scaffoldVuer, texture_prefix) => {
62
62
  0,
63
63
  1
64
64
  );
65
- //console.log(zincObject.morph.matrix)
66
65
  window.texture = zincObject;
67
66
  };
68
67
 
@@ -115,9 +114,9 @@ export const testSlides = async (scaffoldVuer, texture_prefix) => {
115
114
  //textureSlides.morph.matrix.set(-100, 0, 0, 0, 0, -100, 0, 0, 0, 0, -100, 0, -60, -100, 30, 1);
116
115
  //textureSlides.morph.matrix.set( -100, 0, 0, -60, 0, -100, 0, -100, 0, 0, -100, 30, 0, 0, 0, 1 );
117
116
 
118
- const n = textureSlides.morph.matrix.clone();
117
+ const n = textureSlides.getMorph().matrix.clone();
119
118
  n.set(-100, 0, 0, -10, 0, -200, 0, 0, 0, 0, -100, 0, 0, 0, 10, 1);
120
- textureSlides.morph.applyMatrix4(n);
119
+ textureSlides.getMorph().applyMatrix4(n);
121
120
  scaffoldVuer.addZincObject(textureSlides);
122
121
  scaffoldVuer.fitWindow();
123
122
  //window.texture = textureSlides;
@@ -187,14 +186,11 @@ const applyTransformation = (scaffoldVuer, mesh, rotation, position, scale, refe
187
186
  0,
188
187
  0
189
188
  );
190
- console.log(matrix)
191
189
  const quaternion = new THREE.Quaternion().setFromRotationMatrix(matrix);
192
- console.log(quaternion);
193
190
  mesh.position.set(...position);
194
191
  mesh.quaternion.copy( quaternion );
195
192
  mesh.scale.set(...scale);
196
193
  mesh.updateMatrix();
197
- console.log(rotation)
198
194
  }
199
195
 
200
196
 
@@ -220,13 +216,13 @@ export const testArmSlides = async (scaffoldVuer) => {
220
216
  ]);
221
217
 
222
218
  const rotation = [
223
- Math.cos(Math.PI / 2.0), 0, Math.sin(Math.PI / 2.0),
219
+ 0, 0, 1,
224
220
  0, 1, 0,
225
- -Math.sin(Math.PI / 2.0), 0, Math.cos(Math.PI / 2.0)
221
+ -1, 0, 0
226
222
  ];
227
223
  const position = [0, -1.0, 0.95];
228
224
  const scale = [1.6, 1.6, 1.2];
229
- const reference = "centre";
225
+ const reference = "corner";
230
226
  applyTransformation(scaffoldVuer, textureSlides.morph, rotation, position, scale, reference);
231
227
  scaffoldVuer.addZincObject(textureSlides);
232
228
  scaffoldVuer.fitWindow();
@@ -66,8 +66,11 @@ export default {
66
66
  } else {
67
67
  this.isTextureSlides = false;
68
68
  }
69
- if (object && object.morph) this.material = ref(object.morph.material);
70
- else this.material = undefined;
69
+ if (object && object.getMorph()) {
70
+ this.material = ref(object.getMorph().material);
71
+ } else {
72
+ this.material = undefined;
73
+ }
71
74
  }
72
75
  }
73
76
  };
@@ -30,6 +30,8 @@
30
30
  import { ElPopover as Popover } from "element-plus";
31
31
  import { Tooltip } from "@abi-software/flatmapvuer";
32
32
  import "@abi-software/flatmapvuer/dist/style.css";
33
+ import { mapState } from 'pinia';
34
+ import { useMainStore } from "@/store/index";
33
35
 
34
36
  /**
35
37
  * A component to control the opacity of the target object.
@@ -67,6 +69,11 @@ export default {
67
69
  },
68
70
  },
69
71
  inject: ['scaffoldUrl'],
72
+ provide() {
73
+ return {
74
+ userApiKey: this.userToken,
75
+ };
76
+ },
70
77
  data: function () {
71
78
  return {
72
79
  display: false,
@@ -74,6 +81,7 @@ export default {
74
81
  };
75
82
  },
76
83
  computed: {
84
+ ...mapState(useMainStore, ['userToken']),
77
85
  position: function () {
78
86
  let yOffset = 40;
79
87
  if (this.region) {
@@ -92,6 +100,7 @@ export default {
92
100
  this.annotationEntry = {
93
101
  "featureId": encodeURIComponent(region + this.label),
94
102
  "resourceId": encodeURIComponent(this.scaffoldUrl),
103
+ "resource": encodeURIComponent(this.scaffoldUrl),
95
104
  };
96
105
  }
97
106
  }
@@ -2076,6 +2076,7 @@ export default {
2076
2076
  left: 53px !important;
2077
2077
  }
2078
2078
  }
2079
+
2079
2080
  .scaffold-select-box {
2080
2081
  border-radius: 4px;
2081
2082
  border: 1px solid rgb(144, 147, 153);
package/src/main.js CHANGED
@@ -1,17 +1,29 @@
1
1
  import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
2
3
  import * as VueRouter from 'vue-router'
3
4
  import App from './App.vue'
5
+ import { useMainStore } from '@/store/index'
4
6
 
5
7
  const routes = [
6
8
  { path: '/'},
7
9
  ]
8
10
 
11
+ const app = createApp(App)
12
+
9
13
  const router = VueRouter.createRouter({
10
14
  // 4. Provide the history implementation to use. We are using the hash history for simplicity here.
11
15
  history: VueRouter.createWebHashHistory(),
12
16
  routes,
13
17
  })
14
-
15
- const app = createApp(App)
16
18
  app.use(router)
19
+ const pinia = createPinia()
20
+
21
+ app.use(pinia)
22
+
23
+ const mainStore = useMainStore()
24
+ const token = document.cookie.split("; ").find((row) => row.startsWith("user-token"))
25
+ if (mainStore && token) {
26
+ mainStore.setUserToken(token.split("=")[1])
27
+ }
28
+
17
29
  app.mount('#app')
@@ -1,4 +1,27 @@
1
1
  import { THREE } from 'zincjs';
2
+
3
+ const setEmissiveColour = (fullList, colour, setDepthFunc) => {
4
+ for (let i = 0; i < fullList.length; i++) {
5
+ if (fullList[i] && fullList[i].material && fullList[i].material.emissive) {
6
+ let object = fullList[i].userData;
7
+ if (object && object.isZincObject) {
8
+ object.setEmissiveRGB(colour);
9
+ } else if (fullList[i].material && fullList[i].material.emissive) {
10
+ fullList[i].material.emissive.setRGB(...colour);
11
+ }
12
+ if (setDepthFunc && fullList[i].material.depthFunc) {
13
+ fullList[i].material.depthFunc = THREE.LessEqualDepth;
14
+ }
15
+ fullList[i].children.forEach(child => {
16
+ const object = child.userData;
17
+ if (object && object.isZincObject && child.material && child.material.emissive) {
18
+ child.material.emissive.setRGB(...colour);
19
+ }
20
+ });
21
+ }
22
+ }
23
+ }
24
+
2
25
  /**
3
26
  * This module manages highlighted and selected objects in 3D modules.
4
27
  *
@@ -57,17 +80,50 @@ const GraphicsHighlight = function() {
57
80
  }
58
81
  return _temp1;
59
82
  }
60
-
83
+
84
+
85
+ /*
86
+ * Not sure why the following block does not work
87
+ *
61
88
  this.setHighlighted = function(objects) {
62
89
  const previousHighlightedObjects = [...currentHighlightedObjects];
63
- _this.resetHighlighted();
64
90
  // Selected object cannot be highlighted
65
91
  const array = getUnmatchingObjects(objects, currentSelectedObjects);
66
92
  const fullList = getFullListOfObjects(array);
67
- for (let i = 0; i < fullList.length; i++) {
68
- if (fullList[i] && fullList[i].material && fullList[i].material.emissive)
69
- fullList[i].material.emissive.setRGB(..._this.highlightColour);
93
+ const different = isDifferent(array, previousHighlightedObjects);
94
+ console.log("highlight:", different)
95
+ if (different) {
96
+ _this.resetHighlighted();
97
+ setEmissiveColour(fullList, _this.highlightColour, false);
98
+ }
99
+ currentHighlightedObjects = array;
100
+ return different;
101
+ }
102
+
103
+ this.setSelected = function(objects) {
104
+ // first find highlighted object that are not selected
105
+ const previousHSelectedObjects = [...currentSelectedObjects];
106
+ const fullList = getFullListOfObjects(objects);
107
+ const different = isDifferent(objects, previousHSelectedObjects);
108
+ console.log("selected:", different)
109
+ if (different) {
110
+ _this.resetHighlighted();
111
+ _this.resetSelected();
112
+ setEmissiveColour(fullList, _this.selectColour, false);
70
113
  }
114
+ currentSelectedObjects = objects;
115
+ return different;
116
+ }
117
+ */
118
+
119
+
120
+ this.setHighlighted = function(objects) {
121
+ const previousHighlightedObjects = [...currentHighlightedObjects];
122
+ _this.resetHighlighted();
123
+ // Selected object cannot be highlighted
124
+ const array = getUnmatchingObjects(objects, currentSelectedObjects);
125
+ const fullList = getFullListOfObjects(array);
126
+ setEmissiveColour(fullList, _this.highlightColour, false);
71
127
  currentHighlightedObjects = array;
72
128
  return isDifferent(currentHighlightedObjects, previousHighlightedObjects);
73
129
  }
@@ -79,10 +135,7 @@ const GraphicsHighlight = function() {
79
135
  _this.resetHighlighted();
80
136
  _this.resetSelected();
81
137
  const fullList = getFullListOfObjects(objects);
82
- for (let i = 0; i < fullList.length; i++) {
83
- if (fullList[i] && fullList[i].material && fullList[i].material.emissive)
84
- fullList[i].material.emissive.setRGB(..._this.selectColour);
85
- }
138
+ setEmissiveColour(fullList, _this.selectColour, false);
86
139
  currentSelectedObjects = objects;
87
140
  return isDifferent(currentSelectedObjects, previousHSelectedObjects);
88
141
  }
@@ -98,27 +151,13 @@ const GraphicsHighlight = function() {
98
151
 
99
152
  this.resetHighlighted = function() {
100
153
  const fullList = getFullListOfObjects(currentHighlightedObjects);
101
- for (let i = 0; i < fullList.length; i++) {
102
- if (fullList[i] && fullList[i].material) {
103
- if (fullList[i].material.emissive)
104
- fullList[i].material.emissive.setRGB(..._this.originalColour);
105
- if (fullList[i].material.depthFunc)
106
- fullList[i].material.depthFunc = THREE.LessEqualDepth;
107
- }
108
- }
154
+ setEmissiveColour(fullList, _this.originalColour, true);
109
155
  currentHighlightedObjects = [];
110
156
  }
111
157
 
112
158
  this.resetSelected = function() {
113
159
  const fullList = getFullListOfObjects(currentSelectedObjects);
114
- for (let i = 0; i < fullList.length; i++) {
115
- if (fullList[i] && fullList[i].material) {
116
- if (fullList[i].material.emissive)
117
- fullList[i].material.emissive.setRGB(..._this.originalColour);
118
- if (fullList[i].material.depthFunc)
119
- fullList[i].material.depthFunc = THREE.LessEqualDepth;
120
- }
121
- }
160
+ setEmissiveColour(fullList, _this.originalColour, true);
122
161
  currentSelectedObjects = [];
123
162
  }
124
163
 
@@ -201,7 +201,7 @@ const OrgansSceneData = function() {
201
201
  if (intersected.object.userData &&
202
202
  intersected.object.userData.isMarker) {
203
203
  marker = true;
204
- intersectedObject = intersected.object.userData.parent.morph;
204
+ intersectedObject = intersected.object.userData.parent.getMorph();
205
205
  } else {
206
206
  intersectedObject = intersected.object;
207
207
  }
@@ -114,8 +114,8 @@ RendererModule.prototype.setHighlightedByZincObjects = function(
114
114
  let morphs = [];
115
115
  if (zincObjects) {
116
116
  zincObjects.forEach(zincObject => {
117
- if (zincObject && zincObject.morph)
118
- morphs.push(zincObject.morph);
117
+ if (zincObject && zincObject.getMorph())
118
+ morphs.push(zincObject.getMorph());
119
119
  });
120
120
  }
121
121
 
@@ -179,8 +179,12 @@ RendererModule.prototype.setSelectedByZincObjects = function(
179
179
  let morphs = [];
180
180
  if (zincObjects) {
181
181
  zincObjects.forEach(zincObject => {
182
- if (zincObject && zincObject.morph)
183
- morphs.push(zincObject.morph);
182
+ if (zincObject) {
183
+ const morph = zincObject.getMorph();
184
+ if (morph) {
185
+ morphs.push(morph);
186
+ }
187
+ }
184
188
  });
185
189
  }
186
190
 
@@ -194,17 +198,7 @@ const addGlyphToArray = function(objects) {
194
198
  }
195
199
 
196
200
  RendererModule.prototype.findObjectsByGroupName = function(groupName) {
197
- const geometries = this.scene.findGeometriesWithGroupName(groupName);
198
- const objects = [];
199
- for (let i = 0; i < geometries.length; i ++ ) {
200
- objects.push(geometries[i].morph);
201
- }
202
- const glyphsets = this.scene.findGlyphsetsWithGroupName(groupName);
203
- for (let i = 0; i < glyphsets.length; i ++ ) {
204
- glyphsets[i].forEachGlyph(addGlyphToArray(objects));
205
- }
206
-
207
- return objects;
201
+ return this.scene.findObjectsWithGroupName(groupName);
208
202
  }
209
203
 
210
204
  RendererModule.prototype.setHighlightedByGroupName = function(groupName, propagateChanges) {
@@ -0,0 +1,24 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ /**
4
+ * Activate the store when run the application individually.
5
+ * If the store exist in parent application,
6
+ * instead of creating a new store it will access the parent main store.
7
+ */
8
+ export const useMainStore = defineStore('main', {
9
+ state: () => ({
10
+ userProfile: {
11
+ token: ''
12
+ },
13
+ }),
14
+ getters: {
15
+ userToken(state) {
16
+ return state.userProfile.token
17
+ },
18
+ },
19
+ actions: {
20
+ setUserToken(value) {
21
+ this.userProfile.token = value
22
+ },
23
+ }
24
+ })
package/vite.config.js CHANGED
@@ -34,6 +34,11 @@ export default defineConfig(({ command, mode }) => {
34
34
  // https://github.com/antfu/unocss
35
35
  // see unocss.config.ts for config
36
36
  ],
37
+ resolve: {
38
+ alias: {
39
+ '@': path.resolve(__dirname, './src'),
40
+ }
41
+ },
37
42
  build: {
38
43
  lib: {
39
44
  entry: path.resolve(__dirname, "./src/components/index.js"),
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Vuese Generator
3
+ *
4
+ * To generate markdown files from Vue components
5
+ * To watch components changes for Vitepress on Dev Mode
6
+ */
7
+
8
+ import fs from 'fs'
9
+ import path from 'path'
10
+ import chokidar from 'chokidar'
11
+ import { parser } from '@vuese/parser'
12
+ import { Render } from '@vuese/markdown-render'
13
+
14
+ const watchMode = process.argv.find((argv) => argv === 'watch')
15
+
16
+ const componentsDir = 'src/components'
17
+ const components = ['ScaffoldVuer.vue']
18
+ const outputDir = 'docs/components'
19
+
20
+ function generateMarkdown(file) {
21
+ const fileWithPath = `${componentsDir}/${file}`
22
+ const fileContent = fs.readFileSync(fileWithPath, 'utf-8')
23
+
24
+ try {
25
+ const parserResult = parser(fileContent)
26
+ const r = new Render(parserResult)
27
+ const renderResult = r.render()
28
+ const markdownResult = r.renderMarkdown()
29
+ const markdownContent = markdownResult.content
30
+ const componentName = path.basename(fileWithPath, '.vue')
31
+
32
+ if (!fs.existsSync(outputDir)) {
33
+ fs.mkdirSync(outputDir)
34
+ }
35
+
36
+ fs.writeFile(`${outputDir}/${componentName}.md`, markdownContent, (err) => {
37
+ if (err) {
38
+ console.error(`Error writing markdown file for ${componentName}`, err)
39
+ } else {
40
+ console.log(`Markdown file for ${componentName} is generated!`)
41
+ }
42
+ })
43
+ } catch(e) {
44
+ console.error(e)
45
+ }
46
+ }
47
+
48
+ // To generate markdown files - one time
49
+ components.forEach((component) => {
50
+ console.log(`Write markdown file for ${component} on first load.`)
51
+ generateMarkdown(component)
52
+ })
53
+
54
+ // To watch component changes and generate markdown files
55
+ if (watchMode) {
56
+ const watcher = chokidar.watch(components, {
57
+ cwd: componentsDir,
58
+ ignoreInitial: true,
59
+ })
60
+
61
+ watcher.on('change', (file) => {
62
+ console.log(`The component ${file} has changed!`)
63
+ generateMarkdown(file)
64
+ })
65
+ }