buner 1.0.4 → 1.0.6

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/cli/cli.ts DELETED
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
-
4
- import path from 'path';
5
-
6
- import { Command } from 'commander';
7
- import chalk from 'chalk';
8
- import fetch from 'node-fetch';
9
- import prompts from 'prompts';
10
-
11
- import packageJson from '../package.json';
12
-
13
- import { createApp } from './create-app.js';
14
- import { validateNpmName } from './helpers/validate-pkg.js';
15
-
16
- let projectPath = '';
17
- const program = new Command();
18
- const { green, yellow, bold, cyan, red } = chalk;
19
- const packageName = 'x-pkg';
20
-
21
- const onPromptState = (state: { value?: string; aborted?: boolean }) => {
22
- if (state?.aborted) {
23
- // If we don't re-enable the terminal cursor before exiting
24
- // the program, the cursor will remain hidden
25
- process.stdout.write('\x1B[?25h');
26
- process.stdout.write('\n');
27
- process.exit(1);
28
- }
29
- };
30
-
31
- program
32
- .name(packageName)
33
- .description('Create a FE framework')
34
- .version(packageJson.version)
35
- .argument('[project-directory]', 'the project name', '')
36
- .usage(`${green('[project-directory]')} [options]`)
37
- .action((name) => {
38
- projectPath = name;
39
- })
40
- .allowUnknownOption()
41
- .parse(process.argv);
42
-
43
- const parseVersion = (version: string): number => {
44
- return parseInt(version.replaceAll('.', ''));
45
- };
46
-
47
- const update = fetch(`https://registry.npmjs.org/${packageJson.name}/latest`)
48
- .then((res) => res.json())
49
- .catch(() => null);
50
-
51
- async function notifyUpdate(): Promise<void> {
52
- try {
53
- const data = (await update) as { version: string };
54
-
55
- if (data.version && parseVersion(data.version) !== parseVersion(packageJson.version)) {
56
- const updateMessage = `npm update ${packageName}`;
57
-
58
- console.log(
59
- yellow(bold(`A new version of '${packageName}' is available!`)) + '\n' + 'You can update by running: ' + cyan(updateMessage) + '\n'
60
- );
61
- }
62
-
63
- process.exit();
64
- } catch {
65
- // ignore error
66
- }
67
- }
68
-
69
- const run = async () => {
70
- const validation = validateNpmName(path.basename(path.resolve(projectPath)));
71
-
72
- if (!validation.valid) {
73
- const res = await prompts({
74
- onState: onPromptState,
75
- type: 'text',
76
- name: 'path',
77
- message: 'What is your project named?',
78
- initial: 'my-app',
79
- validate: (name) => {
80
- const validation = validateNpmName(path.basename(path.resolve(name)));
81
-
82
- if (validation.valid) {
83
- return true;
84
- }
85
-
86
- return `Invalid project name ${validation?.problems?.[0] ? validation?.problems?.[0] : ''}`;
87
- },
88
- });
89
-
90
- if (typeof res.path === 'string') {
91
- projectPath = res.path.trim();
92
- }
93
- }
94
-
95
- if (!projectPath) {
96
- console.log(
97
- '\nPlease specify the project directory:\n' +
98
- ` ${cyan(program.name())} ${green('<project-directory>')}\n` +
99
- 'For example:\n' +
100
- ` ${cyan(program.name())} ${green('my-app')}\n\n` +
101
- `Run ${cyan(`${program.name()} --help`)} to see all options.`
102
- );
103
- process.exit(1);
104
- }
105
-
106
- const resolvedProjectPath = path.resolve(projectPath);
107
-
108
- await createApp({
109
- appPath: resolvedProjectPath,
110
- });
111
- };
112
-
113
- run()
114
- .then(async () => {
115
- await notifyUpdate();
116
- })
117
- .catch(async (error) => {
118
- console.log(red(error));
119
-
120
- await notifyUpdate();
121
-
122
- process.exit(1);
123
- });
124
-
125
- export { packageName };
package/cli/create-app.ts DELETED
@@ -1,59 +0,0 @@
1
- /* eslint-disable no-console */
2
- import path from 'path';
3
-
4
- import chalk from 'chalk';
5
-
6
- import { isWriteable } from './helpers/is-writeable.js';
7
- import { makeDir } from './helpers/make-dir.js';
8
- import { isFolderEmpty } from './helpers/is-folder-empty.js';
9
- import { tryGitInit } from './helpers/git.js';
10
- import { installTemplate } from './install-template.js';
11
-
12
- interface Props {
13
- appPath: string;
14
- }
15
-
16
- const { green } = chalk;
17
-
18
- const createApp = async (model: Props) => {
19
- const { appPath } = model;
20
- const root = path.resolve(appPath);
21
-
22
- if (!(await isWriteable(path.dirname(root)))) {
23
- console.error('The application path is not writable, please check folder permissions and try again.');
24
-
25
- console.error('It is likely you do not have write permissions for this folder.');
26
-
27
- process.exit(1);
28
- }
29
-
30
- const appName = path.basename(root);
31
-
32
- await makeDir(root);
33
-
34
- if (!isFolderEmpty(root)) {
35
- console.log(`\nThe directory ${green(appName)} contains files that could conflict or not empty`);
36
- console.log('\nEither try using a new directory name, or remove these files.');
37
-
38
- process.exit(1);
39
- }
40
-
41
- console.log(`\nCreating a new app in ${green(root)}.`);
42
-
43
- process.chdir(root);
44
-
45
- await installTemplate({
46
- appName,
47
- root,
48
- });
49
-
50
- console.log('\nInitializing a git repository.');
51
-
52
- if (tryGitInit(root)) {
53
- console.log('\nInitialized a git repository.');
54
- }
55
-
56
- console.log(`\n${green('Success!')} Created ${appName} at ${appPath}`);
57
- };
58
-
59
- export { createApp };
@@ -1,61 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs/promises';
3
-
4
- import { globby } from 'globby';
5
-
6
- interface CopyOption {
7
- cwd: string;
8
- }
9
-
10
- const excludeFiles = [
11
- '.git',
12
- '.github',
13
- '.npmrc',
14
- 'bin',
15
- 'cli',
16
- 'xpack',
17
- '.vscode',
18
- '.build',
19
- 'node_modules',
20
- 'server.ts',
21
- 'prerender.ts',
22
- 'integration.ts',
23
- 'styles.ts',
24
- 'scripts.ts',
25
- 'states.ts',
26
- 'migrate-scss.ts',
27
- 'vite.config.ts',
28
- 'vite.cli.config.ts',
29
- 'src',
30
- 'public/samples',
31
- 'public/assets/vendors',
32
- ];
33
-
34
- const copy = async (src: string | string[], dest: string, { cwd }: CopyOption) => {
35
- const sourceFiles = await globby(src, {
36
- cwd,
37
- dot: true,
38
- absolute: false,
39
- gitignore: true,
40
- ignore: excludeFiles,
41
- });
42
-
43
- const destRelativeToCwd = path.resolve(dest);
44
-
45
- return Promise.all(
46
- sourceFiles.map(async (p) => {
47
- const dirname = path.dirname(p);
48
- const basename = path.basename(p);
49
-
50
- const from = path.resolve(cwd, p);
51
- const filePath = path.join(destRelativeToCwd, dirname, basename);
52
-
53
- // Ensure the destination directory exists
54
- await fs.mkdir(path.dirname(filePath), { recursive: true });
55
-
56
- return fs.copyFile(from, filePath);
57
- })
58
- );
59
- };
60
-
61
- export { copy };
@@ -1,197 +0,0 @@
1
- import path from 'path';
2
- import os from 'os';
3
- import fs from 'fs/promises';
4
-
5
- const writeFile = async (filePath: string, data: string) => {
6
- await fs.mkdir(path.dirname(filePath), { recursive: true });
7
- await fs.writeFile(filePath, data);
8
- };
9
-
10
- const formatFiles = async (root: string) => {
11
- let filePath, data;
12
-
13
- // mock handler file
14
- filePath = path.join(root, 'src/mocks/handlers.ts');
15
- data = "import { handlers } from './consts';\n\nexport { handlers };";
16
-
17
- await writeFile(filePath, data + os.EOL);
18
-
19
- // example mock file
20
- filePath = path.join(root, 'src/mocks/example/index.ts');
21
- data = `
22
- import { handlers } from '@mocks/handlers';
23
- import { rest } from 'msw';
24
-
25
- handlers.push(
26
- rest.get('/api/example', (req, res, ctx) => {
27
- return res(ctx.status(200), ctx.json({test: 'test'}));
28
- })
29
- );
30
- `;
31
-
32
- await writeFile(filePath, data + os.EOL);
33
-
34
- // react loader
35
- filePath = path.join(root, 'src/react-loader.tsx');
36
- data = [
37
- "import { lazy } from 'react';",
38
- '',
39
- 'export const blocks: { [name: string]: any } = {',
40
- "\troot: lazy(() => import('./organisms/root/Root')),",
41
- '};',
42
- '',
43
- ].join('\n');
44
-
45
- await writeFile(filePath, data);
46
-
47
- // src/_types/atoms.d.ts
48
- filePath = path.join(root, 'src/_types/atoms.d.ts');
49
-
50
- await writeFile(
51
- filePath,
52
- `
53
- import { BasedAtomicModel } from "./_general";
54
- `
55
- );
56
-
57
- // src/_types/molecules.d.d.ts
58
- filePath = path.join(root, 'src/_types/molecules.d.ts');
59
-
60
- await writeFile(
61
- filePath,
62
- `
63
- import { BasedAtomicModel } from "./_general";
64
- `
65
- );
66
-
67
- // src/_types/organisms.d.ts
68
- filePath = path.join(root, 'src/_types/organisms.d.ts');
69
-
70
- await writeFile(
71
- filePath,
72
- `
73
- import { BasedAtomicModel } from "./_general";
74
-
75
- interface FooterModel extends BasedAtomicModel {}
76
-
77
- interface HeaderModel extends BasedAtomicModel {}
78
- `
79
- );
80
-
81
- // pages/Home.tsx
82
- filePath = path.join(root, 'src/pages/Home.tsx');
83
-
84
- await writeFile(
85
- filePath,
86
- `
87
- import Template from '@templates/home/Home';
88
-
89
- const Home = () => {
90
- return <Template footer={footer} header={header} />;
91
- };
92
-
93
- export default Home;
94
- `
95
- );
96
-
97
- // templates/home/Home.tsx
98
- filePath = path.join(root, 'src/templates/home/Home.tsx');
99
-
100
- await writeFile(
101
- filePath,
102
- `
103
- import { FooterModel, HeaderModel } from '@_types/organisms';
104
- import Footer from '@organisms/footer/Footer';
105
- import Header from '@organisms/header/Header';
106
-
107
- interface Props {
108
- header?: HeaderModel;
109
- footer?: FooterModel;
110
- }
111
-
112
- const Home = (model: Props) => {
113
- const { header, footer } = model;
114
-
115
- return (
116
- <>
117
- {header && <Header {...header} />}
118
-
119
- <main>
120
- // write components here
121
- </main>
122
-
123
- <Footer {...footer} />
124
- </>
125
- );
126
- };
127
-
128
- export default Home;
129
- `
130
- );
131
-
132
- // src/organisms/header/Header.tsx
133
- filePath = path.join(root, 'src/organisms/header/Header.tsx');
134
-
135
- await writeFile(
136
- filePath,
137
- `
138
- import { getModifiers } from '@helpers/functions';
139
- import RequireCss from '@helpers/RequireCss';
140
- import { HeaderModel } from '@_types/organisms';
141
-
142
- const Header = (model: HeaderModel) => {
143
- const modifiers = getModifiers(model, 'zzz-o-header');
144
-
145
- return (
146
- <header className={modifiers}>
147
- <h2>Header</h2>
148
- <RequireCss path="b-header" />
149
- </header>
150
- );
151
- };
152
-
153
- export default Header;
154
- `
155
- );
156
-
157
- // src/organisms/header/Header.scss
158
- filePath = path.join(root, 'src/organisms/header/Header.scss');
159
-
160
- await writeFile(filePath, '');
161
-
162
- // src/organisms/footer/Footer.tsx
163
- filePath = path.join(root, 'src/organisms/footer/Footer.tsx');
164
-
165
- await writeFile(
166
- filePath,
167
- `
168
- import { getModifiers } from '@helpers/functions';
169
- import RequireCss from '@helpers/RequireCss';
170
- import { FooterModel } from '@_types/organisms';
171
-
172
- const Footer = (model: FooterModel) => {
173
- const modifiers = getModifiers(model, 'zzz-o-footer');
174
-
175
- return (
176
- <footer className={modifiers}>
177
- <h2>Footer</h2>
178
- <RequireCss path="b-footer" />
179
- </footer>
180
- );
181
- };
182
-
183
- export default Footer;
184
- `
185
- );
186
-
187
- // src/organisms/footer/Footer.scss
188
- filePath = path.join(root, 'src/organisms/footer/Footer.scss');
189
-
190
- await writeFile(filePath, '');
191
-
192
- return ['xxx'];
193
- };
194
-
195
- // formatFiles('E:\\projects\\test-x-pkg');
196
-
197
- export { formatFiles };
@@ -1,77 +0,0 @@
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 };
@@ -1,26 +0,0 @@
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 };
@@ -1,40 +0,0 @@
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 };
@@ -1,14 +0,0 @@
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 };
@@ -1,7 +0,0 @@
1
- import fs from 'fs';
2
-
3
- const makeDir = (root: string, options = { recursive: true }): Promise<string | undefined> => {
4
- return fs.promises.mkdir(root, options);
5
- };
6
-
7
- export { makeDir };
@@ -1,17 +0,0 @@
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
- }
@@ -1,72 +0,0 @@
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
- import packageJson_ from '../package.json';
13
-
14
- export const filename = fileURLToPath(import.meta.url);
15
- export const dirname = path.dirname(filename);
16
-
17
- interface Props {
18
- appName: string;
19
- root: string;
20
- }
21
-
22
- const { cyan } = chalk;
23
-
24
- const installTemplate = async (model: Props) => {
25
- const { appName, root } = model;
26
-
27
- console.log('\nInitializing project');
28
- const copySource = ['**'];
29
-
30
- await copy(copySource, root, {
31
- cwd: path.join(dirname, '..'),
32
- });
33
-
34
- await formatFiles(root);
35
-
36
- const packageJson = {
37
- name: appName,
38
- description: '',
39
- version: '0.1.0',
40
- type: 'module',
41
- private: true,
42
- scripts: {
43
- start: 'buner dev',
44
- dev: 'buner dev',
45
- serve: 'buner serve',
46
- build: 'buner build',
47
- generate: 'buner generate',
48
- eshn: 'buner eshn',
49
- inte: 'buner inte',
50
- styles: 'buner styles',
51
- prerender: 'buner prerender',
52
- },
53
- dependencies: {
54
- buner: `^${packageJson_.version}`,
55
- react: '^19.0.0',
56
- 'react-dom': '^19.0.0',
57
- 'react-router-dom': '^7.0.0',
58
- },
59
- };
60
-
61
- await fs.writeFile(path.join(root, 'package.json'), JSON.stringify(packageJson, null, 2) + os.EOL);
62
-
63
- console.log('\nInstalling dependencies:');
64
-
65
- for (const dependency in packageJson.dependencies) {
66
- console.log(`- ${cyan(dependency)}`);
67
- }
68
-
69
- await install();
70
- };
71
-
72
- export { installTemplate };