create-vitrify 0.3.5 → 0.4.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/dist/cli.js +15 -10
  2. package/dist/templates.js +127 -12
  3. package/dist/types/templates.d.ts +21 -15
  4. package/package.json +3 -1
  5. package/templates/quasar/.vscode/extensions.json +1 -1
  6. package/templates/quasar/_eslintignore +2 -0
  7. package/templates/quasar/_eslintrc.cjs +19 -0
  8. package/templates/quasar/_prettierignore +3 -0
  9. package/templates/quasar/_prettierrc.json +22 -0
  10. package/templates/quasar/index.html +3 -7
  11. package/templates/quasar/src/App.vue +16 -5
  12. package/templates/quasar/src/components/HelloWorld.vue +6 -1
  13. package/templates/quasar/src/layouts/MainLayout.vue +4 -8
  14. package/templates/quasar/src/pages/{Error404.vue → Error404Page.vue} +7 -3
  15. package/templates/quasar/src/pages/{Index.vue → IndexPage.vue} +6 -0
  16. package/templates/quasar/src/router/routes.ts +2 -2
  17. package/templates/quasar/src/setup.ts +8 -0
  18. package/templates/quasar/src/shims-vue.d.ts +6 -0
  19. package/templates/quasar/vitrify.config.ts +36 -0
  20. package/templates/quasar-monorepo/packages/quasar/package.json.hbs +2 -1
  21. package/templates/quasar-monorepo/packages/quasar-plugin/package.json.hbs +1 -1
  22. package/templates/quasar-plugin/package.json.hbs +1 -1
  23. package/templates/vite-ui-plugin/.vscode/extensions.json +3 -0
  24. package/templates/vite-ui-plugin/_eslintignore +2 -0
  25. package/templates/vite-ui-plugin/_eslintrc.cjs +19 -0
  26. package/templates/vite-ui-plugin/_gitignore +3 -0
  27. package/templates/vite-ui-plugin/_prettierignore +3 -0
  28. package/templates/vite-ui-plugin/_prettierrc.json +22 -0
  29. package/templates/vite-ui-plugin/src/shims-vue.d.ts +6 -0
  30. package/templates/vite-ui-plugin/src/ui/components/HelloWorld.vue +20 -0
  31. package/templates/vite-ui-plugin/src/ui/icon-set/index.ts +40 -0
  32. package/templates/vite-ui-plugin/src/ui/icon-set/material-icons.ts +8 -0
  33. package/templates/vite-ui-plugin/src/ui/index.ts +9 -0
  34. package/templates/vite-ui-plugin/src/ui/lang/en-US.ts +8 -0
  35. package/templates/vite-ui-plugin/src/ui/lang/index.ts +42 -0
  36. package/templates/vite-ui-plugin/src/ui/utils/helpers.ts +1 -0
  37. package/templates/vite-ui-plugin/src/ui/vue-plugin.ts +15 -0
  38. package/templates/vite-ui-plugin/src/vite-plugin.ts +53 -0
  39. package/templates/vite-ui-plugin/tsconfig.build.plugin.json +7 -0
  40. package/templates/vite-ui-plugin/tsconfig.node.json +11 -0
  41. package/templates/vite-ui-plugin/tsconfig.types.json +17 -0
  42. package/templates/vite-ui-plugin/vite.config.ts +41 -0
  43. package/dist/index.js +0 -83
  44. package/dist/types/index.d.ts +0 -16
  45. package/templates/quasar/package.json.hbs +0 -28
  46. package/templates/quasar/tsconfig.json +0 -15
  47. package/templates/quasar/vitrify.config.js +0 -23
package/dist/cli.js CHANGED
@@ -1,17 +1,14 @@
1
- import { renderTemplate } from './index.js';
1
+ import { renderDirectory, renderPackageJson, renderTsconfigJson } from '@vitrify/tools/render';
2
2
  import parseArgs from 'minimist';
3
3
  import inquirer from 'inquirer';
4
+ import { promises } from 'fs';
4
5
  import { templates } from './templates.js';
5
6
  const escape = (val) => JSON.stringify(val).slice(1, -1);
6
- // const templates = (await promises.readdir(new URL('../templates/', import.meta.url), { withFileTypes: true }))
7
- // .filter((file) => file.isDirectory())
8
- // .map((file) => file.name)
9
7
  const argv = parseArgs(process.argv.slice(2), {
10
8
  string: ['template']
11
9
  });
12
10
  let questions = [];
