buner 0.0.2 → 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.
Files changed (175) hide show
  1. package/.env +15 -0
  2. package/.env.development +6 -0
  3. package/.env.eshn +5 -0
  4. package/README.md +141 -5
  5. package/bin/buner.js +566 -0
  6. package/cli/README.md +1 -0
  7. package/cli/buner.ts +234 -0
  8. package/cli/cli.ts +125 -0
  9. package/cli/create-app.ts +59 -0
  10. package/cli/helpers/copy.ts +62 -0
  11. package/cli/helpers/format-files.ts +189 -0
  12. package/cli/helpers/git.ts +77 -0
  13. package/cli/helpers/install.ts +26 -0
  14. package/cli/helpers/is-folder-empty.ts +40 -0
  15. package/cli/helpers/is-writeable.ts +14 -0
  16. package/cli/helpers/make-dir.ts +7 -0
  17. package/cli/helpers/validate-pkg.ts +17 -0
  18. package/cli/install-template.ts +77 -0
  19. package/eslint.config.mjs +187 -0
  20. package/index.html +44 -0
  21. package/integration.ts +179 -0
  22. package/migrate-scss.ts +42 -0
  23. package/package.json +135 -7
  24. package/prerender.ts +229 -0
  25. package/public/.nojekyll +1 -0
  26. package/public/400.html +1 -0
  27. package/public/401.html +21 -0
  28. package/public/403.html +252 -0
  29. package/public/404.css +51 -0
  30. package/public/404.html +29 -0
  31. package/public/__images__/awww.jpeg +0 -0
  32. package/public/__images__/bat-body.png +0 -0
  33. package/public/__images__/bat-wing.png +0 -0
  34. package/public/__images__/haunted-house-background.png +0 -0
  35. package/public/__images__/haunted-house-foreground.png +0 -0
  36. package/public/assets/fonts/crimson-text/CrimsonText-Bold.ttf +0 -0
  37. package/public/assets/fonts/crimson-text/CrimsonText-BoldItalic.ttf +0 -0
  38. package/public/assets/fonts/crimson-text/CrimsonText-Italic.ttf +0 -0
  39. package/public/assets/fonts/crimson-text/CrimsonText-Regular.ttf +0 -0
  40. package/public/assets/fonts/crimson-text/CrimsonText-SemiBold.ttf +0 -0
  41. package/public/assets/fonts/crimson-text/CrimsonText-SemiBoldItalic.ttf +0 -0
  42. package/public/assets/fonts/crimson-text/CrimsonText.woff2 +0 -0
  43. package/public/assets/fonts/crimson-text/OFL.txt +93 -0
  44. package/public/assets/fonts/work-sans/OFL.txt +93 -0
  45. package/public/assets/fonts/work-sans/README.txt +81 -0
  46. package/public/assets/fonts/work-sans/WorkSans-Italic-VariableFont_wght.ttf +0 -0
  47. package/public/assets/fonts/work-sans/WorkSans-VariableFont_wght.ttf +0 -0
  48. package/public/assets/fonts/work-sans/WorkSans.woff2 +0 -0
  49. package/public/assets/fonts/work-sans/static/WorkSans-Black.ttf +0 -0
  50. package/public/assets/fonts/work-sans/static/WorkSans-BlackItalic.ttf +0 -0
  51. package/public/assets/fonts/work-sans/static/WorkSans-Bold.ttf +0 -0
  52. package/public/assets/fonts/work-sans/static/WorkSans-BoldItalic.ttf +0 -0
  53. package/public/assets/fonts/work-sans/static/WorkSans-ExtraBold.ttf +0 -0
  54. package/public/assets/fonts/work-sans/static/WorkSans-ExtraBoldItalic.ttf +0 -0
  55. package/public/assets/fonts/work-sans/static/WorkSans-ExtraLight.ttf +0 -0
  56. package/public/assets/fonts/work-sans/static/WorkSans-ExtraLightItalic.ttf +0 -0
  57. package/public/assets/fonts/work-sans/static/WorkSans-Italic.ttf +0 -0
  58. package/public/assets/fonts/work-sans/static/WorkSans-Light.ttf +0 -0
  59. package/public/assets/fonts/work-sans/static/WorkSans-LightItalic.ttf +0 -0
  60. package/public/assets/fonts/work-sans/static/WorkSans-Medium.ttf +0 -0
  61. package/public/assets/fonts/work-sans/static/WorkSans-MediumItalic.ttf +0 -0
  62. package/public/assets/fonts/work-sans/static/WorkSans-Regular.ttf +0 -0
  63. package/public/assets/fonts/work-sans/static/WorkSans-SemiBold.ttf +0 -0
  64. package/public/assets/fonts/work-sans/static/WorkSans-SemiBoldItalic.ttf +0 -0
  65. package/public/assets/fonts/work-sans/static/WorkSans-Thin.ttf +0 -0
  66. package/public/assets/fonts/work-sans/static/WorkSans-ThinItalic.ttf +0 -0
  67. package/public/assets/images/icons.svg +67 -0
  68. package/public/assets/images/logo.svg +14 -0
  69. package/public/assets/images/root.svg +49 -0
  70. package/public/assets/vendors/axios@0.24.0/axios.js +2275 -0
  71. package/public/assets/vendors/axios@0.24.0/axios.map +1 -0
  72. package/public/assets/vendors/axios@0.24.0/axios.min.js +2 -0
  73. package/public/assets/vendors/axios@0.24.0/axios.min.map +1 -0
  74. package/public/favicon.ico +0 -0
  75. package/public/favicon.svg +3 -0
  76. package/public/icon-128.png +0 -0
  77. package/public/icon-16.png +0 -0
  78. package/public/icon-192.png +0 -0
  79. package/public/icon-48.png +0 -0
  80. package/public/icon-512.png +0 -0
  81. package/public/json/avatar.json +42 -0
  82. package/public/manifest.webmanifest +29 -0
  83. package/public/mockServiceWorker.js +349 -0
  84. package/public/pl-states.svg +4 -0
  85. package/public/samples/01.svg +1 -0
  86. package/public/samples/Airbnb.svg +3 -0
  87. package/public/samples/Facebook.svg +3 -0
  88. package/public/samples/Google.svg +8 -0
  89. package/public/samples/Microsoft.svg +7 -0
  90. package/public/samples/Spotify.svg +3 -0
  91. package/public/samples/alexandra-stolz.svg +35 -0
  92. package/public/samples/browserconfig.xml +9 -0
  93. package/public/samples/cliff-curtis.jpg +0 -0
  94. package/public/samples/emilia-clarke.jpg +0 -0
  95. package/public/samples/favicon.ico +0 -0
  96. package/public/samples/icons/android-chrome-192x192.png +0 -0
  97. package/public/samples/icons/apple-touch-icon.png +0 -0
  98. package/public/samples/icons/favicon-144x144.png +0 -0
  99. package/public/samples/icons/favicon-150x150.png +0 -0
  100. package/public/samples/icons/favicon-16x16.png +0 -0
  101. package/public/samples/icons/favicon-32x32.png +0 -0
  102. package/public/samples/icons/favicon-48x48.png +0 -0
  103. package/public/samples/icons/favicon-70x70.png +0 -0
  104. package/public/samples/icons/favicon.ico +0 -0
  105. package/public/samples/image-1.svg +166 -0
  106. package/public/samples/image-2.svg +110 -0
  107. package/public/samples/image-3.svg +113 -0
  108. package/public/samples/janet-bray.svg +36 -0
  109. package/public/samples/kate-winslet.jpg +0 -0
  110. package/public/samples/manifest.json +19 -0
  111. package/public/samples/michelle-yeoh.jpg +0 -0
  112. package/public/samples/peg-legge.svg +37 -0
  113. package/public/samples/richard-guerra.svg +42 -0
  114. package/public/samples/rose-leslie.jpg +0 -0
  115. package/public/samples/sample-1.svg +365 -0
  116. package/public/samples/sample-2.svg +129 -0
  117. package/public/samples/sample-3.svg +93 -0
  118. package/public/samples/sample-4.svg +168 -0
  119. package/public/samples/sample-5.svg +155 -0
  120. package/public/samples/sample-6.svg +445 -0
  121. package/public/samples/sample-7.svg +404 -0
  122. package/public/samples/sample-8.png +0 -0
  123. package/public/staticwebapp.config.json +138 -0
  124. package/scripts.ts +56 -0
  125. package/server.ts +29 -0
  126. package/states.ts +63 -0
  127. package/styles.ts +232 -0
  128. package/tsconfig.json +71 -25
  129. package/types.d.ts +54 -0
  130. package/vite.config.ts +3 -0
  131. package/xpack/alias.ts +21 -0
  132. package/xpack/config.ts +59 -0
  133. package/xpack/create-server.ts +68 -0
  134. package/xpack/create-vite-dev-server.ts +33 -0
  135. package/xpack/deploy/deploy-inte.ts +3 -0
  136. package/xpack/filename.ts +43 -0
  137. package/xpack/hooks/build-start.ts +17 -0
  138. package/xpack/hooks/close-bundle.ts +19 -0
  139. package/xpack/hooks/handle-hot-update.ts +22 -0
  140. package/xpack/hooks/options.ts +55 -0
  141. package/xpack/hooks/resolve-dynamic-import.ts +18 -0
  142. package/xpack/hooks/transform-index-html.ts +18 -0
  143. package/xpack/hooks/transform.ts +72 -0
  144. package/xpack/hooks/write-bundle.ts +16 -0
  145. package/xpack/manual-chunk.ts +56 -0
  146. package/xpack/paths.ts +30 -0
  147. package/xpack/renderer.ts +141 -0
  148. package/xpack/root/active-item-options.tsx +98 -0
  149. package/xpack/root/frame-controls.tsx +139 -0
  150. package/xpack/root/index.tsx +107 -0
  151. package/xpack/root/rendered-item.tsx +25 -0
  152. package/xpack/root/root-context.ts +22 -0
  153. package/xpack/root/root-nav.tsx +162 -0
  154. package/xpack/root/state-animation-html.tsx +18 -0
  155. package/xpack/root/template.tsx +23 -0
  156. package/xpack/root/use-click-outside.ts +37 -0
  157. package/xpack/scripts/color-mode.entry.ts +28 -0
  158. package/xpack/scripts/mock-api.entry.ts +11 -0
  159. package/xpack/scripts/pl-states.entry.ts +321 -0
  160. package/xpack/scripts/root.entry.ts +135 -0
  161. package/xpack/scripts/theme-critical.entry.ts +20 -0
  162. package/xpack/states.schema.json +61 -0
  163. package/xpack/styles/_border.scss +22 -0
  164. package/xpack/styles/_breakpoint.scss +117 -0
  165. package/xpack/styles/_form.scss +23 -0
  166. package/xpack/styles/_px2rem.scss +5 -0
  167. package/xpack/styles/_reset.scss +134 -0
  168. package/xpack/styles/_state-toggle.scss +121 -0
  169. package/xpack/styles/_theme.scss +68 -0
  170. package/xpack/styles/_top-panel.scss +87 -0
  171. package/xpack/styles/_xpack-root.scss +322 -0
  172. package/xpack/styles/pl-states.scss +308 -0
  173. package/xpack/styles/root.scss +129 -0
  174. package/.github/workflows/deploy.yaml +0 -32
  175. package/index.ts +0 -1
