@vc-shell/create-vc-app 2.0.0-alpha.9 → 2.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +102 -245
  2. package/README.md +19 -18
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.test.d.ts +2 -0
  5. package/dist/commands/init.test.d.ts.map +1 -0
  6. package/dist/engine/codegen.d.ts.map +1 -1
  7. package/dist/engine/helpers.d.ts +1 -1
  8. package/dist/engine/helpers.d.ts.map +1 -1
  9. package/dist/engine/helpers.test.d.ts +2 -0
  10. package/dist/engine/helpers.test.d.ts.map +1 -0
  11. package/dist/engine/template.d.ts.map +1 -1
  12. package/dist/engine/template.test.d.ts +2 -0
  13. package/dist/engine/template.test.d.ts.map +1 -0
  14. package/dist/index.js +172 -170
  15. package/dist/output.d.ts.map +1 -1
  16. package/dist/templates/dynamic-module/_package.json.ejs +6 -6
  17. package/dist/templates/dynamic-module/src/modules/index.ts.ejs +8 -5
  18. package/dist/templates/dynamic-module/tsconfig.json +1 -1
  19. package/dist/templates/dynamic-module/vite.config.mts.ejs +1 -1
  20. package/dist/templates/host-app/_package.json.ejs +14 -16
  21. package/dist/templates/host-app/src/main.ts.ejs +17 -15
  22. package/dist/templates/host-app/src/router/routes.ts.ejs +0 -9
  23. package/dist/templates/host-app/tsconfig.json +1 -0
  24. package/dist/templates/host-app/vite.config.mts.ejs +3 -6
  25. package/dist/templates/module/composables/useDetails.ts.ejs +41 -38
  26. package/dist/templates/module/index.ts.ejs +11 -8
  27. package/dist/templates/module/locales/en.json.ejs +33 -22
  28. package/dist/templates/module/pages/details.vue.ejs +83 -111
  29. package/dist/templates/module/pages/list.vue.ejs +88 -117
  30. package/dist/templates/sample-module/index.ts +11 -8
  31. package/dist/templates/sample-module/pages/details.vue +20 -47
  32. package/dist/templates/sample-module/pages/list.vue +107 -154
  33. package/dist/templates/standalone/_package.json.ejs +18 -20
  34. package/dist/templates/standalone/eslint.config.mjs +31 -0
  35. package/dist/templates/standalone/src/bootstrap.ts.ejs +5 -5
  36. package/dist/templates/standalone/src/main.ts.ejs +29 -23
  37. package/dist/templates/standalone/src/router/routes.ts.ejs +0 -9
  38. package/dist/templates/standalone/tsconfig.json +1 -0
  39. package/dist/types.d.ts +2 -2
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +4 -3
  42. package/dist/templates/host-app/src/shims-vue.d.ts +0 -27
  43. package/dist/templates/host-app/src/vue-i18n.d.ts +0 -10
  44. package/dist/templates/standalone/_eslintignore +0 -3
  45. package/dist/templates/standalone/_eslintrc.js +0 -41
  46. package/dist/templates/standalone/src/shims-vue.d.ts +0 -27
  47. package/dist/templates/standalone/src/vue-i18n.d.ts +0 -10
@@ -1,3 +1,3 @@
1
- import { getDynamicModuleConfiguration } from "@vc-shell/config-generator";
1
+ import { getDynamicModuleConfiguration } from "@vc-shell/mf-module";
2
2
 
3
3
  export default getDynamicModuleConfiguration();
@@ -14,27 +14,27 @@
14
14
  "generate-api-client": "cross-env api-client-generator --APP_PLATFORM_MODULES='[]' --APP_API_CLIENT_DIRECTORY=./src/api_client/ --APP_OUT_DIR=dist --APP_PACKAGE_NAME=api --APP_PACKAGE_VERSION=$npm_package_version"
15
15
  },
