buner 0.0.2 → 1.0.1
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/.env +15 -0
- package/.env.development +6 -0
- package/.env.eshn +5 -0
- package/README.md +141 -5
- package/bin/buner.js +566 -0
- package/cli/README.md +1 -0
- package/cli/buner.ts +234 -0
- package/cli/cli.ts +125 -0
- package/cli/create-app.ts +59 -0
- package/cli/helpers/copy.ts +62 -0
- package/cli/helpers/format-files.ts +189 -0
- package/cli/helpers/git.ts +77 -0
- package/cli/helpers/install.ts +26 -0
- package/cli/helpers/is-folder-empty.ts +40 -0
- package/cli/helpers/is-writeable.ts +14 -0
- package/cli/helpers/make-dir.ts +7 -0
- package/cli/helpers/validate-pkg.ts +17 -0
- package/cli/install-template.ts +77 -0
- package/eslint.config.mjs +187 -0
- package/index.html +44 -0
- package/integration.ts +179 -0
- package/migrate-scss.ts +42 -0
- package/package.json +135 -7
- package/prerender.ts +229 -0
- package/public/.nojekyll +1 -0
- package/public/400.html +1 -0
- package/public/401.html +21 -0
- package/public/403.html +252 -0
- package/public/404.css +51 -0
- package/public/404.html +29 -0
- package/public/__images__/awww.jpeg +0 -0
- package/public/__images__/bat-body.png +0 -0
- package/public/__images__/bat-wing.png +0 -0
- package/public/__images__/haunted-house-background.png +0 -0
- package/public/__images__/haunted-house-foreground.png +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText-Bold.ttf +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText-BoldItalic.ttf +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText-Italic.ttf +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText-Regular.ttf +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText-SemiBold.ttf +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText-SemiBoldItalic.ttf +0 -0
- package/public/assets/fonts/crimson-text/CrimsonText.woff2 +0 -0
- package/public/assets/fonts/crimson-text/OFL.txt +93 -0
- package/public/assets/fonts/work-sans/OFL.txt +93 -0
- package/public/assets/fonts/work-sans/README.txt +81 -0
- package/public/assets/fonts/work-sans/WorkSans-Italic-VariableFont_wght.ttf +0 -0
- package/public/assets/fonts/work-sans/WorkSans-VariableFont_wght.ttf +0 -0
- package/public/assets/fonts/work-sans/WorkSans.woff2 +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Black.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-BlackItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Bold.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-BoldItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-ExtraBold.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-ExtraBoldItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-ExtraLight.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-ExtraLightItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Italic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Light.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-LightItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Medium.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-MediumItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Regular.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-SemiBold.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-SemiBoldItalic.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-Thin.ttf +0 -0
- package/public/assets/fonts/work-sans/static/WorkSans-ThinItalic.ttf +0 -0
- package/public/assets/images/icons.svg +67 -0
- package/public/assets/images/logo.svg +14 -0
- package/public/assets/images/root.svg +49 -0
- package/public/assets/vendors/axios@0.24.0/axios.js +2275 -0
- package/public/assets/vendors/axios@0.24.0/axios.map +1 -0
- package/public/assets/vendors/axios@0.24.0/axios.min.js +2 -0
- package/public/assets/vendors/axios@0.24.0/axios.min.map +1 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +3 -0
- package/public/icon-128.png +0 -0
- package/public/icon-16.png +0 -0
- package/public/icon-192.png +0 -0
- package/public/icon-48.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/json/avatar.json +42 -0
- package/public/manifest.webmanifest +29 -0
- package/public/mockServiceWorker.js +349 -0
- package/public/pl-states.svg +4 -0
- package/public/samples/01.svg +1 -0
- package/public/samples/Airbnb.svg +3 -0
- package/public/samples/Facebook.svg +3 -0
- package/public/samples/Google.svg +8 -0
- package/public/samples/Microsoft.svg +7 -0
- package/public/samples/Spotify.svg +3 -0
- package/public/samples/alexandra-stolz.svg +35 -0
- package/public/samples/browserconfig.xml +9 -0
- package/public/samples/cliff-curtis.jpg +0 -0
- package/public/samples/emilia-clarke.jpg +0 -0
- package/public/samples/favicon.ico +0 -0
- package/public/samples/icons/android-chrome-192x192.png +0 -0
- package/public/samples/icons/apple-touch-icon.png +0 -0
- package/public/samples/icons/favicon-144x144.png +0 -0
- package/public/samples/icons/favicon-150x150.png +0 -0
- package/public/samples/icons/favicon-16x16.png +0 -0
- package/public/samples/icons/favicon-32x32.png +0 -0
- package/public/samples/icons/favicon-48x48.png +0 -0
- package/public/samples/icons/favicon-70x70.png +0 -0
- package/public/samples/icons/favicon.ico +0 -0
- package/public/samples/image-1.svg +166 -0
- package/public/samples/image-2.svg +110 -0
- package/public/samples/image-3.svg +113 -0
- package/public/samples/janet-bray.svg +36 -0
- package/public/samples/kate-winslet.jpg +0 -0
- package/public/samples/manifest.json +19 -0
- package/public/samples/michelle-yeoh.jpg +0 -0
- package/public/samples/peg-legge.svg +37 -0
- package/public/samples/richard-guerra.svg +42 -0
- package/public/samples/rose-leslie.jpg +0 -0
- package/public/samples/sample-1.svg +365 -0
- package/public/samples/sample-2.svg +129 -0
- package/public/samples/sample-3.svg +93 -0
- package/public/samples/sample-4.svg +168 -0
- package/public/samples/sample-5.svg +155 -0
- package/public/samples/sample-6.svg +445 -0
- package/public/samples/sample-7.svg +404 -0
- package/public/samples/sample-8.png +0 -0
- package/public/staticwebapp.config.json +138 -0
- package/scripts.ts +56 -0
- package/server.ts +29 -0
- package/states.ts +63 -0
- package/styles.ts +232 -0
- package/tsconfig.json +71 -25
- package/types.d.ts +54 -0
- package/vite.config.ts +3 -0
- package/xpack/alias.ts +21 -0
- package/xpack/config.ts +59 -0
- package/xpack/create-server.ts +68 -0
- package/xpack/create-vite-dev-server.ts +33 -0
- package/xpack/deploy/deploy-inte.ts +3 -0
- package/xpack/filename.ts +43 -0
- package/xpack/hooks/build-start.ts +17 -0
- package/xpack/hooks/close-bundle.ts +19 -0
- package/xpack/hooks/handle-hot-update.ts +22 -0
- package/xpack/hooks/options.ts +55 -0
- package/xpack/hooks/resolve-dynamic-import.ts +18 -0
- package/xpack/hooks/transform-index-html.ts +18 -0
- package/xpack/hooks/transform.ts +72 -0
- package/xpack/hooks/write-bundle.ts +16 -0
- package/xpack/manual-chunk.ts +56 -0
- package/xpack/paths.ts +30 -0
- package/xpack/react-loader-init.tsx +4 -0
- package/xpack/react-loader.tsx +54 -0
- package/xpack/renderer.ts +141 -0
- package/xpack/root/active-item-options.tsx +98 -0
- package/xpack/root/frame-controls.tsx +139 -0
- package/xpack/root/index.tsx +107 -0
- package/xpack/root/rendered-item.tsx +25 -0
- package/xpack/root/root-context.ts +22 -0
- package/xpack/root/root-nav.tsx +162 -0
- package/xpack/root/state-animation-html.tsx +18 -0
- package/xpack/root/template.tsx +23 -0
- package/xpack/root/use-click-outside.ts +37 -0
- package/xpack/scripts/color-mode.entry.ts +28 -0
- package/xpack/scripts/mock-api.entry.ts +11 -0
- package/xpack/scripts/pl-states.entry.ts +321 -0
- package/xpack/scripts/root.entry.ts +135 -0
- package/xpack/scripts/theme-critical.entry.ts +20 -0
- package/xpack/states.schema.json +61 -0
- package/xpack/styles/_border.scss +22 -0
- package/xpack/styles/_breakpoint.scss +117 -0
- package/xpack/styles/_form.scss +23 -0
- package/xpack/styles/_px2rem.scss +5 -0
- package/xpack/styles/_reset.scss +134 -0
- package/xpack/styles/_state-toggle.scss +121 -0
- package/xpack/styles/_theme.scss +68 -0
- package/xpack/styles/_top-panel.scss +87 -0
- package/xpack/styles/_xpack-root.scss +322 -0
- package/xpack/styles/pl-states.scss +308 -0
- package/xpack/styles/root.scss +129 -0
- package/.github/workflows/deploy.yaml +0 -32
- package/index.ts +0 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
|
|
6
|
+
function isInGitRepository(): boolean {
|
|
7
|
+
try {
|
|
8
|
+
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
|
|
9
|
+
|
|
10
|
+
return true;
|
|
11
|
+
} catch (_) {
|
|
12
|
+
/* empty */
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isInMercurialRepository(): boolean {
|
|
19
|
+
try {
|
|
20
|
+
execSync('hg --cwd . root', { stdio: 'ignore' });
|
|
21
|
+
|
|
22
|
+
return true;
|
|
23
|
+
} catch (_) {
|
|
24
|
+
/* empty */
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isDefaultBranchSet(): boolean {
|
|
31
|
+
try {
|
|
32
|
+
execSync('git config init.defaultBranch', { stdio: 'ignore' });
|
|
33
|
+
|
|
34
|
+
return true;
|
|
35
|
+
} catch (_) {
|
|
36
|
+
/* empty */
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const tryGitInit = (root: string): boolean => {
|
|
43
|
+
let didInit = false;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
execSync('git --version', { stdio: 'ignore' });
|
|
47
|
+
if (isInGitRepository() || isInMercurialRepository()) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
execSync('git init', { stdio: 'ignore' });
|
|
52
|
+
didInit = true;
|
|
53
|
+
|
|
54
|
+
if (!isDefaultBranchSet()) {
|
|
55
|
+
execSync('git checkout -b main', { stdio: 'ignore' });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
execSync('git add -A', { stdio: 'ignore' });
|
|
59
|
+
execSync('git commit -m "Initial commit from Create App"', {
|
|
60
|
+
stdio: 'ignore',
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
if (didInit) {
|
|
66
|
+
try {
|
|
67
|
+
fs.rmSync(path.join(root, '.git'), { recursive: true, force: true });
|
|
68
|
+
} catch (_) {
|
|
69
|
+
/* empty */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { tryGitInit };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { exec } from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
|
|
6
|
+
const { red } = chalk;
|
|
7
|
+
|
|
8
|
+
const install = async () => {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
exec('npm install', (error, stdout) => {
|
|
11
|
+
if (error) {
|
|
12
|
+
reject(error);
|
|
13
|
+
|
|
14
|
+
console.log(`${red(error)}`);
|
|
15
|
+
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log(stdout);
|
|
20
|
+
|
|
21
|
+
resolve(stdout);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { install };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
const isFolderEmpty = (root: string): boolean => {
|
|
4
|
+
const validFiles = [
|
|
5
|
+
'.DS_Store',
|
|
6
|
+
'.git',
|
|
7
|
+
'.gitattributes',
|
|
8
|
+
'.gitignore',
|
|
9
|
+
'.gitlab-ci.yml',
|
|
10
|
+
'.hg',
|
|
11
|
+
'.hgcheck',
|
|
12
|
+
'.hgignore',
|
|
13
|
+
'.idea',
|
|
14
|
+
'.npmignore',
|
|
15
|
+
'.travis.yml',
|
|
16
|
+
'LICENSE',
|
|
17
|
+
'Thumbs.db',
|
|
18
|
+
'docs',
|
|
19
|
+
'mkdocs.yml',
|
|
20
|
+
'npm-debug.log',
|
|
21
|
+
'yarn-debug.log',
|
|
22
|
+
'yarn-error.log',
|
|
23
|
+
'yarnrc.yml',
|
|
24
|
+
'.yarn',
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const conflicts = fs
|
|
28
|
+
.readdirSync(root)
|
|
29
|
+
.filter((file) => !validFiles.includes(file))
|
|
30
|
+
// Support IntelliJ IDEA-based editors
|
|
31
|
+
.filter((file) => !/\.iml$/.test(file));
|
|
32
|
+
|
|
33
|
+
if (conflicts.length > 0) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { isFolderEmpty };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
const isWriteable = async (directory: string): Promise<boolean> => {
|
|
4
|
+
try {
|
|
5
|
+
await fs.promises.access(directory, fs.constants.W_OK);
|
|
6
|
+
|
|
7
|
+
return true;
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
9
|
+
} catch (err) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { isWriteable };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import validateProjectName from 'validate-npm-package-name';
|
|
2
|
+
|
|
3
|
+
export function validateNpmName(name: string): {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
problems?: string[];
|
|
6
|
+
} {
|
|
7
|
+
const nameValidation = validateProjectName(name);
|
|
8
|
+
|
|
9
|
+
if (nameValidation.validForNewPackages && !name.startsWith('-')) {
|
|
10
|
+
return { valid: true };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
valid: false,
|
|
15
|
+
problems: [...(nameValidation.errors || []), ...(nameValidation.warnings || [])],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
|
|
9
|
+
import { copy } from './helpers/copy.js';
|
|
10
|
+
import { install } from './helpers/install.js';
|
|
11
|
+
import { formatFiles } from './helpers/format-files.js';
|
|
12
|
+
|
|
13
|
+
export const filename = fileURLToPath(import.meta.url);
|
|
14
|
+
export const dirname = path.dirname(filename);
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
appName: string;
|
|
18
|
+
root: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { cyan } = chalk;
|
|
22
|
+
|
|
23
|
+
const installTemplate = async (model: Props) => {
|
|
24
|
+
const { appName, root } = model;
|
|
25
|
+
|
|
26
|
+
console.log('\nInitializing project');
|
|
27
|
+
const copySource = ['**'];
|
|
28
|
+
|
|
29
|
+
await copy(copySource, root, {
|
|
30
|
+
cwd: path.join(dirname, '..'),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await formatFiles(root);
|
|
34
|
+
|
|
35
|
+
const packageJson = JSON.parse(await fs.readFile('package.json', 'utf8'));
|
|
36
|
+
|
|
37
|
+
packageJson.name = appName;
|
|
38
|
+
packageJson.description = '';
|
|
39
|
+
packageJson.version = '0.1.0';
|
|
40
|
+
|
|
41
|
+
delete packageJson.bin;
|
|
42
|
+
packageJson.scripts &&
|
|
43
|
+
Object.keys(packageJson.scripts).map((scriptName: string) => {
|
|
44
|
+
if (scriptName.startsWith('cli')) {
|
|
45
|
+
delete packageJson.scripts[scriptName];
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
packageJson.dependencies &&
|
|
50
|
+
Object.keys(packageJson.dependencies).map((dependency) => {
|
|
51
|
+
if (!dependency.startsWith('react')) {
|
|
52
|
+
delete packageJson.dependencies[dependency];
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const devDeps = Object.keys(packageJson.devDependencies).length;
|
|
57
|
+
|
|
58
|
+
if (!devDeps) delete packageJson.devDependencies;
|
|
59
|
+
|
|
60
|
+
await fs.writeFile(path.join(root, 'package.json'), JSON.stringify(packageJson, null, 2) + os.EOL);
|
|
61
|
+
|
|
62
|
+
console.log('\nInstalling dependencies:');
|
|
63
|
+
|
|
64
|
+
for (const dependency in packageJson.dependencies) {
|
|
65
|
+
console.log(`- ${cyan(dependency)}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (devDeps) {
|
|
69
|
+
console.log('\nInstalling devDependencies:');
|
|
70
|
+
|
|
71
|
+
for (const dependency in packageJson.devDependencies) console.log(`- ${cyan(dependency)}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await install();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { installTemplate };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
2
|
+
import { fixupConfigRules, fixupPluginRules } from '@eslint/compat';
|
|
3
|
+
import react from 'eslint-plugin-react';
|
|
4
|
+
import unusedImports from 'eslint-plugin-unused-imports';
|
|
5
|
+
import _import from 'eslint-plugin-import';
|
|
6
|
+
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
|
7
|
+
import jsxA11Y from 'eslint-plugin-jsx-a11y';
|
|
8
|
+
import prettier from 'eslint-plugin-prettier';
|
|
9
|
+
import nextPlugin from '@next/eslint-plugin-next';
|
|
10
|
+
import globals from 'globals';
|
|
11
|
+
import tsParser from '@typescript-eslint/parser';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
import js from '@eslint/js';
|
|
15
|
+
import { FlatCompat } from '@eslint/eslintrc';
|
|
16
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = path.dirname(__filename);
|
|
20
|
+
const compat = new FlatCompat({
|
|
21
|
+
baseDirectory: __dirname,
|
|
22
|
+
recommendedConfig: js.configs.recommended,
|
|
23
|
+
allConfig: js.configs.all,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export default defineConfig([
|
|
27
|
+
globalIgnores([
|
|
28
|
+
'.now/*',
|
|
29
|
+
'**/*.css',
|
|
30
|
+
'**/.changeset',
|
|
31
|
+
'**/dist',
|
|
32
|
+
'esm/*',
|
|
33
|
+
'public/*',
|
|
34
|
+
'tests/*',
|
|
35
|
+
'scripts/*',
|
|
36
|
+
'**/*.config.js',
|
|
37
|
+
'**/.DS_Store',
|
|
38
|
+
'**/node_modules',
|
|
39
|
+
'**/coverage',
|
|
40
|
+
'**/.next',
|
|
41
|
+
'**/build',
|
|
42
|
+
'!**/.commitlintrc.cjs',
|
|
43
|
+
'!**/.lintstagedrc.cjs',
|
|
44
|
+
'!**/jest.config.js',
|
|
45
|
+
'!**/plopfile.js',
|
|
46
|
+
'!**/react-shim.js',
|
|
47
|
+
'!**/tsup.config.ts',
|
|
48
|
+
]),
|
|
49
|
+
...fixupConfigRules(
|
|
50
|
+
compat.extends('plugin:react/recommended', 'plugin:prettier/recommended', 'plugin:react-hooks/recommended', 'plugin:jsx-a11y/recommended')
|
|
51
|
+
),
|
|
52
|
+
{
|
|
53
|
+
settings: {
|
|
54
|
+
react: {
|
|
55
|
+
version: 'detect',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
61
|
+
|
|
62
|
+
plugins: {
|
|
63
|
+
react: fixupPluginRules(react),
|
|
64
|
+
'unused-imports': unusedImports,
|
|
65
|
+
import: fixupPluginRules(_import),
|
|
66
|
+
'@typescript-eslint': typescriptEslint,
|
|
67
|
+
'react-refresh': reactRefresh,
|
|
68
|
+
'jsx-a11y': fixupPluginRules(jsxA11Y),
|
|
69
|
+
prettier: fixupPluginRules(prettier),
|
|
70
|
+
'@next/next': fixupPluginRules(nextPlugin),
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
languageOptions: {
|
|
74
|
+
globals: {
|
|
75
|
+
...globals.browser,
|
|
76
|
+
...globals.node,
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
parser: tsParser,
|
|
80
|
+
ecmaVersion: 'latest',
|
|
81
|
+
sourceType: 'module',
|
|
82
|
+
|
|
83
|
+
parserOptions: {
|
|
84
|
+
ecmaFeatures: {
|
|
85
|
+
jsx: true,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
rules: {
|
|
91
|
+
'no-console': 'warn',
|
|
92
|
+
'react/prop-types': 'off',
|
|
93
|
+
'react/jsx-uses-react': 'off',
|
|
94
|
+
'react/react-in-jsx-scope': 'off',
|
|
95
|
+
'react-hooks/exhaustive-deps': 'off',
|
|
96
|
+
'jsx-a11y/click-events-have-key-events': 'warn',
|
|
97
|
+
'jsx-a11y/interactive-supports-focus': 'warn',
|
|
98
|
+
'prettier/prettier': 'warn',
|
|
99
|
+
'no-unused-vars': 'off',
|
|
100
|
+
'unused-imports/no-unused-vars': 'off',
|
|
101
|
+
'unused-imports/no-unused-imports': 'warn',
|
|
102
|
+
'react-refresh/only-export-components': 'error',
|
|
103
|
+
'no-new': 'error',
|
|
104
|
+
complexity: ['error', 15],
|
|
105
|
+
'max-depth': ['error', 4],
|
|
106
|
+
|
|
107
|
+
'@typescript-eslint/no-unused-vars': [
|
|
108
|
+
'warn',
|
|
109
|
+
{
|
|
110
|
+
args: 'after-used',
|
|
111
|
+
ignoreRestSiblings: false,
|
|
112
|
+
argsIgnorePattern: '^_.*?$',
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
|
|
116
|
+
'import/order': [
|
|
117
|
+
'warn',
|
|
118
|
+
{
|
|
119
|
+
groups: ['type', 'builtin', 'object', 'external', 'internal', 'parent', 'sibling', 'index'],
|
|
120
|
+
|
|
121
|
+
pathGroups: [
|
|
122
|
+
{
|
|
123
|
+
pattern: '~/**',
|
|
124
|
+
group: 'external',
|
|
125
|
+
position: 'after',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
pattern: '@/**',
|
|
129
|
+
group: 'internal',
|
|
130
|
+
position: 'after',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
|
|
134
|
+
'newlines-between': 'always',
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
|
|
138
|
+
'react/self-closing-comp': 'warn',
|
|
139
|
+
|
|
140
|
+
'react/jsx-sort-props': [
|
|
141
|
+
'warn',
|
|
142
|
+
{
|
|
143
|
+
callbacksLast: true,
|
|
144
|
+
shorthandFirst: true,
|
|
145
|
+
noSortAlphabetically: false,
|
|
146
|
+
reservedFirst: true,
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
|
|
150
|
+
'padding-line-between-statements': [
|
|
151
|
+
'warn',
|
|
152
|
+
{
|
|
153
|
+
blankLine: 'always',
|
|
154
|
+
prev: '*',
|
|
155
|
+
next: 'return',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
blankLine: 'always',
|
|
159
|
+
prev: ['const', 'let', 'var'],
|
|
160
|
+
next: '*',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
blankLine: 'any',
|
|
164
|
+
prev: ['const', 'let', 'var'],
|
|
165
|
+
next: ['const', 'let', 'var'],
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
|
|
169
|
+
quotes: [
|
|
170
|
+
'warn',
|
|
171
|
+
'single',
|
|
172
|
+
{
|
|
173
|
+
avoidEscape: true,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
180
|
+
plugins: {
|
|
181
|
+
'@next/next': fixupPluginRules(nextPlugin),
|
|
182
|
+
},
|
|
183
|
+
rules: {
|
|
184
|
+
'@next/next/no-img-element': 'off',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
]);
|
package/index.html
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<link rel="icon" href="#__BASE_URL__/favicon.ico" sizes="any" />
|
|
7
|
+
<link rel="icon" href="#__BASE_URL__/favicon.svg" type="image/svg+xml" />
|
|
8
|
+
<link rel="manifest" href="#__BASE_URL__/manifest.webmanifest" />
|
|
9
|
+
<meta name="locale" content="en-US" />
|
|
10
|
+
<meta name="ROBOTS" content="NONE, NOARCHIVE" />
|
|
11
|
+
<meta name="GOOGLEBOT" content="NOARCHIVE" />
|
|
12
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes" />
|
|
14
|
+
<meta name="description" content="This is the description for Precise Alloy page." />
|
|
15
|
+
<title>B2C Home</title>
|
|
16
|
+
<meta name="twitter:image" content="#__BASE_URL__/icons/apple-touch-icon.png" />
|
|
17
|
+
<meta name="og:image" content="#__BASE_URL__/icons/apple-touch-icon.png" />
|
|
18
|
+
<meta name="theme-color" content="#fff" media="(prefers-color-scheme: light)" />
|
|
19
|
+
<meta name="theme-color" content="#fff" media="(prefers-color-scheme: dark)" />
|
|
20
|
+
<link rel="apple-touch-icon" sizes="180x180" href="#__BASE_URL__/icons/apple-touch-icon.png" />
|
|
21
|
+
<link rel="icon" type="image/png" sizes="32x32" href="#__BASE_URL__/icons/favicon-32x32.png" />
|
|
22
|
+
<link rel="icon" type="image/png" sizes="16x16" href="#__BASE_URL__/icons/favicon-16x16.png" />
|
|
23
|
+
<link rel="manifest" href="#__BASE_URL__/manifest.json" crossorigin />
|
|
24
|
+
<link rel="stylesheet" href="#__BASE_URL__/assets/css/style-base.css" as="style" />
|
|
25
|
+
<link rel="stylesheet" href="#__BASE_URL__/assets/css/pl-states.css" as="style" />
|
|
26
|
+
<link rel="preload" href="#__BASE_URL__/assets/fonts/work-sans/WorkSans.woff2" as="font" type="font/woff2" />
|
|
27
|
+
<link rel="preload" href="#__BASE_URL__/assets/fonts/crimson-text/CrimsonText.woff2" as="font" type="font/woff2" />
|
|
28
|
+
|
|
29
|
+
<script defer src="#__BASE_URL__/assets/js/color-mode.js"></script>
|
|
30
|
+
<script src="#__BASE_URL__/assets/js/theme-critical.js"></script>
|
|
31
|
+
|
|
32
|
+
<script defer src="#__BASE_URL__/assets/js/main.js"></script>
|
|
33
|
+
|
|
34
|
+
<!-- Don't include this line in a production site -->
|
|
35
|
+
<script type="module" src="#__BASE_URL__/assets/js/mock-api.js"></script>
|
|
36
|
+
<!-- Don't include this line in a production site -->
|
|
37
|
+
</head>
|
|
38
|
+
|
|
39
|
+
<body>
|
|
40
|
+
<!--app-html-->
|
|
41
|
+
<script type="module" src="/xpack/react-loader-init.tsx"></script>
|
|
42
|
+
<script type="module" defer src="#__BASE_URL__/assets/js/pl-states.js"></script>
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|
package/integration.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path, { resolve } from 'path';
|
|
4
|
+
import crypto from 'node:crypto';
|
|
5
|
+
import nodeFs from 'node:fs';
|
|
6
|
+
|
|
7
|
+
import slash from 'slash';
|
|
8
|
+
import { glob } from 'glob';
|
|
9
|
+
import { loadEnv } from 'vite';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
|
|
12
|
+
interface CopyItem {
|
|
13
|
+
from: string;
|
|
14
|
+
to?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface FileExistCheck {
|
|
18
|
+
folder?: string;
|
|
19
|
+
fileName: string | RegExp;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const argvModeIndex = process.argv.indexOf('--mode');
|
|
23
|
+
const mode =
|
|
24
|
+
argvModeIndex >= 0 && argvModeIndex < process.argv.length - 1 && !process.argv[argvModeIndex + 1].startsWith('-')
|
|
25
|
+
? process.argv[argvModeIndex + 1]
|
|
26
|
+
: 'production';
|
|
27
|
+
const projectRoot = process.cwd();
|
|
28
|
+
const xpackEnv = loadEnv(mode, projectRoot);
|
|
29
|
+
const toAbsolute = (p: string) => slash(path.resolve(projectRoot, p));
|
|
30
|
+
const log = console.log.bind(console);
|
|
31
|
+
|
|
32
|
+
const hashes: Map<string, string> = new Map();
|
|
33
|
+
const staticBasePath = toAbsolute('dist/static');
|
|
34
|
+
const srcBasePath = toAbsolute('dist/static/assets');
|
|
35
|
+
const destBasePath = toAbsolute(xpackEnv.VITE_INTE_ASSET_DIR);
|
|
36
|
+
const patternPath = xpackEnv.VITE_INTE_PATTERN_DIR ? toAbsolute(xpackEnv.VITE_INTE_PATTERN_DIR) : undefined;
|
|
37
|
+
|
|
38
|
+
if (patternPath && fs.existsSync(patternPath)) {
|
|
39
|
+
fs.rmSync(patternPath, { recursive: true, force: true });
|
|
40
|
+
|
|
41
|
+
fs.mkdirSync(patternPath, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const copyItems: CopyItem[] = [
|
|
45
|
+
{ from: 'css' },
|
|
46
|
+
{ from: 'fonts' },
|
|
47
|
+
{ from: 'images' },
|
|
48
|
+
{ from: 'js' },
|
|
49
|
+
{ from: 'vendors' },
|
|
50
|
+
{ from: 'hashes.json' },
|
|
51
|
+
{ from: 'pages', to: patternPath },
|
|
52
|
+
];
|
|
53
|
+
const hashItems: string[] = ['css', 'images', 'js'];
|
|
54
|
+
|
|
55
|
+
copyItems.forEach((item) => {
|
|
56
|
+
const srcPath = slash(path.join(srcBasePath, item.from));
|
|
57
|
+
const destPath = slash(item.to ?? path.join(destBasePath, item.from));
|
|
58
|
+
|
|
59
|
+
if (!fs.existsSync(srcPath)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
log(`Copy file ${srcPath} to ${destPath}`);
|
|
64
|
+
|
|
65
|
+
if (fs.statSync(srcPath).isDirectory()) {
|
|
66
|
+
if (fs.existsSync(destPath)) {
|
|
67
|
+
fs.rmSync(destPath, { recursive: true, force: true });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
71
|
+
|
|
72
|
+
fs.cpSync(srcPath, destPath, { recursive: true, force: true });
|
|
73
|
+
} else {
|
|
74
|
+
const destDirPath = path.dirname(destPath);
|
|
75
|
+
|
|
76
|
+
if (!fs.existsSync(destDirPath)) {
|
|
77
|
+
fs.mkdirSync(destDirPath);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
fs.copyFileSync(srcPath, destPath);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
hashItems.forEach((item) => {
|
|
85
|
+
const srcPath = slash(path.join(srcBasePath, item));
|
|
86
|
+
const files = glob.sync(srcPath + '/**/*.{css,js,svg}');
|
|
87
|
+
|
|
88
|
+
files.forEach((file) => {
|
|
89
|
+
const relativePath = slash(file.substring(staticBasePath.length));
|
|
90
|
+
|
|
91
|
+
if (!/\.0x[a-z0-9_-]{8,12}\.\w+$/gi.test(file)) {
|
|
92
|
+
const content = fs.readFileSync(file);
|
|
93
|
+
const sha1Hash = crypto.createHash('sha1');
|
|
94
|
+
|
|
95
|
+
sha1Hash.update(content);
|
|
96
|
+
const hash = sha1Hash.digest('base64url').substring(0, 10);
|
|
97
|
+
|
|
98
|
+
hashes.set(relativePath, hash);
|
|
99
|
+
} else {
|
|
100
|
+
hashes.set(relativePath, '');
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const sortedHashes = Array.from(hashes)
|
|
106
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
107
|
+
.reduce(
|
|
108
|
+
(obj, [key, value]) => {
|
|
109
|
+
obj[key] = value;
|
|
110
|
+
|
|
111
|
+
return obj;
|
|
112
|
+
},
|
|
113
|
+
{} as { [key: string]: string }
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
fs.writeFileSync(path.join(destBasePath, 'hashes.json'), JSON.stringify(sortedHashes, null, ' '));
|
|
117
|
+
|
|
118
|
+
if (patternPath) {
|
|
119
|
+
fs.mkdirSync(patternPath, { recursive: true });
|
|
120
|
+
glob.sync('./dist/static/{atoms,molecules,organisms,templates,pages}/**/*.*').forEach((p) => {
|
|
121
|
+
let basename = '';
|
|
122
|
+
const segments = slash(p).split('/');
|
|
123
|
+
|
|
124
|
+
if (segments.length < 4) return;
|
|
125
|
+
switch (segments.length) {
|
|
126
|
+
case 4:
|
|
127
|
+
basename = path.basename(slash(p).replaceAll(/(atoms|molecules|organisms|templates|pages)\/([\w._-]+)$/gi, '$1-$2'));
|
|
128
|
+
fs.copyFileSync(p, resolve(patternPath, basename));
|
|
129
|
+
break;
|
|
130
|
+
default:
|
|
131
|
+
segments.splice(0, 2);
|
|
132
|
+
nodeFs.cpSync(p, resolve(patternPath, segments.join('-')), { recursive: true });
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
glob.sync(slash(path.resolve(patternPath + '/**/*.{htm,html}'))).forEach((p) => {
|
|
138
|
+
const text = fs.readFileSync(p, 'utf-8');
|
|
139
|
+
const newText = text
|
|
140
|
+
.replaceAll(/react-loader\.0x[a-z0-9_-]{8,12}\.js/gi, 'react-loader.0x00000000.js')
|
|
141
|
+
.replaceAll(/\.svg\?v=[a-z0-9_-]+/gi, '.svg');
|
|
142
|
+
|
|
143
|
+
if (text !== newText) {
|
|
144
|
+
fs.writeFileSync(p, newText);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const checkExistFileList: FileExistCheck[] = [
|
|
150
|
+
{ fileName: 'hashes.json' },
|
|
151
|
+
{ fileName: /react-loader\.0x[a-z0-9_-]{8,12}\.js/gi, folder: 'js' },
|
|
152
|
+
{ fileName: 'main.js', folder: 'js' },
|
|
153
|
+
];
|
|
154
|
+
let isAllExist = true;
|
|
155
|
+
|
|
156
|
+
checkExistFileList.forEach((file) => {
|
|
157
|
+
if (typeof file.fileName === 'string') {
|
|
158
|
+
const destPath = slash(path.join(destBasePath, file.folder ?? '', file.fileName.toString()));
|
|
159
|
+
|
|
160
|
+
if (!fs.existsSync(destPath)) {
|
|
161
|
+
log(chalk.yellow(`Cannot find: ${destPath}`));
|
|
162
|
+
isAllExist = false;
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
const fileName = file.fileName;
|
|
166
|
+
const folderFiles = slash(path.join(destBasePath, file.folder ?? ''));
|
|
167
|
+
const files = fs.readdirSync(folderFiles);
|
|
168
|
+
const found = files.find((f) => fileName.test(f));
|
|
169
|
+
|
|
170
|
+
if (!found) {
|
|
171
|
+
log(chalk.yellow(`Cannot find: ${slash(path.join(folderFiles, fileName.toString()))}`));
|
|
172
|
+
isAllExist = false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
if (!isAllExist) {
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|