13
11
  if (!argv.template) {
14
- // throw new Error('Please provide a template argument: --template')
15
12
  questions = [
16
13
  ...questions,
17
14
  {
@@ -64,11 +61,19 @@ questions = [
64
61
  const answers = await inquirer.prompt(questions);
65
62
  const cwdUrl = new URL('', `file://${process.cwd()}/`);
66
63
  const templateVariables = answers;
67
- const templateUrl =
68
64
  // @ts-ignore
69
- templates[answers.template].url || templates[argv.template].url;
70
- renderTemplate({
71
- templateUrl,
65
+ const template = templates[answers.template] || templates[argv.template];
66
+ const directoryUrl = template.url;
67
+ const outputDir = new URL(`./${answers.name}/`, cwdUrl);
68
+ await renderDirectory({
69
+ directoryUrl,
72
70
  templateVariables,
73
- outputDir: new URL(`./${answers.name}/`, cwdUrl)
71
+ outputDir
74
72
  });
73
+ promises.writeFile(new URL('./package.json', outputDir), renderPackageJson({
74
+ ...templateVariables,
75
+ version: '0.1.0',
76
+ license: 'UNLICENSED',
77
+ ...template.pkgJson
78
+ }));
79
+ promises.writeFile(new URL('./tsconfig.json', outputDir), renderTsconfigJson(template.tsconfigJson));
package/dist/templates.js CHANGED
@@ -1,20 +1,135 @@
1
+ import latestVersion from 'latest-version';
2
+ const getLatestVersions = async (dependencies) => {
3
+ console.log('Fetching latest package versions...');
4
+ const deps = {};
5
+ for (const dep of dependencies) {
6
+ deps[dep] = await latestVersion(dep);
7
+ }
8
+ return deps;
9
+ };
1
10
  export const templates = {
2
11
  quasar: {
3
12
  name: 'quasar',
4
13
  fullName: 'Quasar Project',
5
14
  description: 'Quasar Framework project',
6
- url: new URL('../templates/quasar/', import.meta.url)
7
- },
8
- plugin: {
9
- name: 'quasar-plugin',
10
- fullName: 'Quasar Plugin',
11
- description: 'Quasar Framework plugin',
12
- url: new URL('../templates/quasar-plugin/', import.meta.url)
15
+ url: new URL('../templates/quasar/', import.meta.url),
16
+ pkgJson: {
17
+ scripts: {
18
+ dev: 'vitrify dev',
19
+ 'dev:ssr': 'vitrify dev -m ssr',
20
+ build: 'vitrify build',
21
+ 'build:ssr': 'vitrify build -m ssr',
22
+ 'build:ssg': 'vitrify build -m ssg',
23
+ test: 'vitrify test',
24
+ lint: 'eslint --ext .vue --ext .ts src',
25
+ 'lint:fix': 'eslint --ext .vue --ext .ts src --fix',
26
+ 'format:check': 'prettier --check .',
27
+ 'format:write': 'prettier --write .'
28
+ },
29
+ dependencies: await getLatestVersions([
30
+ '@fastify/middie',
31
+ '@fastify/static',
32
+ '@quasar/extras',
33
+ 'quasar',
34
+ 'vue',
35
+ 'vue-router'
36
+ ]),
37
+ devDependencies: await getLatestVersions([
38
+ '@vitejs/plugin-vue',
39
+ '@typescript-eslint/eslint-plugin',
40
+ '@typescript-eslint/parser',
41
+ 'eslint',
42
+ 'eslint-config-prettier',
43
+ 'eslint-plugin-prettier-vue',
44
+ 'eslint-plugin-vue',
45
+ 'devcert',
46
+ 'fastify',
47
+ 'typescript',
48
+ 'vite',
49
+ 'vitrify'
50
+ ])
51
+ },
52
+ tsconfigJson: {
53
+ paths: {
54
+ src: ['./src']
55
+ },
56
+ types: ['vite/client', 'vitrify/client'],
57
+ include: [
58
+ 'vitrify.config.ts',
59
+ 'src/**/*.ts',
60
+ 'src/**/*.d.ts',
61
+ 'src/**/*.tsx',
62
+ 'src/**/*.vue'
63
+ ]
64
+ }
13
65
  },
14
- quasarMonorepo: {
15
- name: 'quasar-monorepo',
16
- fullName: 'Quasar monorepo (project + plugin)',
17
- description: 'Quasar Framework monorepo',
18
- url: new URL('../templates/quasar-monorepo/', import.meta.url)
66
+ uiPlugin: {
67
+ name: 'vite-ui-plugin',
68
+ fullName: 'Vite UI plugin',
69
+ description: 'A Vite plugin for UI components',
70
+ url: new URL('../templates/vite-ui-plugin/', import.meta.url),
71
+ pkgJson: {
72
+ exports: {
73
+ '.': {
74
+ types: './dist/types/index.d.ts',
75
+ import: './dist/index.js',
76
+ src: './src/ui/index.ts'
77
+ },
78
+ './vite-plugin': {
79
+ types: './dist/vite-plugin.d.ts',
80
+ import: './dist/vite-plugin.js',
81
+ src: './src/vite-plugin.ts'
82
+ }
83
+ },
84
+ scripts: {
85
+ 'build:plugin': 'vite build',
86
+ 'build:vite-plugin': 'tsc -p tsconfig.build.plugin.json',
87
+ 'generate:types': 'vue-tsc -p tsconfig.types.json',
88
+ 'clean:buildinfo': 'rimraf tsconfig.build.plugin.tsbuildinfo',
89
+ clean: 'run-s clean:buildinfo',
90
+ build: 'run-s clean build:plugin build:vite-plugin generate:types',
91
+ lint: 'eslint --ext .vue --ext .ts src',
92
+ 'lint:fix': 'eslint --ext .vue --ext .ts src --fix',
93
+ 'format:check': 'prettier --check .',
94
+ 'format:write': 'prettier --write .'
95
+ },
96
+ dependencies: await getLatestVersions(['unplugin-vue-components']),
97
+ devDependencies: await getLatestVersions([
98
+ '@types/node',
99
+ '@types/ws',
100
+ '@vitejs/plugin-vue',
101
+ '@vue/server-renderer',
102
+ '@typescript-eslint/eslint-plugin',
103
+ '@typescript-eslint/parser',
104
+ 'eslint',
105
+ 'eslint-config-prettier',
106
+ 'eslint-plugin-prettier-vue',
107
+ 'eslint-plugin-vue',
108
+ 'npm-run-all',
109
+ 'quasar',
110
+ 'typescript',
111
+ 'rimraf',
112
+ 'vite',
113
+ 'vitrify',
114
+ 'vue',
115
+ 'vue-router',
116
+ 'vue-tsc'
117
+ ])
118
+ },
119
+ tsconfigJson: {
120
+ types: ['vite/client']
121
+ }
19
122
  }
123
+ // plugin: {
124
+ // name: 'quasar-plugin',
125
+ // fullName: 'Quasar Plugin',
126
+ // description: 'Quasar Framework plugin',
127
+ // url: new URL('../templates/quasar-plugin/', import.meta.url)
128
+ // },
129
+ // quasarMonorepo: {
130
+ // name: 'quasar-monorepo',
131
+ // fullName: 'Quasar monorepo (project + plugin)',
132
+ // description: 'Quasar Framework monorepo',
133
+ // url: new URL('../templates/quasar-monorepo/', import.meta.url)
134
+ // }
20
135
  };
@@ -1,20 +1,26 @@
1
- export declare const templates: {
2
- quasar: {
1
+ interface Templates {
2
+ [key: string]: {
3
3
  name: string;
4
4
  fullName: string;
5
5
  description: string;
6
6
  url: URL;
7
+ pkgJson: {
8
+ scripts: Record<string, string>;
9
+ exports?: Record<string, {
10
+ types?: string;
11
+ import: string;
12
+ src?: string;
13
+ }>;
14
+ dependencies?: Record<string, string>;
15
+ devDependencies?: Record<string, string>;
16
+ peerDependencies?: Record<string, string>;
17
+ };
18
+ tsconfigJson: {
19
+ paths?: Record<string, string[]>;
20
+ types?: string[];
21
+ include?: string[];
22
+ };
7
23
  };
8
- plugin: {
9
- name: string;
10
- fullName: string;
11
- description: string;
12
- url: URL;
13
- };
14
- quasarMonorepo: {
15
- name: string;
16
- fullName: string;
17
- description: string;
18
- url: URL;
19
- };
20
- };
24
+ }
25
+ export declare const templates: Templates;
26
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vitrify",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "license": "MIT",
5
5
  "author": "Stefan van Herwijnen",
6
6
  "type": "module",
@@ -27,12 +27,14 @@
27
27
  "dependencies": {
28
28
  "handlebars": "^4.7.7",
29
29
  "inquirer": "^8.2.2",
30
+ "latest-version": "^7.0.0",
30
31
  "minimist": "^1.2.6"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/inquirer": "^8.2.1",
34
35
  "@types/minimist": "^1.2.2",
35
36
  "@types/node": "^17.0.23",
37
+ "@vitrify/tools": "^0.1.0",
36
38
  "typescript": "^4.7.3",
37
39
  "vite": "^3.0.0-beta.0",
38
40
  "vue": "^3.2.37"
@@ -1,3 +1,3 @@
1
1
  {
2
- "recommendations": ["johnsoncodehk.volar"]
2
+ "recommendations": ["vue.volar", "dbaeumer.vscode-eslint"]
3
3
  }
@@ -0,0 +1,2 @@
1
+ .eslintrc.cjs
2
+ node_modules/
@@ -0,0 +1,19 @@
1
+ module.exports = {
2
+ ignorePatterns: ['.eslintrc.cjs'],
3
+ extends: [
4
+ 'eslint:recommended',
5
+ 'plugin:@typescript-eslint/recommended',
6
+ 'plugin:vue/vue3-recommended',
7
+ 'plugin:prettier-vue/recommended'
8
+ ],
9
+ parser: 'vue-eslint-parser',
10
+ parserOptions: {
11
+ parser: '@typescript-eslint/parser',
12
+ sourceType: 'module'
13
+ },
14
+ rules: {
15
+ '@typescript-eslint/ban-ts-comment': 0
16
+ },
17
+ plugins: ['@typescript-eslint'],
18
+ root: true
19
+ }
@@ -0,0 +1,3 @@
1
+ dist/
2
+ node_modules/
3
+ pnpm-lock.yaml
@@ -0,0 +1,22 @@
1
+ {
2
+ "semi": false,
3
+ "tabWidth": 2,
4
+ "singleQuote": true,
5
+ "printWidth": 80,
6
+ "trailingComma": "none",
7
+ "overrides": [
8
+ {
9
+ "files": ["*.json5"],
10
+ "options": {
11
+ "singleQuote": false,
12
+ "quoteProps": "preserve"
13
+ }
14
+ },
15
+ {
16
+ "files": ["*.yml"],
17
+ "options": {
18
+ "singleQuote": false
19
+ }
20
+ }
21
+ ]
22
+ }
@@ -3,15 +3,11 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title><!--product-name--></title>
7
- <!--preload-links-->
6
+ <title></title>
8
7
  </head>
9
8
 
10
9
  <body>
11
- <!-- Do not add whitespace or newlines to #app, this will cause hydration errors -->
12
- <div id="app"><!--app-html--></div>
13
- <!--dev-ssr-css-->
14
- <!--entry-script-->
15
- <!--initial-state-->
10
+ <!-- A body opening and closing tag is sufficient for Vitrify -->
11
+ <div id="app"></div>
16
12
  </body>
17
13
  </html>
@@ -1,9 +1,20 @@
1
1
  <template>
2
- <router-view></router-view>
2
+ <router-view v-slot="{ Component }">
3
+ <Suspense>
4
+ <template #default>
5
+ <component :is="Component" />
6
+ </template>
7
+ <template #fallback>
8
+ <div>Loading...</div>
9
+ </template>
10
+ </Suspense>
11
+ </router-view>
3
12
  </template>
4
13
 
5
- <script setup lang="ts"></script>
14
+ <script lang="ts">
15
+ export default {
16
+ name: 'App'
17
+ }
18
+ </script>
6
19
 
7
- <style lang="sass">
8
- // do not remove, required for additionalData import
9
- </style>
20
+ <script setup lang="ts"></script>
@@ -10,7 +10,12 @@
10
10
  </q-card>
11
11
  </template>
12
12
 
13
+ <script lang="ts">
14
+ export default {
15
+ name: 'HelloWorldComponent'
16
+ }
17
+ </script>
18
+
13
19
  <script lang="ts" setup>
14
20
  import logo from 'src/assets/quasar-logo-vertical.svg'
15
- const name = 'HelloWorld'
16
21
  </script>
@@ -2,14 +2,9 @@
2
2
  <q-layout view="lHh Lpr lFf">
3
3
  <q-header elevated>
4
4
  <q-toolbar>
5
- <q-btn
6
- flat
7
- dense
8
- round
9
- icon="menu"
10
- aria-label="Menu"
11
- @click="toggleLeftDrawer"
12
- />
5
+ <q-btn flat dense round aria-label="Menu" @click="toggleLeftDrawer">
6
+ <q-icon :name="matMenu" />
7
+ </q-btn>
13
8
 
14
9
  <q-toolbar-title> Quasar App </q-toolbar-title>
15
10
 
@@ -32,6 +27,7 @@
32
27
  <script setup lang="ts">
33
28
  import { ref } from 'vue'
34
29
  import { useQuasar } from 'quasar'
30
+ import { matMenu } from '@quasar/extras/material-icons'
35
31
 
36
32
  const $q = useQuasar()
37
33
  const leftDrawerOpen = ref(false)
@@ -20,6 +20,10 @@
20
20
  </div>
21
21
  </template>
22
22
 
23
- <script setup lang="ts">
24
- const name = 'Error404'
25
- </script>
23
+ <scirpt lang="ts">
24
+ export default {
25
+ name: 'Error404Page'
26
+ }
27
+ </scirpt>
28
+
29
+ <script setup lang="ts"></script>
@@ -4,6 +4,12 @@
4
4
  </q-page>
5
5
  </template>
6
6
 
7
+ <scirpt lang="ts">
8
+ export default {
9
+ name: 'IndexPage'
10
+ }
11
+ </scirpt>
12
+
7
13
  <script setup lang="ts">
8
14
  import HelloWorld from 'src/components/HelloWorld.vue'
9
15
  </script>
@@ -4,14 +4,14 @@ const routes: RouteRecordRaw[] = [
4
4
  {
5
5
  path: '/',
6
6
  component: () => import('src/layouts/MainLayout.vue'),
7
- children: [{ path: '', component: () => import('src/pages/Index.vue') }]
7
+ children: [{ path: '', component: () => import('src/pages/IndexPage.vue') }]
8
8
  },
9
9
 
10
10
  // Always leave this as last one,
11
11
  // but you can also remove it
12
12
  {
13
13
  path: '/:catchAll(.*)*',
14
- component: () => import('src/pages/Error404.vue')
14
+ component: () => import('src/pages/Error404Page.vue')
15
15
  }
16
16
  ]
17
17
 
@@ -0,0 +1,8 @@
1
+ import type { FastifyInstance } from 'fastify'
2
+
3
+ /**
4
+ * Only used in SSR/SSG
5
+ */
6
+ export default async function (fastify: FastifyInstance) {
7
+ console.log('Running setup function....')
8
+ }
@@ -0,0 +1,6 @@
1
+ // Mocks all files ending in `.vue` showing them as plain Vue instances
2
+ declare module '*.vue' {
3
+ import type { ComponentOptions } from 'vue'
4
+ const component: ComponentOptions
5
+ export default component
6
+ }
@@ -0,0 +1,36 @@
1
+ import type { VitrifyConfig } from 'vitrify'
2
+ import { certificateFor } from 'devcert'
3
+
4
+ export default async function ({ mode, command }): Promise<VitrifyConfig> {
5
+ const config: VitrifyConfig = {
6
+ vitrify: {
7
+ hooks: {
8
+ onSetup: [new URL('src/setup.ts', import.meta.url)]
9
+ },
10
+ sass: {
11
+ variables: {
12
+ $primary: '#000000'
13
+ }
14
+ },
15
+ ssr: {
16
+ serverModules: []
17
+ }
18
+ },
19
+ quasar: {
20
+ // extras: ['material-icons'],
21
+ framework: {
22
+ components: [
23
+ // Deprecated
24
+ ],
25
+ iconSet: 'svg-material-icons',
26
+ plugins: ['Dialog', 'Notify']
27
+ }
28
+ }
29
+ }
30
+ if (mode === 'development') {
31
+ config.server = {
32
+ https: await certificateFor('vitrify.test')
33
+ }
34
+ }
35
+ return config
36
+ }
@@ -23,7 +23,8 @@
23
23
  },
24
24
  "devDependencies": {
25
25
  "@vue/server-renderer": "^3.2.37",
26
- "vitrify": "^0.5.0",
26
+ "critters": "^0.0.16",
27
+ "vitrify": "^0.6.0",
27
28
  "typescript": "^4.6.2"
28
29
  }
29
30
  }
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@vue/server-renderer": "^3.2.37",
39
- "vitrify": "^0.5.0",
39
+ "vitrify": "^0.6.0",
40
40
  "@types/node": "^16.11.11",
41
41
  "@types/ws": "^8.5.3",
42
42
  "@vitejs/plugin-vue": "^3.0.0-alpha.1",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@vue/server-renderer": "^3.2.37",
39
- "vitrify": "^0.5.0",
39
+ "vitrify": "^0.6.0",
40
40
  "@types/node": "^16.11.11",
41
41
  "@types/ws": "^8.5.3",
42
42
  "@vitejs/plugin-vue": "^3.0.0-alpha.1",
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["vue.volar", "dbaeumer.vscode-eslint"]
3
+ }
@@ -0,0 +1,2 @@
1
+ .eslintrc.cjs
2
+ node_modules/
@@ -0,0 +1,19 @@
1
+ module.exports = {
2
+ ignorePatterns: ['.eslintrc.cjs'],
3
+ extends: [
4
+ 'eslint:recommended',
5
+ 'plugin:@typescript-eslint/recommended',
6
+ 'plugin:vue/vue3-recommended',
7
+ 'plugin:prettier-vue/recommended'
8
+ ],
9
+ parser: 'vue-eslint-parser',
10
+ parserOptions: {
11
+ parser: '@typescript-eslint/parser',
12
+ sourceType: 'module'
13
+ },
14
+ rules: {
15
+ '@typescript-eslint/ban-ts-comment': 0
16
+ },
17
+ plugins: ['@typescript-eslint'],
18
+ root: true
19
+ }
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ dist
3
+ *.local
@@ -0,0 +1,3 @@
1
+ dist/
2
+ node_modules/
3
+ pnpm-lock.yaml
@@ -0,0 +1,22 @@
1
+ {
2
+ "semi": false,
3
+ "tabWidth": 2,
4
+ "singleQuote": true,
5
+ "printWidth": 80,
6
+ "trailingComma": "none",
7
+ "overrides": [
8
+ {
9
+ "files": ["*.json5"],
10
+ "options": {
11
+ "singleQuote": false,
12
+ "quoteProps": "preserve"
13
+ }
14
+ },
15
+ {
16
+ "files": ["*.yml"],
17
+ "options": {
18
+ "singleQuote": false
19
+ }
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,6 @@
1
+ // Mocks all files ending in `.vue` showing them as plain Vue instances
2
+ declare module '*.vue' {
3
+ import type { ComponentOptions } from 'vue'
4
+ const component: ComponentOptions
5
+ export default component
6
+ }
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <div>
3
+ {{ lang.helloWorld }}
4
+ {{ iconSet.someIcon }}
5
+ </div>
6
+ </template>
7
+
8
+ <script lang="ts">
9
+ export default {
10
+ name: 'HelloWorld'
11
+ }
12
+ </script>
13
+
14
+ <script setup lang="ts">
15
+ import { useIconSet } from '../icon-set'
16
+ import { useLang } from '../lang'
17
+
18
+ const lang = useLang()
19
+ const iconSet = useIconSet()
20
+ </script>
@@ -0,0 +1,40 @@
1
+ export interface IconSet {
2
+ name: string
3
+ someIcon: string
4
+ }
5
+
6
+ import type { Ref } from 'vue'
7
+ import { ref } from 'vue'
8
+ import material from './material-icons'
9
+ export const iconSet = ref(material)
10
+
11
+ const iconSets = import.meta.glob<{ default: IconSet }>([
12
+ './*.ts',
13
+ '!./index.ts'
14
+ ])
15
+
16
+ export const defineIconSet = (iconSet: IconSet) => {
17
+ return iconSet
18
+ }
19
+
20
+ export const useIconSet = () => {
21
+ return iconSet as Ref<IconSet>
22
+ }
23
+
24
+ let loadingIconSet = false
25
+ export const loadIconSet = async (name: string) => {
26
+ if (!loadingIconSet) {
27
+ loadingIconSet = true
28
+ try {
29
+ const data = (await iconSets[`./${name}.ts`]()).default
30
+
31
+ if (data) {
32
+ iconSet.value = data
33
+ }
34
+ } catch (e) {
35
+ if (import.meta.env.DEBUG) console.error(e)
36
+ throw new Error(`[quasar-components] Failed to load ${name} icon set.`)
37
+ }
38
+ loadingIconSet = false
39
+ }
40
+ }
@@ -0,0 +1,8 @@
1
+ import type { IconSet } from '../icon-set'
2
+
3
+ const iconSet: IconSet = {
4
+ name: 'material-icons',
5
+ someIcon: 'check'
6
+ }
7
+
8
+ export default iconSet
@@ -0,0 +1,9 @@
1
+ import * as VuePlugin from './vue-plugin'
2
+ import HelloWorld from './components/HelloWorld.vue'
3
+
4
+ // export * from './utils/helpers'
5
+ export * from './lang'
6
+ export * from './icon-set'
7
+ export { HelloWorld }
8
+
9
+ export default VuePlugin
@@ -0,0 +1,8 @@
1
+ import type { Language } from '../lang'
2
+
3
+ const lang: Language = {
4
+ isoName: 'en-US',
5
+ helloWorld: 'Hello world!'
6
+ }
7
+
8
+ export default lang
@@ -0,0 +1,42 @@
1
+ export interface Language {
2
+ isoName: string
3
+ helloWorld: string
4
+ }
5
+
6
+ import type { Ref } from 'vue'
7
+ import { ref } from 'vue'
8
+ import en from './en-US'
9
+ export const lang = ref(en)
10
+
11
+ const locales = import.meta.glob<{ default: Language }>([
12
+ './*.ts',
13
+ '!./index.ts'
14
+ ])
15
+
16
+ export const defineLang = (lang: Language) => {
17
+ return lang
18
+ }
19
+
20
+ export const useLang = () => {
21
+ return lang as Ref<Language>
22
+ }
23
+
24
+ let loadingLanguage = false
25
+ export const loadLang = async (isoName: string) => {
26
+ if (!loadingLanguage) {
27
+ loadingLanguage = true
28
+ try {
29
+ const data = (await locales[`./${isoName}.ts`]()).default
30
+
31
+ if (data) {
32
+ lang.value = data
33
+ }
34
+ } catch (e) {
35
+ if (import.meta.env.DEBUG) console.error(e)
36
+ throw new Error(
37
+ `[quasar-components] Failed to load ${isoName} language file.`
38
+ )
39
+ }
40
+ loadingLanguage = false
41
+ }
42
+ }
@@ -0,0 +1 @@
1
+ export default {}
@@ -0,0 +1,15 @@
1
+ const components = import.meta.glob('./components/*.vue')
2
+
3
+ import { loadLang } from './lang'
4
+
5
+ function install(app: any, options: { lang: string }) {
6
+ loadLang(options?.lang || 'en-us')
7
+ for (const path in components) {
8
+ components[path]().then((mod) => {
9
+ // @ts-ignore
10
+ app.component(mod.name, mod)
11
+ })
12
+ }
13
+ }
14
+
15
+ export { install }
@@ -0,0 +1,53 @@
1
+ import type { Plugin } from 'vite'
2
+ import { promises } from 'fs'
3
+ const { readFile } = promises
4
+
5
+ export default async function ({
6
+ buildFromSrc
7
+ }: {
8
+ buildFromSrc?: boolean
9
+ } = {}): Promise<Plugin> {
10
+ const pkgJson = JSON.parse(
11
+ await readFile(
12
+ new URL('../package.json', import.meta.url).pathname,
13
+ 'utf-8'
14
+ )
15
+ )
16
+ const exports = pkgJson.exports as Record<
17
+ string,
18
+ {
19
+ types: string
20
+ import: string
21
+ src: string
22
+ }
23
+ >[]
24
+ const name = pkgJson.name
25
+
26
+ return {
27
+ name: `${name}-plugin`,
28
+ config(config, { mode }) {
29
+ if (mode === 'development' || buildFromSrc) {
30
+ const alias = Object.entries(exports)
31
+ .map(([key, val]) => {
32
+ return {
33
+ find: name + key.slice(1),
34
+ replacement: new URL('.' + val.src, import.meta.url).pathname
35
+ }
36
+ })
37
+ .sort(
38
+ (a, b) =>
39
+ (b.find.match(/\//g) || []).length -
40
+ (a.find.match(/\//g) || []).length
41
+ )
42
+
43
+ return {
44
+ resolve: {
45
+ alias
46
+ }
47
+ }
48
+ }
49
+
50
+ return {}
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "compilerOptions": {
3
+ "rootDir": "./src"
4
+ },
5
+ "extends": "./tsconfig.node.json",
6
+ "include": ["./src/vite-plugin.ts"]
7
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "module": "esnext",
5
+ "moduleResolution": "node",
6
+ "outDir": "./dist",
7
+ "declaration": true,
8
+ "resolveJsonModule": true
9
+ },
10
+ "include": ["vite.config.ts"]
11
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "module": "esnext",
5
+ "lib": ["esnext", "DOM"],
6
+ "strict": true,
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "node",
9
+ "declaration": true,
10
+ "outDir": "dist",
11
+ "emitDeclarationOnly": true,
12
+ "declarationDir": "./dist/types",
13
+ "isolatedModules": true,
14
+ "types": ["vite/client"]
15
+ },
16
+ "include": ["./src/ui"]
17
+ }
@@ -0,0 +1,41 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+ import Components from 'unplugin-vue-components/vite'
4
+ import { QuasarResolver } from 'unplugin-vue-components/resolvers'
5
+
6
+ export default defineConfig(async ({ command, mode }) => ({
7
+ plugins: [
8
+ vue(),
9
+ Components({
10
+ resolvers: [QuasarResolver()]
11
+ })
12
+ ],
13
+ build: {
14
+ // minify: false,
15
+ lib: {
16
+ fileName: 'ui',
17
+ formats: ['es'],
18
+ entry: './src/ui/index.ts'
19
+ },
20
+ minify: false,
21
+ emptyOutDir: true,
22
+ rollupOptions: {
23
+ /**
24
+ * For building subpath exports
25
+ */
26
+ // input: {
27
+ // subodule: new URL(
28
+ // './src/ui/submodule/index.ts',
29
+ // import.meta.url
30
+ // ).pathname
31
+ // },
32
+ output: {
33
+ entryFileNames: '[name].js'
34
+ },
35
+ /**
36
+ * Add (UI) frameworks that are used
37
+ */
38
+ external: ['vue', 'vue-router', 'quasar']
39
+ }
40
+ }
41
+ }))
package/dist/index.js DELETED
@@ -1,83 +0,0 @@
1
- import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs';
2
- import Handlebars from 'handlebars';
3
- export const renderAll = ({ inputPath, outputPath, templateVariables, exclude }) => {
4
- if (!existsSync(outputPath)) {
5
- mkdirSync(outputPath);
6
- }
7
- const content = readdirSync(inputPath, { withFileTypes: true });
8
- const files = content
9
- .filter((dirent) => !dirent.isDirectory())
10
- .map((dirent) => dirent.name);
11
- const directories = content
12
- .filter((dirent) => dirent.isDirectory())
13
- .map((dirent) => dirent.name);
14
- for (let file of files) {
15
- const fileContent = readFileSync(new URL(`./${file}`, inputPath), 'utf-8');
16
- let output;
17
- if (file.endsWith('.hbs')) {
18
- const template = Handlebars.compile(fileContent);
19
- output = template(templateVariables);
20
- }
21
- else {
22
- output = fileContent;
23
- }
24
- if (file.startsWith('_'))
25
- file = file.replace('_', '.');
26
- const fileOutputPath = new URL(file.replace('.hbs', ''), outputPath);
27
- writeFileSync(fileOutputPath, output, 'utf-8');
28
- }
29
- for (const directory of directories) {
30
- renderAll({
31
- inputPath: new URL(`./${directory}/`, inputPath),
32
- outputPath: new URL(`./${directory}/`, outputPath),
33
- templateVariables
34
- });
35
- }
36
- };
37
- export const render = ({ inputPath, outputPath, templateVariables }) => {
38
- const outputFolder = new URL('./', outputPath);
39
- if (!existsSync(outputFolder)) {
40
- mkdirSync(outputFolder);
41
- }
42
- const fileContent = readFileSync(new URL(inputPath), 'utf-8');
43
- const template = Handlebars.compile(fileContent);
44
- const compiled = template(templateVariables);
45
- writeFileSync(outputPath, compiled, 'utf-8');
46
- };
47
- export const renderTemplate = ({ templateUrl, templateVariables, outputDir }) => {
48
- if (outputDir.pathname[outputDir.pathname.length - 1] !== '/') {
49
- throw new Error('outputDir is not a directory. Make sure the URL ends with a /');
50
- }
51
- // const templatesDir = new URL(`../templates/`, import.meta.url)
52
- // const templateDir = new URL(`../templates/${template}/`, import.meta.url)
53
- /**
54
- * General Quasar project files
55
- */
56
- // render({
57
- // inputPath: new URL('./package.json.hbs', templatesDir),
58
- // outputPath: new URL(`./package.json`, outputDir),
59
- // templateVariables
60
- // })
61
- // render({
62
- // inputPath: new URL('./quasar.conf.js', templatesDir),
63
- // outputPath: new URL(`./quasar.conf.js`, outputDir),
64
- // templateVariables
65
- // })
66
- // render({
67
- // inputPath: new URL('_gitignore', templateUrl),
68
- // outputPath: new URL(`.gitignore`, outputDir),
69
- // templateVariables
70
- // })
71
- /**
72
- * Specific template files
73
- */
74
- renderAll({
75
- inputPath: new URL(`./`, templateUrl),
76
- outputPath: new URL(`./`, outputDir),
77
- templateVariables
78
- });
79
- };
80
- // renderTemplate({
81
- // template: 'quasar-ts',
82
- // outputDir: new URL('./generated/', import.meta.url)
83
- // })
@@ -1,16 +0,0 @@
1
- export declare const renderAll: ({ inputPath, outputPath, templateVariables, exclude }: {
2
- inputPath: URL;
3
- outputPath: URL;
4
- templateVariables: Record<string, any>;
5
- exclude?: string[] | undefined;
6
- }) => void;
7
- export declare const render: ({ inputPath, outputPath, templateVariables }: {
8
- inputPath: URL;
9
- outputPath: URL;
10
- templateVariables: Record<string, any>;
11
- }) => void;
12
- export declare const renderTemplate: ({ templateUrl, templateVariables, outputDir }: {
13
- templateUrl: URL;
14
- templateVariables: Record<string, any>;
15
- outputDir: URL;
16
- }) => void;
@@ -1,28 +0,0 @@
1
- {
2
- "name": "{{ name }}",
3
- "productName": "{{ productName }}",
4
- "version": "1.0.0",
5
- "type": "module",
6
- "description": "{{ description }}",
7
- "scripts": {
8
- "dev": "vitrify dev",
9
- "build": "vitrify build",
10
- "build:ssr": "vitrify build -m ssr",
11
- "test": "echo \"Error: no test specified\" && exit 1"
12
- },
13
- "author": "{{ author }}",
14
- "dependencies": {
15
- "@fastify/static": "^6.4.0",
16
- "fastify": "^4.0.0",
17
- "fastify-plugin": "^3.0.1",
18
- "vue": "^3.2.37",
19
- "vue-router": "^4.0.12",
20
- "@quasar/extras": "^1.13.1",
21
- "quasar": "^2.6.0"
22
- },
23
- "devDependencies": {
24
- "@vue/server-renderer": "^3.2.37",
25
- "vitrify": "^0.5.0",
26
- "typescript": "^4.6.2"
27
- }
28
- }
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "esnext",
4
- "useDefineForClassFields": true,
5
- "module": "esnext",
6
- "moduleResolution": "node",
7
- "strict": true,
8
- "jsx": "preserve",
9
- "sourceMap": true,
10
- "resolveJsonModule": true,
11
- "esModuleInterop": true,
12
- "lib": ["esnext", "dom"]
13
- },
14
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
15
- }
@@ -1,23 +0,0 @@
1
- export default function ({ mode, command }) {
2
- return {
3
- vitrify: {
4
- hooks: {
5
- // Vitrify hooks
6
- },
7
- sass: {
8
- variables: {
9
- $primary: '#000000'
10
- }
11
- }
12
- },
13
- quasar: {
14
- extras: ['material-icons'],
15
- framework: {
16
- components: [
17
- // Deprecated
18
- ],
19
- plugins: []
20
- }
21
- }
22
- }
23
- }