16
16
  "devDependencies": {
17
- "@commitlint/cli": "^18.4.3",
18
- "@commitlint/config-conventional": "^18.4.3",
17
+ "@commitlint/cli": "^20.4.1",
18
+ "@commitlint/config-conventional": "^20.4.1",
19
19
  "@laynezh/vite-plugin-lib-assets": "^0.5.13",
20
20
  "@rollup/plugin-typescript": "^11.1.5",
21
21
  "@types/lodash-es": "^4.17.12",
22
22
  "@types/node": "^20.10.5",
23
23
  "@typescript-eslint/eslint-plugin": "^7.4.0",
24
24
  "@typescript-eslint/parser": "^7.4.0",
25
- "@vc-shell/api-client-generator": "^2.0.0-alpha.9",
26
- "@vc-shell/ts-config": "^2.0.0-alpha.9",
25
+ "@vc-shell/api-client-generator": "^2.0.0-alpha.35",
26
+ "@vc-shell/ts-config": "^2.0.0-alpha.35",
27
27
  "@vitejs/plugin-vue": "^5.2.3",
28
- "@vue/eslint-config-prettier": "^9.0.0",
29
- "@vue/eslint-config-typescript": "^13.0.0",
28
+ "@vue/eslint-config-prettier": "^10.2.0",
29
+ "@vue/eslint-config-typescript": "^14.6.0",
30
30
  "autoprefixer": "^10.4.16",
31
31
  "conventional-changelog-cli": "^5.0.0",
32
32
  "cross-env": "^7.0.3",
33
- "eslint": "^8.57.0",
33
+ "eslint": "^9.35.0",
34
34
  "eslint-import-resolver-typescript": "^3.6.1",
35
35
  "eslint-plugin-import": "^2.29.1",
36
36
  "eslint-plugin-prettier": "^5.1.3",
37
- "eslint-plugin-vue": "^9.19.2",
37
+ "eslint-plugin-vue": "^10.4.0",
38
38
  "husky": "^8.0.3",
39
39
  "lint-staged": "^15.2.0",
40
40
  "lodash-es": "^4.17.21",
@@ -45,21 +45,19 @@
45
45
  "tsx": "^4.7.1",
46
46
  "typescript": "^5.8.3",
47
47
  "vite": "^6.3.3",
48
- "vite-plugin-checker": "^0.9.1",
48
+ "vite-plugin-checker": "^0.13.0",
49
49
  "vite-plugin-mkcert": "^1.17.1",
50
50
  "vue-eslint-parser": "^9.3.2",
51
- "vue-tsc": "^2.2.10"
51
+ "vue-tsc": "^3.2.5"
52
52
  },
53
53
  "dependencies": {
54
- "@vc-shell/config-generator": "^2.0.0-alpha.9",
55
- "@vc-shell/framework": "^2.0.0-alpha.9",
54
+ "@vc-shell/config-generator": "^2.0.0-alpha.35",
55
+ "@vc-shell/framework": "^2.0.0-alpha.35",
56
56
  "@vueuse/core": "^10.7.1",
57
57
  "@vueuse/integrations": "^10.7.1",
58
- "cross-spawn": "^7.0.3",
59
- "moment": "^2.30.1",
60
58
  "vee-validate": "^4.12.4",
61
- "vue": "^3.5.13",
62
- "vue-router": "^4.2.5"
59
+ "vue": "^3.5.30",
60
+ "vue-router": "^5.0.3"
63
61
  },