package/xpack/alias.ts ADDED
@@ -0,0 +1,21 @@
1
+ import path from 'path';
2
+
3
+ import { root, srcRoot } from './paths';
4
+
5
+ const alias = [
6
+ { find: '@atoms', replacement: path.resolve(srcRoot, 'atoms') },
7
+ { find: '@molecules', replacement: path.resolve(srcRoot, 'molecules') },
8
+ { find: '@organisms', replacement: path.resolve(srcRoot, 'organisms') },
9
+ { find: '@templates', replacement: path.resolve(srcRoot, 'templates') },
10
+ { find: '@pages', replacement: path.resolve(srcRoot, 'pages') },
11
+ { find: '@assets', replacement: path.resolve(srcRoot, 'assets') },
12
+ { find: '@helpers', replacement: path.resolve(srcRoot, '_helpers') },
13
+ { find: '@data', replacement: path.resolve(srcRoot, '_data') },
14
+ { find: '@_types', replacement: path.resolve(srcRoot, '_types') },
15
+ { find: '@_http', replacement: path.resolve(srcRoot, '_http') },
16
+ { find: '@_api', replacement: path.resolve(srcRoot, '_api') },
17
+ { find: '@mocks', replacement: path.resolve(srcRoot, 'mocks') },
18
+ { find: '@xpack', replacement: path.resolve(root, 'xpack') },
19
+ ];
20
+
21
+ export default alias;
@@ -0,0 +1,59 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ import alias from './alias';
5
+ import { getAssetFileName, getChunkFileName, getEntryFileName } from './filename';
6
+ import { getManualChunk } from './manual-chunk';
7
+ import { outDir, xpackEnv } from './paths';
8
+ import buildStart from './hooks/build-start';
9
+ import writeBundle from './hooks/write-bundle';
10
+ import closeBundle from './hooks/close-bundle';
11
+ import resolveDynamicImport from './hooks/resolve-dynamic-import';
12
+ import handleHotUpdate from './hooks/handle-hot-update';
13
+ import transformIndexHtml from './hooks/transform-index-html';
14
+ import options from './hooks/options';
15
+ import transfrom from './hooks/transform';
16
+
17
+ // console.log('config');
18
+
19
+ const config = defineConfig({
20
+ base: xpackEnv.VITE_BASE_URL,
21
+ plugins: [
22
+ react(),
23
+ options(),
24
+ buildStart(),
25
+ transfrom(),
26
+ transformIndexHtml(xpackEnv.VITE_BASE_URL),
27
+ resolveDynamicImport(),
28
+ handleHotUpdate(),
29
+ writeBundle(),
30
+ closeBundle(),
31
+ ],
32
+ assetsInclude: ['**/*.svg', '**/*.htm', '**/*.cshtml'],
33
+ build: {
34
+ rollupOptions: {
35
+ output: {
36
+ entryFileNames: getEntryFileName,
37
+ chunkFileNames: getChunkFileName,
38
+ assetFileNames: getAssetFileName,
39
+ manualChunks: getManualChunk,
40
+ },
41
+ },
42
+ minify: 'esbuild',
43
+ sourcemap: true,
44
+ outDir,
45
+ emptyOutDir: true,
46
+ },
47
+
48
+ css: {
49
+ preprocessorOptions: {
50
+ scss: {},
51
+ },
52
+ },
53
+
54
+ resolve: {
55
+ alias: alias,
56
+ },
57
+ });
58
+
59
+ export default config;
@@ -0,0 +1,68 @@
1
+ /* eslint-disable no-console */
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ import express from 'express';
6
+ import serveStatic from 'serve-static';
7
+ import { ViteDevServer, loadEnv } from 'vite';
8
+ import chalk from 'chalk';
9
+
10
+ import { createViteDevServer } from './create-vite-dev-server.js';
11
+ import { _useRenderer } from './renderer.js';
12
+
13
+ interface Props {
14
+ root: string;
15
+ isTest: boolean;
16
+ port: number;
17
+ hmrPort?: number;
18
+ baseUrl?: string;
19
+ }
20
+
21
+ const argvModeIndex = process.argv.indexOf('--mode');
22
+ const mode =
23
+ argvModeIndex >= 0 && argvModeIndex < process.argv.length - 1 && !process.argv[argvModeIndex + 1].startsWith('-')
24
+ ? process.argv[argvModeIndex + 1]
25
+ : 'production';
26
+
27
+ process.env.MY_CUSTOM_SECRET = 'API_KEY_4c2928b5a14b475d94c3579cbea06178';
28
+ const isProd = process.env.NODE_ENV === 'production';
29
+
30
+ const createServer = async ({ root, hmrPort, baseUrl, isTest }: Props) => {
31
+ const resolve = (p: string) => path.join(root, p);
32
+
33
+ const indexProd = isProd ? fs.readFileSync(resolve('index.html'), 'utf-8') : '';
34
+
35
+ const app = express();
36
+
37
+ let viteDevServer: ViteDevServer | undefined;
38
+
39
+ if (!isProd) {
40
+ viteDevServer = await createViteDevServer({ root, baseUrl, hmrPort, isTest });
41
+ // use vite's connect instance as middleware
42
+ app.use(viteDevServer.middlewares);
43
+ }
44
+
45
+ app.use('/assets/images', serveStatic(resolve('public/assets/images'), { index: false }));
46
+ app.use('/assets/fonts', serveStatic(resolve('public/assets/fonts'), { index: false }));
47
+ app.use('/assets/css', serveStatic(resolve('public/assets/css'), { index: false }));
48
+ app.use('/assets/js', serveStatic(resolve('public/assets/js'), { index: false }));
49
+ app.use('/assets/vendors', serveStatic(resolve('public/assets/vendors'), { index: false }));
50
+ app.use('/assets', serveStatic(resolve('dist/assets'), { index: false }));
51
+ app.use('/samples', serveStatic(resolve('public/samples'), { index: false }));
52
+
53
+ _useRenderer({ app, indexProd, isProd, viteDevServer, resolve });
54
+
55
+ return { app, viteDevServer };
56
+ };
57
+
58
+ const startServer = (props: Props) => {
59
+ createServer(props).then(({ app }) => {
60
+ app.listen(props.port, () => {
61
+ const xpackEnv = loadEnv(mode, props.root);
62
+
63
+ console.log('Running on ' + chalk.green('http://localhost:' + props.port + xpackEnv.VITE_BASE_URL));
64
+ });
65
+ });
66
+ };
67
+
68
+ export { startServer };
@@ -0,0 +1,33 @@
1
+ import { ViteDevServer, createServer } from 'vite';
2
+
3
+ interface Props {
4
+ root: string;
5
+ baseUrl?: string;
6
+ isTest: boolean;
7
+ hmrPort?: number;
8
+ }
9
+
10
+ const createViteDevServer = ({ root, baseUrl, hmrPort, isTest }: Props): Promise<ViteDevServer> => {
11
+ const server = createServer({
12
+ root,
13
+ base: baseUrl,
14
+ logLevel: isTest ? 'error' : 'info',
15
+ server: {
16
+ middlewareMode: true,
17
+ watch: {
18
+ // During tests we edit the files too fast and sometimes chokidar
19
+ // misses change events, so enforce polling for consistency
20
+ usePolling: true,
21
+ interval: 200,
22
+ },
23
+ hmr: {
24
+ port: hmrPort,
25
+ },
26
+ },
27
+ appType: 'custom',
28
+ });
29
+
30
+ return server;
31
+ };
32
+
33
+ export { createViteDevServer };
@@ -0,0 +1,3 @@
1
+ const deployInte = () => {};
2
+
3
+ export { deployInte };
@@ -0,0 +1,43 @@
1
+ import _ from 'lodash';
2
+ import { PreRenderedAsset, PreRenderedChunk } from 'rollup';
3
+
4
+ // console.log('filename');
5
+
6
+ interface AssetPathInfo {
7
+ name?: string;
8
+ ext: string;
9
+ noHash?: boolean;
10
+ }
11
+
12
+ const getAssetPath = ({ name, ext, noHash }: AssetPathInfo) => {
13
+ const normalizedName = _.lowerCase(name).replaceAll(/(\s+)/gi, '-');
14
+
15
+ if (noHash) {
16
+ return `assets/js/${normalizedName}.${ext}`;
17
+ }
18
+
19
+ return `assets/js/${normalizedName}.0x[hash].${ext}`;
20
+ };
21
+
22
+ export const getAssetFileName = (chunkInfo: PreRenderedAsset): string => {
23
+ // console.log('asset:', chunkInfo.name);
24
+ return getAssetPath({ name: chunkInfo.name, ext: 'css' });
25
+ };
26
+
27
+ export const getEntryFileName = (chunkInfo: PreRenderedChunk): string => {
28
+ // console.log('entry:', chunkInfo.name);
29
+ if (chunkInfo.name === 'entry-server') {
30
+ return chunkInfo.name + '.js';
31
+ }
32
+
33
+ if (chunkInfo.name === 'index') {
34
+ return 'assets/js/react-loader.0x[hash].js';
35
+ }
36
+
37
+ return getAssetPath({ name: chunkInfo.name, ext: 'js', noHash: true });
38
+ };
39
+
40
+ export const getChunkFileName = (chunkInfo: PreRenderedChunk): string => {
41
+ // console.log('chunk:', chunkInfo.name);
42
+ return getAssetPath({ name: chunkInfo.name, ext: 'js' });
43
+ };
@@ -0,0 +1,17 @@
1
+ import { NormalizedInputOptions } from 'rollup';
2
+ import { PluginOption } from 'vite';
3
+
4
+ const buildStart = (): PluginOption => {
5
+ // console.log('[INIT] buildStart');
6
+
7
+ return {
8
+ name: 'xpack-build-start',
9
+ enforce: 'pre',
10
+
11
+ buildStart(_options: NormalizedInputOptions) {
12
+ // console.log('buildStart');
13
+ },
14
+ };
15
+ };
16
+
17
+ export default buildStart;
@@ -0,0 +1,19 @@
1
+ import { PluginOption } from 'vite';
2
+
3
+ import { deployInte } from '../deploy/deploy-inte';
4
+
5
+ const closeBundle = (): PluginOption => {
6
+ // console.log('[INIT] closeBundle');
7
+
8
+ return {
9
+ name: 'xpack-close-bundle',
10
+ enforce: 'post',
11
+
12
+ closeBundle() {
13
+ // console.log('closeBundle');
14
+ deployInte();
15
+ },
16
+ };
17
+ };
18
+
19
+ export default closeBundle;
@@ -0,0 +1,22 @@
1
+ import { PluginOption } from 'vite';
2
+
3
+ const handleHotUpdate = (): PluginOption => {
4
+ // console.log('[INIT] handleHotUpdate');
5
+
6
+ return {
7
+ name: 'xpack-hot-update',
8
+ enforce: 'post',
9
+
10
+ handleHotUpdate({ file, server }) {
11
+ // console.log('handleHotUpdate');
12
+
13
+ if (file.endsWith('.js') || file.endsWith('.css') || file.endsWith('.json'))
14
+ server.ws.send({
15
+ type: 'full-reload',
16
+ path: '*',
17
+ });
18
+ },
19
+ };
20
+ };
21
+
22
+ export default handleHotUpdate;
@@ -0,0 +1,55 @@
1
+ import path from 'path';
2
+
3
+ import { glob } from 'glob';
4
+ import { PluginOption } from 'vite';
5
+
6
+ import { root, mode } from '../paths';
7
+ const scriptOnly = process.env.scriptOnly;
8
+
9
+ const options = (): PluginOption => {
10
+ // console.log('[INIT] options');
11
+
12
+ const getSiteInputs = () => {
13
+ const inputs: { [name: string]: string } = {};
14
+
15
+ if (!scriptOnly) {
16
+ inputs['index'] = `${root}/index.html`;
17
+ }
18
+
19
+ const filePaths = glob.sync(['/src/assets/**/*.entry.ts', '/xpack/scripts/**/*.entry.ts'], { root: root });
20
+
21
+ [].forEach.call(filePaths, (filePath: string) => {
22
+ const fileName = path.basename(filePath).toLowerCase();
23
+ const entryName = fileName.replace(/\.entry\.ts$/gi, '');
24
+
25
+ if (entryName === 'mock-api' && mode === 'production') {
26
+ return;
27
+ }
28
+
29
+ if (entryName != fileName) {
30
+ inputs[entryName] = filePath;
31
+
32
+ return;
33
+ }
34
+ });
35
+
36
+ return inputs;
37
+ };
38
+
39
+ return {
40
+ name: 'xpack-options',
41
+ enforce: 'pre',
42
+
43
+ options(options) {
44
+ // console.log('options');
45
+
46
+ if (typeof options.input === 'string' && options.input.includes('entry-server')) {
47
+ return options;
48
+ }
49
+
50
+ options.input = getSiteInputs();
51
+ },
52
+ };
53
+ };
54
+
55
+ export default options;
@@ -0,0 +1,18 @@
1
+ import { AcornNode } from 'rollup';
2
+ import { PluginOption } from 'vite';
3
+
4
+ const resolveDynamicImport = (): PluginOption => {
5
+ // console.log('[INIT] resolveDynamicImport');
6
+
7
+ return {
8
+ name: 'xpack-transform',
9
+ enforce: 'post',
10
+
11
+ resolveDynamicImport(_specifier: string | AcornNode, _importer: string) {
12
+ // console.log('resolveDynamicImport');
13
+ // console.log(_specifier, _importer);
14
+ },
15
+ };
16
+ };
17
+
18
+ export default resolveDynamicImport;
@@ -0,0 +1,18 @@
1
+ import { PluginOption } from 'vite';
2
+
3
+ const transformIndexHtml = (baseUrl: string): PluginOption => {
4
+ // console.log('[INIT] transformIndexHtml');
5
+
6
+ return {
7
+ name: 'xpack-transform-index-html',
8
+ enforce: 'post',
9
+
10
+ transformIndexHtml(html) {
11
+ // console.log('transformIndexHtml');
12
+
13
+ return html.replaceAll('#__BASE_URL__/', baseUrl);
14
+ },
15
+ };
16
+ };
17
+
18
+ export default transformIndexHtml;
@@ -0,0 +1,72 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import crypto from 'node:crypto';
4
+
5
+ import MagicString, { SourceMapOptions } from 'magic-string';
6
+ import { PluginOption } from 'vite';
7
+
8
+ import { root, xpackEnv } from '../paths';
9
+
10
+ const transfrom = (): PluginOption => {
11
+ // console.log('[INIT] transform');
12
+ const hashes: { [key: string]: string } = {};
13
+
14
+ const getHash = (content: Buffer | string) => {
15
+ const sha1Hash = crypto.createHash('sha1');
16
+
17
+ sha1Hash.update(content);
18
+
19
+ return sha1Hash.digest('base64url').substring(0, 10);
20
+ };
21
+
22
+ return {
23
+ name: 'xpack-transform',
24
+ enforce: 'post',
25
+
26
+ transform(code, id, _options?) {
27
+ // console.log('transform');
28
+
29
+ const magicString = new MagicString(code);
30
+
31
+ magicString.replaceAll('VITE_EXTENSION_UNIQUE_ID', xpackEnv.VITE_EXTENSION_UNIQUE_ID).replaceAll(/\/assets\/[a-z0-9./_-]+\.svg\b\??/gi, (s) => {
32
+ if (s.includes('?')) {
33
+ // If the path already has a query string, return the original path
34
+ return s;
35
+ }
36
+
37
+ if (hashes[s]) {
38
+ // If the hash is already calculated, return the hash
39
+ return s + '?v=' + hashes[s];
40
+ }
41
+
42
+ const svgPath = path.resolve(root, 'public' + s);
43
+
44
+ if (fs.existsSync(svgPath)) {
45
+ // If the file exists, calculate the hash and return the hash
46
+ const content = fs.readFileSync(svgPath);
47
+ const hash = getHash(content);
48
+
49
+ hashes[s] = hash;
50
+
51
+ return s + '?v=' + hash;
52
+ }
53
+
54
+ // If the file does not exist, return the original path
55
+ return s;
56
+ });
57
+
58
+ const sourcemapOptions: SourceMapOptions = { source: id, file: id + '.map', includeContent: false, hires: true };
59
+ const newCode = magicString.toString();
60
+ const map = magicString.generateMap(sourcemapOptions);
61
+
62
+ return newCode !== code
63
+ ? {
64
+ code: newCode,
65
+ map,
66
+ }
67
+ : undefined;
68
+ },
69
+ };
70
+ };
71
+
72
+ export default transfrom;
@@ -0,0 +1,16 @@
1
+ import { PluginOption } from 'vite';
2
+
3
+ const writeBundle = (): PluginOption => {
4
+ // console.log('[INIT] writeBundle');
5
+
6
+ return {
7
+ name: 'xpack-write-bundle',
8
+ enforce: 'post',
9
+
10
+ writeBundle(/* options: NormalizedOutputOptions, bundle: OutputBundle */) {
11
+ // console.log('writeBundle');
12
+ },
13
+ };
14
+ };
15
+
16
+ export default writeBundle;
@@ -0,0 +1,56 @@
1
+ import path from 'path';
2
+
3
+ import { ManualChunkMeta } from 'rollup';
4
+ import slash from 'slash';
5
+
6
+ import { getAbsolutePath, srcRoot } from './paths';
7
+
8
+ // console.log('manual-chunk');
9
+
10
+ const getInternalName = (id: string, api: ManualChunkMeta): string | null | void => {
11
+ const moduleInfo = api.getModuleInfo(id);
12
+
13
+ if (!moduleInfo?.isEntry) {
14
+ return;
15
+ }
16
+
17
+ const entryPath = getAbsolutePath(id);
18
+
19
+ if (entryPath.startsWith(srcRoot)) {
20
+ const relativePath = slash(path.relative(srcRoot, entryPath));
21
+ const match = /^([a-z0-9.@_-]+?)\/([a-z0-9.@_-]+?)(\.[^\.]+)$/gi.exec(relativePath);
22
+
23
+ if (match) {
24
+ return match[1] + '~' + match[2];
25
+ }
26
+ }
27
+ };
28
+
29
+ const getExternalName = (_: string): string | null | void => {
30
+ // const name = id
31
+ // .toString()
32
+ // .split('node_modules/')[1]
33
+ // .split('/')[0]
34
+ // .toString();
35
+ // if (name === 'react') {
36
+ // return "react";
37
+ // }
38
+ // if (name === 'react-dom') {
39
+ // return "react-dom";
40
+ // }
41
+ // if (id.includes("@aws-amplify")) {
42
+ // return "vendor_aws";
43
+ // }
44
+ // else if (id.includes("@material-ui")) {
45
+ // return "vendor_mui";
46
+ // }
47
+ // return 'vendor'; // all other package goes here
48
+ };
49
+
50
+ export const getManualChunk = (id: string, api: ManualChunkMeta): string | null | void => {
51
+ if (id.includes('node_modules/')) {
52
+ return getExternalName(id);
53
+ } else {
54
+ return getInternalName(id, api);
55
+ }
56
+ };
package/xpack/paths.ts ADDED
@@ -0,0 +1,30 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+
4
+ import slash from 'slash';
5
+ import { loadEnv } from 'vite';
6
+
7
+ const argvModeIndex = process.argv.indexOf('--mode');
8
+ const mode =
9
+ argvModeIndex >= 0 && argvModeIndex < process.argv.length - 1 && !process.argv[argvModeIndex + 1].startsWith('-')
10
+ ? process.argv[argvModeIndex + 1]
11
+ : 'production';
12
+
13
+ // Consumer project root — where buner commands are run
14
+ export const root = slash(process.cwd());
15
+
16
+ // Package install location — where buner's own files live
17
+ export const packageRoot = slash(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'));
18
+
19
+ export const xpackEnv = loadEnv(mode, root);
20
+
21
+ export const srcRoot = slash(path.resolve(root, 'src'));
22
+ export const typesRoot = slash(path.resolve(srcRoot, '_types'));
23
+ export const viteSharedRoot = slash(path.resolve(root, 'xpack/shared'));
24
+ export const outDir = slash(path.resolve(root, 'dist'));
25
+
26
+ export const getAbsolutePath = (p: string) => {
27
+ return path.isAbsolute(p) ? slash(p) : slash(path.resolve(root, p));
28
+ };
29
+
30
+ export { mode };