64
62
  "lint-staged": {
65
63
  "*.{js,ts,html,css}": "prettier --write '**/*.{ts,vue}'",
@@ -16,24 +16,26 @@ async function startApp() {
16
16
  console.log(e);
17
17
  }
18
18
 
19
- const app = createApp(RouterView)
20
- .use(VirtoShellFramework, {
21
- router,
22
- i18n: {
23
- locale: import.meta.env.APP_I18N_LOCALE,
24
- fallbackLocale: import.meta.env.APP_I18N_FALLBACK_LOCALE,
25
- },
19
+ const { currentLocale, setLocale } = useLanguages();
20
+
21
+ const app = createApp(RouterView);
22
+
23
+ app.use(VirtoShellFramework, {
24
+ router,
25
+ i18n: {
26
+ locale: import.meta.env.APP_I18N_LOCALE,
27
+ fallbackLocale: import.meta.env.APP_I18N_FALLBACK_LOCALE,
28
+ },
26
29
  <% if (aiAgent) { %>
27
- aiAgent: {
28
- config: {
29
- url: import.meta.env.APP_AI_AGENT_URL,
30
- },
30
+ aiAgent: {
31
+ config: {
32
+ url: import.meta.env.APP_AI_AGENT_URL,
31
33
  },
34
+ },
32
35
  <% } %>
33
- })
34
- .use(router);
36
+ });
35
37
 
36
- const { currentLocale, setLocale } = app.runWithContext(() => useLanguages());
38
+ app.use(router);
37
39
 
38
40
  bootstrap(app);
39
41
 
@@ -43,7 +45,7 @@ async function startApp() {
43
45
 
44
46
  setLocale(currentLocale.value);
45
47
 
46
- app.config.errorHandler = (err) => {
48
+ app.config.errorHandler = (err: unknown) => {
47
49
  notification.error((err as Error).toString(), {
48
50
  timeout: 5000,
49
51
  });
@@ -43,15 +43,6 @@ export const routes: RouteRecordRaw[] = [
43
43
  }),
44
44
  },
45
45
  ],
46
- <% if (tenantRoutes) { %>
47
- beforeEnter: (to) => {
48
- const { tenantId } = to.params;
49
- if (!tenantId || new RegExp(tenantIdRegex).test(tenantId as string)) {
50
- return true;
51
- }
52
- return { path: "/" };
53
- },
54
- <% } %>
55
46
  },
56
47
  {
57
48
  name: "Login",
@@ -6,6 +6,7 @@
6
6
  "rootDir": "src",
7
7
  "types": [
8
8
  "vite/client",
9
+ "@vc-shell/framework/globals"
9
10
  ]
10
11
  },
11
12
  "include": [
@@ -1,7 +1,4 @@
1
- import { getApplicationConfiguration, getHostFederationConfig } from "@vc-shell/config-generator";
2
- import { mergeConfig } from "vite";
1
+ import { getApplicationConfiguration } from "@vc-shell/config-generator";
2
+ import { mfHostConfig } from "@vc-shell/mf-host/vite";
3
3
 
4
- export default mergeConfig(
5
- getApplicationConfiguration(),
6
- getHostFederationConfig(),
7
- );
4
+ export default getApplicationConfiguration(mfHostConfig());
@@ -1,38 +1,41 @@
1
- import { ref } from "vue";
2
- import { useAsync, useLoading } from "@vc-shell/framework";
3
-
4
- export default function use<%- ModuleNamePascalCase %>Details() {
5
- const item = ref<Record<string, unknown>>({});
6
-
7
- const { loading: itemLoading, action: fetchItem } = useAsync(async (id?: string) => {
8
- // TODO: Replace with real API call
9
- // const result = await apiClient.getById(id);
10
- // item.value = result;
11
- });
12
-
13
- const { loading: saveLoading, action: saveAction } = useAsync(async () => {
14
- // TODO: Replace with real API call
15
- // if (item.value.id) {
16
- // await apiClient.update(item.value);
17
- // } else {
18
- // await apiClient.create(item.value);
19
- // }
20
- });
21
-
22
- const loading = useLoading(itemLoading, saveLoading);
23
-
24
- async function getItem(id: string) {
25
- await fetchItem(id);
26
- }
27
-
28
- async function saveItem() {
29
- await saveAction();
30
- }
31
-
32
- return {
33
- item,
34
- loading,
35
- getItem,
36
- saveItem,
37
- };
38
- }
1
+ import { ref } from "vue";
2
+ import { useAsync, useLoading, useModificationTracker } from "@vc-shell/framework";
3
+
4
+ export default function use<%- ModuleNamePascalCase %>Details() {
5
+ const item = ref<Record<string, any>>({});
6
+ const { isModified, resetModificationState } = useModificationTracker(item);
7
+
8
+ const { loading: itemLoading, action: fetchItem } = useAsync(async (id?: string) => {
9
+ // TODO: Replace with real API call
10
+ // const result = await apiClient.getById(id);
11
+ // item.value = result;
12
+ });
13
+
14
+ const { loading: saveLoading, action: saveAction } = useAsync(async () => {
15
+ // TODO: Replace with real API call
16
+ // if (item.value.id) {
17
+ // await apiClient.update(item.value);
18
+ // } else {
19
+ // await apiClient.create(item.value);
20
+ // }
21
+ });
22
+
23
+ const loading = useLoading(itemLoading, saveLoading);
24
+
25
+ async function getItem(id: string) {
26
+ await fetchItem(id);
27
+ }
28
+
29
+ async function saveItem() {
30
+ await saveAction();
31
+ }
32
+
33
+ return {
34
+ item,
35
+ loading,
36
+ getItem,
37
+ saveItem,
38
+ isModified,
39
+ resetModificationState,
40
+ };
41
+ }
@@ -1,8 +1,11 @@
1
- import * as pages from "./pages";
2
- import * as locales from "./locales";
3
- import { createAppModule } from "@vc-shell/framework";
4
-
5
- export default createAppModule(pages, locales);
6
-
7
- export * from "./pages";
8
- export * from "./composables";
1
+ import * as blades from "./pages";
2
+ import * as locales from "./locales";
3
+ import { defineAppModule } from "@vc-shell/framework";
4
+
5
+ export default defineAppModule({
6
+ blades,
7
+ locales,
8
+ });
9
+
10
+ export * from "./pages";
11
+ export * from "./composables";
@@ -1,22 +1,33 @@
1
- {
2
- "<%- ModuleNameScreamingSnake %>": {
3
- "MENU": {
4
- "TITLE": "<%- ModuleNameSentenceCase %>"
5
- },
6
- "PAGES": {
7
- "LIST": {
8
- "TITLE": "<%- ModuleNameSentenceCase %>",
9
- "TOOLBAR": {
10
- "REFRESH": "Refresh",
11
- "ADD": "Add"
12
- }
13
- },
14
- "DETAILS": {
15
- "TITLE": "<%- ModuleNameSentenceCase %> Details"
16
- },
17
- "ALERTS": {
18
- "CLOSE_CONFIRMATION": "You have unsaved changes. Close anyway?"
19
- }
20
- }
21
- }
22
- }
1
+ {
2
+ "<%- ModuleNameScreamingSnake %>": {
3
+ "MENU": {
4
+ "TITLE": "<%- ModuleNameSentenceCase %>"
5
+ },
6
+ "PAGES": {
7
+ "LIST": {
8
+ "TITLE": "<%- ModuleNameSentenceCase %>",
9
+ "COLUMNS": {
10
+ "NAME": "Name",
11
+ "CREATED_DATE": "Created"
12
+ },
13
+ "TOOLBAR": {
14
+ "REFRESH": "Refresh",
15
+ "ADD": "Add"
16
+ }
17
+ },
18
+ "DETAILS": {
19
+ "TITLE": "<%- ModuleNameSentenceCase %> Details",
20
+ "TITLE_NEW": "New <%- ModuleNameSentenceCase %>",
21
+ "FIELDS": {
22
+ "NAME": "Name"
23
+ },
24
+ "TOOLBAR": {
25
+ "SAVE": "Save"
26
+ }
27
+ }
28
+ },
29
+ "ALERTS": {
30
+ "CLOSE_CONFIRMATION": "You have unsaved changes. Are you sure you want to close?"
31
+ }
32
+ }
33
+ }
@@ -1,111 +1,83 @@
1
- <template>
2
- <VcBlade
3
- :title="title"
4
- :toolbar-items="bladeToolbar"
5
- :loading="loading"
6
- :expanded="expanded"
7
- :closable="closable"
8
- width="70%"
9
- @close="$emit('close:blade')"
10
- @expand="$emit('expand:blade')"
11
- @collapse="$emit('collapse:blade')"
12
- >
13
- <VcContainer>
14
- <VcForm>
15
- <!-- Add your form fields here -->
16
- <VcInput
17
- v-model="item.name"
18
- :label="'Name'"
19
- required
20
- />
21
- </VcForm>
22
- </VcContainer>
23
- </VcBlade>
24
- </template>
25
-
26
- <script setup lang="ts">
27
- import {
28
- VcBlade,
29
- VcContainer,
30
- VcForm,
31
- VcInput,
32
- useBladeNavigation,
33
- useModificationTracker,
34
- usePopup,
35
- useBeforeUnload,
36
- type IBladeToolbar,
37
- type IParentCallArgs,
38
- } from "@vc-shell/framework";
39
- import { ref, computed, onMounted } from "vue";
40
- import use<%- ModuleNamePascalCase %>Details from "../composables/useDetails";
41
-
42
- export interface Props {
43
- expanded?: boolean;
44
- closable?: boolean;
45
- param?: string;
46
- }
47
-
48
- export interface Emits {
49
- (event: "parent:call", args: IParentCallArgs): void;
50
- (event: "collapse:blade"): void;
51
- (event: "expand:blade"): void;
52
- (event: "close:blade"): void;
53
- }
54
-
55
- defineOptions({
56
- url: "/<%- ModuleName %>-details",
57
- name: "<%- ModuleNamePascalCase %>Details",
58
- });
59
-
60
- const props = withDefaults(defineProps<Props>(), {
61
- expanded: true,
62
- closable: true,
63
- param: undefined,
64
- });
65
-
66
- const emit = defineEmits<Emits>();
67
-
68
- const { onBeforeClose } = useBladeNavigation();
69
- const { showConfirmation } = usePopup();
70
-
71
- const { item, loading, getItem, saveItem } = use<%- ModuleNamePascalCase %>Details();
72
- const { isModified, resetModificationState } = useModificationTracker(item);
73
-
74
- const title = computed(() => {
75
- return props.param
76
- ? String(item.value?.name || "<%- ModuleNameSentenceCase %> Details")
77
- : "New <%- ModuleNameSentenceCase %>";
78
- });
79
-
80
- const bladeToolbar = ref<IBladeToolbar[]>([
81
- {
82
- id: "save",
83
- title: "Save",
84
- icon: "lucide-save",
85
- disabled: computed(() => !isModified.value),
86
- async clickHandler() {
87
- await saveItem();
88
- resetModificationState();
89
- emit("parent:call", { method: "reload" });
90
- },
91
- },
92
- ]);
93
-
94
- onMounted(async () => {
95
- if (props.param) {
96
- await getItem(props.param);
97
- }
98
- });
99
-
100
- onBeforeClose(async () => {
101
- if (isModified.value) {
102
- return await showConfirmation("You have unsaved changes. Are you sure you want to close?");
103
- }
104
- });
105
-
106
- useBeforeUnload(computed(() => isModified.value));
107
-
108
- defineExpose({
109
- title,
110
- });
111
- </script>
1
+ <template>
2
+ <VcBlade
3
+ :title="title"
4
+ :toolbar-items="bladeToolbar"
5
+ :loading="loading"
6
+ width="70%"
7
+ >
8
+ <VcContainer>
9
+ <VcForm>
10
+ <!-- Add your form fields here -->
11
+ <VcInput
12
+ v-model="item.name"
13
+ :label="$t('<%- ModuleNameScreamingSnake %>.PAGES.DETAILS.FIELDS.NAME')"
14
+ required
15
+ />
16
+ </VcForm>
17
+ </VcContainer>
18
+ </VcBlade>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import {
23
+ VcBlade,
24
+ VcContainer,
25
+ VcForm,
26
+ VcInput,
27
+ useBlade,
28
+ useModificationTracker,
29
+ usePopup,
30
+ useBeforeUnload,
31
+ type IBladeToolbar,
32
+ } from "@vc-shell/framework";
33
+ import { ref, computed, onMounted } from "vue";
34
+ import use<%- ModuleNamePascalCase %>Details from "../composables/useDetails";
35
+ import { useI18n } from "vue-i18n";
36
+
37
+ defineBlade({
38
+ url: "/<%- ModuleName %>-details",
39
+ name: "<%- ModuleNamePascalCase %>Details",
40
+ });
41
+
42
+ const { t } = useI18n({ useScope: "global" });
43
+ const { param, closeSelf, callParent, onBeforeClose } = useBlade();
44
+
45
+ const { showConfirmation } = usePopup();
46
+
47
+ const { item, loading, getItem, saveItem, isModified, resetModificationState } = use<%- ModuleNamePascalCase %>Details();
48
+
49
+ const title = computed(() => {
50
+ return param.value
51
+ ? String(item.value?.name || t("<%- ModuleNameScreamingSnake %>.PAGES.DETAILS.TITLE"))
52
+ : t("<%- ModuleNameScreamingSnake %>.PAGES.DETAILS.TITLE_NEW");
53
+ });
54
+
55
+ const bladeToolbar = ref<IBladeToolbar[]>([
56
+ {
57
+ id: "save",
58
+ title: t("<%- ModuleNameScreamingSnake %>.PAGES.DETAILS.TOOLBAR.SAVE"),
59
+ icon: "lucide-save",
60
+ disabled: computed(() => !isModified.value),
61
+ async clickHandler() {
62
+ await saveItem();
63
+ resetModificationState();
64
+ callParent("reload");
65
+ },
66
+ },
67
+ ]);
68
+
69
+ onMounted(async () => {
70
+ if (param.value) {
71
+ await getItem(param.value);
72
+ }
73
+ });
74
+
75
+ onBeforeClose(async () => {
76
+ if (isModified.value) {
77
+ return !(await showConfirmation(t("<%- ModuleNameScreamingSnake %>.ALERTS.CLOSE_CONFIRMATION")));
78
+ }
79
+ return false;
80
+ });
81
+
82
+ useBeforeUnload(computed(() => isModified.value));
83
+ </script>