esmate 0.0.0 → 0.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/package.json +44 -11
- package/src/cli/esmate.d.ts +14 -0
- package/src/cli/esmate.js +108 -0
- package/src/cli/index.d.ts +2 -0
- package/src/cli/index.js +95 -0
- package/src/cli/modes.d.ts +3 -0
- package/src/cli/modes.js +86 -0
- package/src/cli/utils.d.ts +10 -0
- package/src/cli/utils.js +35 -0
- package/src/eslint/index.d.ts +2 -0
- package/src/eslint/index.js +2 -0
- package/src/eslint/node.d.ts +1 -0
- package/src/eslint/node.js +15 -0
- package/src/eslint/react.d.ts +1 -0
- package/src/eslint/react.js +24 -0
- package/src/eslint/shared.d.ts +5 -0
- package/src/eslint/shared.js +20 -0
- package/src/prettier/index.d.ts +2 -0
- package/src/prettier/index.js +2 -0
- package/src/prettier/shared.d.ts +2 -0
- package/src/prettier/shared.js +30 -0
- package/src/prettier/tailwind.d.ts +10 -0
- package/src/prettier/tailwind.js +4 -0
- package/src/vite/index.d.ts +2 -0
- package/src/vite/index.js +2 -0
- package/src/vite/react.d.ts +20 -0
- package/src/vite/react.js +16 -0
- package/src/cli.ts +0 -90
- package/template/package.json +0 -25
- package/tsconfig.json +0 -15
- package/tsup.config.ts +0 -11
package/package.json
CHANGED
|
@@ -1,18 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "esmate",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"bin": {
|
|
6
|
-
"esmate": "src/cli.ts"
|
|
7
|
-
},
|
|
3
|
+
"version": "0.0.1",
|
|
8
4
|
"license": "MIT",
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
"typescript": "^5.8.2"
|
|
12
|
-
},
|
|
5
|
+
"esmate": "lib",
|
|
6
|
+
"type": "module",
|
|
13
7
|
"dependencies": {
|
|
14
|
-
"tsx": "^4.19.3",
|
|
15
8
|
"@inquirer/prompts": "^7.4.1",
|
|
16
|
-
"
|
|
9
|
+
"@vitejs/plugin-react-swc": "^3.8.1",
|
|
10
|
+
"commander": "^13.1.0",
|
|
11
|
+
"concurrently": "^9.1.2",
|
|
12
|
+
"es-toolkit": "^1.34.1",
|
|
13
|
+
"eslint": "^9.24.0",
|
|
14
|
+
"eslint-config-flat-gitignore": "^2.1.0",
|
|
15
|
+
"eslint-config-prettier": "^10.1.1",
|
|
16
|
+
"eslint-plugin-prettier": "^5.2.6",
|
|
17
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
18
|
+
"eslint-plugin-react-refresh": "^0.4.19",
|
|
19
|
+
"find-up": "^7.0.0",
|
|
20
|
+
"fs-extra": "^11.3.0",
|
|
21
|
+
"globby": "^14.1.0",
|
|
22
|
+
"jiti": "^2.4.2",
|
|
23
|
+
"npm-check-updates": "^17.1.18",
|
|
24
|
+
"prettier": "^3.5.3",
|
|
25
|
+
"prettier-plugin-organize-imports": "^4.1.0",
|
|
26
|
+
"prettier-plugin-tailwindcss": "^0.6.11",
|
|
27
|
+
"typescript": "^5.8.3",
|
|
28
|
+
"typescript-eslint": "^8.29.0",
|
|
29
|
+
"vite": "^6.2.5",
|
|
30
|
+
"vite-plugin-pages": "^0.33.0",
|
|
31
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
32
|
+
"zod": "^3.24.2"
|
|
33
|
+
},
|
|
34
|
+
"bin": {
|
|
35
|
+
"esm": "src/cli/index.js"
|
|
36
|
+
},
|
|
37
|
+
"exports": {
|
|
38
|
+
"./eslint": {
|
|
39
|
+
"import": "./src/eslint/index.js",
|
|
40
|
+
"types": "./src/eslint/index.d.ts"
|
|
41
|
+
},
|
|
42
|
+
"./prettier": {
|
|
43
|
+
"import": "./src/prettier/index.js",
|
|
44
|
+
"types": "./src/prettier/index.d.ts"
|
|
45
|
+
},
|
|
46
|
+
"./vite": {
|
|
47
|
+
"import": "./src/vite/index.js",
|
|
48
|
+
"types": "./src/vite/index.d.ts"
|
|
49
|
+
}
|
|
17
50
|
}
|
|
18
51
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare class ESMate {
|
|
2
|
+
private schema;
|
|
3
|
+
private path;
|
|
4
|
+
private package;
|
|
5
|
+
private exports;
|
|
6
|
+
constructor();
|
|
7
|
+
get mode(): "app" | "lib";
|
|
8
|
+
get version(): string;
|
|
9
|
+
private write;
|
|
10
|
+
private includeFiles;
|
|
11
|
+
build(): void;
|
|
12
|
+
}
|
|
13
|
+
export declare const esmate: ESMate;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { globbySync } from 'globby';
|
|
4
|
+
import { findUpSync } from 'find-up';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
class ESMate {
|
|
7
|
+
constructor() {
|
|
8
|
+
Object.defineProperty(this, "schema", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: z.object({
|
|
13
|
+
name: z.string(),
|
|
14
|
+
version: z.string(),
|
|
15
|
+
private: z.literal(true),
|
|
16
|
+
esmate: z.enum(['app', 'lib']),
|
|
17
|
+
type: z.literal('module'),
|
|
18
|
+
main: z.undefined({ message: 'The "main" field is not needed for ESM projects.' }),
|
|
19
|
+
module: z.undefined({ message: 'The "module" field is not needed for ESM projects.' }),
|
|
20
|
+
scripts: z.record(z.string(), z.string()).optional(),
|
|
21
|
+
bin: z
|
|
22
|
+
.record(z.string(), z.string().refine((value) => fs.existsSync(value), (value) => ({
|
|
23
|
+
message: 'No file matches this bin value: ' + value,
|
|
24
|
+
})))
|
|
25
|
+
.optional(),
|
|
26
|
+
exports: z
|
|
27
|
+
.record(z.string().refine((key) => this.exports[key].replace('src/', '').startsWith(key), {
|
|
28
|
+
message: 'An export value must be prefixed by its own key.',
|
|
29
|
+
}), z
|
|
30
|
+
.string()
|
|
31
|
+
.refine((value) => !value.includes('**'), (value) => ({
|
|
32
|
+
message: 'Avoid cross-directory matching in this export value: ' + value,
|
|
33
|
+
}))
|
|
34
|
+
.refine((value) => globbySync(value).length > 0, (value) => ({
|
|
35
|
+
message: 'No file matches this export value: ' + value,
|
|
36
|
+
})))
|
|
37
|
+
.optional(),
|
|
38
|
+
files: z
|
|
39
|
+
.array(z.string().refine((value) => globbySync(value).length > 0, (value) => ({
|
|
40
|
+
message: 'No file matches this include value: ' + value,
|
|
41
|
+
})))
|
|
42
|
+
.optional(),
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(this, "path", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: findUpSync('package.json')
|
|
50
|
+
});
|
|
51
|
+
Object.defineProperty(this, "package", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
value: fs.readJSONSync(this.path)
|
|
56
|
+
});
|
|
57
|
+
Object.defineProperty(this, "exports", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: this.package.exports || {}
|
|
62
|
+
});
|
|
63
|
+
this.schema.parse(this.package);
|
|
64
|
+
}
|
|
65
|
+
get mode() {
|
|
66
|
+
return this.package.esmate;
|
|
67
|
+
}
|
|
68
|
+
get version() {
|
|
69
|
+
return this.package.version;
|
|
70
|
+
}
|
|
71
|
+
write() {
|
|
72
|
+
const { dir, base } = path.parse(this.path);
|
|
73
|
+
const newPackage = Object.assign(Object.assign({}, this.package), { files: undefined, scripts: undefined, private: undefined, devDependencies: undefined, bin: (() => {
|
|
74
|
+
const newBin = {};
|
|
75
|
+
for (const key in this.package.bin) {
|
|
76
|
+
const value = this.package.bin[key];
|
|
77
|
+
const { dir, name } = path.parse(value);
|
|
78
|
+
newBin[key] = `${dir}/${name}.js`;
|
|
79
|
+
}
|
|
80
|
+
return newBin;
|
|
81
|
+
})(), exports: (() => {
|
|
82
|
+
const newExports = {};
|
|
83
|
+
for (const key in this.package.exports) {
|
|
84
|
+
const value = this.package.exports[key];
|
|
85
|
+
const { dir, name } = path.parse(value);
|
|
86
|
+
const out = `${dir}/${name}`;
|
|
87
|
+
newExports[key] = {
|
|
88
|
+
import: out + '.js',
|
|
89
|
+
types: out + '.d.ts',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return newExports;
|
|
93
|
+
})() });
|
|
94
|
+
const newPath = path.join(dir, 'dist', base);
|
|
95
|
+
fs.ensureFileSync(newPath);
|
|
96
|
+
fs.writeJsonSync(newPath, newPackage, { spaces: 2 });
|
|
97
|
+
}
|
|
98
|
+
includeFiles() {
|
|
99
|
+
for (const filePath of globbySync(this.package.files || [])) {
|
|
100
|
+
fs.copy(filePath, path.join('dist', filePath));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
build() {
|
|
104
|
+
this.write();
|
|
105
|
+
this.includeFiles();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export const esmate = new ESMate();
|
package/src/cli/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env -S node
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import { confirm } from '@inquirer/prompts';
|
|
13
|
+
import { esmate } from './esmate.js';
|
|
14
|
+
import { app, lib } from './modes.js';
|
|
15
|
+
import { executeOne, userArgs } from './utils.js';
|
|
16
|
+
const program = new Command();
|
|
17
|
+
program
|
|
18
|
+
.name('esmate')
|
|
19
|
+
.description('Build apps and libs with TypeScript following the ECMAScript standard.')
|
|
20
|
+
.version(esmate.version)
|
|
21
|
+
.action(() => {
|
|
22
|
+
program.help();
|
|
23
|
+
});
|
|
24
|
+
program
|
|
25
|
+
.command('run')
|
|
26
|
+
.description('run a program')
|
|
27
|
+
.allowExcessArguments(true)
|
|
28
|
+
.allowUnknownOption()
|
|
29
|
+
.option('-h, --help')
|
|
30
|
+
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
yield executeOne({
|
|
32
|
+
name: 'tsx',
|
|
33
|
+
command: 'npx tsx',
|
|
34
|
+
args: userArgs,
|
|
35
|
+
prefixColor: 'blue',
|
|
36
|
+
});
|
|
37
|
+
}));
|
|
38
|
+
switch (esmate.mode) {
|
|
39
|
+
case 'app':
|
|
40
|
+
app(program);
|
|
41
|
+
break;
|
|
42
|
+
case 'lib':
|
|
43
|
+
lib(program);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
program
|
|
47
|
+
.command('lint')
|
|
48
|
+
.description('lint and format code')
|
|
49
|
+
.allowExcessArguments(true)
|
|
50
|
+
.allowUnknownOption()
|
|
51
|
+
.option('-h, --help')
|
|
52
|
+
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
yield executeOne({
|
|
54
|
+
name: 'eslint',
|
|
55
|
+
command: 'npx eslint',
|
|
56
|
+
args: [...userArgs, '.'],
|
|
57
|
+
});
|
|
58
|
+
yield executeOne({
|
|
59
|
+
name: 'prettier',
|
|
60
|
+
command: 'npx prettier',
|
|
61
|
+
args: [
|
|
62
|
+
'--log-level',
|
|
63
|
+
'warn',
|
|
64
|
+
'--ignore-unknown',
|
|
65
|
+
(() => {
|
|
66
|
+
if (userArgs.includes('--fix')) {
|
|
67
|
+
return '--write';
|
|
68
|
+
}
|
|
69
|
+
else if (userArgs.includes('--fix-dry-run')) {
|
|
70
|
+
return '--list-different';
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return '--check';
|
|
74
|
+
}
|
|
75
|
+
})(),
|
|
76
|
+
'.',
|
|
77
|
+
],
|
|
78
|
+
prefixColor: 'cyan',
|
|
79
|
+
});
|
|
80
|
+
}));
|
|
81
|
+
program
|
|
82
|
+
.command('update')
|
|
83
|
+
.description('check and update packages')
|
|
84
|
+
.allowExcessArguments(true)
|
|
85
|
+
.allowUnknownOption()
|
|
86
|
+
.option('-h, --help')
|
|
87
|
+
.action((script) => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
+
let answer = yield confirm({ message: 'Do you want to update to the latest packages?', default: false });
|
|
89
|
+
executeOne({
|
|
90
|
+
name: 'ncu',
|
|
91
|
+
command: 'ncu',
|
|
92
|
+
args: ['--interactive', '--target', answer ? 'semver' : 'latest'],
|
|
93
|
+
});
|
|
94
|
+
}));
|
|
95
|
+
program.parse(process.argv);
|
package/src/cli/modes.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { executeMany, executeOne, userArgs } from './utils.js';
|
|
11
|
+
import { esmate } from './esmate.js';
|
|
12
|
+
export function app(program) {
|
|
13
|
+
program
|
|
14
|
+
.command('dev')
|
|
15
|
+
.description('start dev server')
|
|
16
|
+
.allowExcessArguments(true)
|
|
17
|
+
.allowUnknownOption()
|
|
18
|
+
.option('-h, --help')
|
|
19
|
+
.action(() => __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
yield executeMany([
|
|
21
|
+
{
|
|
22
|
+
name: 'vite',
|
|
23
|
+
command: 'npx vite',
|
|
24
|
+
args: userArgs,
|
|
25
|
+
prefixColor: 'cyan',
|
|
26
|
+
},
|
|
27
|
+
]);
|
|
28
|
+
// https://www.npmjs.com/package/glob-watcher
|
|
29
|
+
// watch files to fix and format
|
|
30
|
+
}));
|
|
31
|
+
program
|
|
32
|
+
.command('build')
|
|
33
|
+
.description('build for production')
|
|
34
|
+
.allowExcessArguments(true)
|
|
35
|
+
.allowUnknownOption()
|
|
36
|
+
.option('-h, --help')
|
|
37
|
+
.action(() => __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
yield executeOne({
|
|
39
|
+
name: 'typescript',
|
|
40
|
+
command: 'npx tsc --noEmit',
|
|
41
|
+
args: [],
|
|
42
|
+
prefixColor: 'blue',
|
|
43
|
+
});
|
|
44
|
+
yield executeOne({
|
|
45
|
+
name: 'vite',
|
|
46
|
+
command: 'npx vite build',
|
|
47
|
+
args: [...userArgs, '--emptyOutDir'],
|
|
48
|
+
prefixColor: 'cyan',
|
|
49
|
+
});
|
|
50
|
+
}));
|
|
51
|
+
program
|
|
52
|
+
.command('start')
|
|
53
|
+
.description('serve production build')
|
|
54
|
+
.allowExcessArguments(true)
|
|
55
|
+
.allowUnknownOption()
|
|
56
|
+
.option('-h, --help')
|
|
57
|
+
.action(() => __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
yield executeOne({
|
|
59
|
+
name: 'vite',
|
|
60
|
+
command: 'npx vite preview',
|
|
61
|
+
args: userArgs,
|
|
62
|
+
prefixColor: 'cyan',
|
|
63
|
+
});
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
export function lib(program) {
|
|
67
|
+
program
|
|
68
|
+
.command('dev')
|
|
69
|
+
.description('watch and build')
|
|
70
|
+
.allowExcessArguments(true)
|
|
71
|
+
.allowUnknownOption()
|
|
72
|
+
.option('-h, --help')
|
|
73
|
+
.action(() => __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
esmate.build();
|
|
75
|
+
yield executeMany([
|
|
76
|
+
{
|
|
77
|
+
name: 'typescript',
|
|
78
|
+
command: 'npx tsc --watch',
|
|
79
|
+
args: [],
|
|
80
|
+
prefixColor: 'blue',
|
|
81
|
+
},
|
|
82
|
+
]);
|
|
83
|
+
// https://www.npmjs.com/package/glob-watcher
|
|
84
|
+
// watch files to fix and format
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Command {
|
|
2
|
+
name: string;
|
|
3
|
+
command: string;
|
|
4
|
+
args: string[];
|
|
5
|
+
prefixColor?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const userArgs: string[];
|
|
8
|
+
export declare function executeOne(command: Command): Promise<void>;
|
|
9
|
+
export declare function executeMany(commands: Command[]): Promise<void>;
|
|
10
|
+
export {};
|
package/src/cli/utils.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import concurrently from 'concurrently';
|
|
11
|
+
import { spawnSync } from 'node:child_process';
|
|
12
|
+
export const userArgs = process.argv.slice(3);
|
|
13
|
+
export function executeOne(command) {
|
|
14
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
spawnSync(command.command, command.args, {
|
|
16
|
+
cwd: process.cwd(),
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
shell: true,
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function executeMany(commands) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
commands = commands.map((cmd) => {
|
|
25
|
+
const args = ' ' + cmd.args.map((arg) => arg.trim()).join(' ');
|
|
26
|
+
const command = cmd.command.trim() + args;
|
|
27
|
+
return Object.assign(Object.assign({}, cmd), { command, cwd: process.cwd() });
|
|
28
|
+
});
|
|
29
|
+
yield concurrently(commands, {
|
|
30
|
+
killOthers: ['failure', 'success'],
|
|
31
|
+
})
|
|
32
|
+
.result.then(() => { })
|
|
33
|
+
.catch(() => { });
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function node(): import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import globals from 'globals';
|
|
2
|
+
import javaScript from '@eslint/js';
|
|
3
|
+
import typeScript from 'typescript-eslint';
|
|
4
|
+
import gitIgnore from 'eslint-config-flat-gitignore';
|
|
5
|
+
import { prettier } from './shared.js';
|
|
6
|
+
import { defineConfig, languageOptions } from './shared.js';
|
|
7
|
+
export function node() {
|
|
8
|
+
return defineConfig([
|
|
9
|
+
{
|
|
10
|
+
files: ['**/*.?(c|m)[jt]s?(x)'],
|
|
11
|
+
languageOptions: Object.assign(Object.assign({}, languageOptions), { globals: globals.node }),
|
|
12
|
+
extends: [gitIgnore(), javaScript.configs.recommended, ...typeScript.configs.recommended, prettier()],
|
|
13
|
+
},
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function react(): import("eslint").Linter.Config<import("eslint").Linter.RulesRecord>[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import globals from 'globals';
|
|
2
|
+
import javaScript from '@eslint/js';
|
|
3
|
+
import typeScript from 'typescript-eslint';
|
|
4
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
5
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
6
|
+
import gitIgnore from 'eslint-config-flat-gitignore';
|
|
7
|
+
import { prettier } from './shared.js';
|
|
8
|
+
import { defineConfig, languageOptions } from './shared.js';
|
|
9
|
+
export function react() {
|
|
10
|
+
return defineConfig([
|
|
11
|
+
{
|
|
12
|
+
files: ['**/*.?(c|m)[jt]s?(x)'],
|
|
13
|
+
languageOptions: Object.assign(Object.assign({}, languageOptions), { globals: globals.browser }),
|
|
14
|
+
extends: [
|
|
15
|
+
gitIgnore(),
|
|
16
|
+
javaScript.configs.recommended,
|
|
17
|
+
...typeScript.configs.recommended,
|
|
18
|
+
reactHooks.configs['recommended-latest'],
|
|
19
|
+
reactRefresh.configs.vite,
|
|
20
|
+
prettier(),
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import prettierPlugin from 'eslint-plugin-prettier';
|
|
3
|
+
import prettierConfig from 'eslint-config-prettier';
|
|
4
|
+
export { defineConfig };
|
|
5
|
+
export function prettier() {
|
|
6
|
+
return defineConfig([
|
|
7
|
+
{
|
|
8
|
+
plugins: {
|
|
9
|
+
prettier: prettierPlugin,
|
|
10
|
+
},
|
|
11
|
+
extends: [prettierConfig],
|
|
12
|
+
rules: {
|
|
13
|
+
'prettier/prettier': ['warn'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
18
|
+
export const languageOptions = {
|
|
19
|
+
ecmaVersion: 2020,
|
|
20
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { uniq } from 'es-toolkit';
|
|
2
|
+
export function defineConfig(configs) {
|
|
3
|
+
const defaultConfig = {
|
|
4
|
+
tabWidth: 2,
|
|
5
|
+
semi: true,
|
|
6
|
+
printWidth: 120,
|
|
7
|
+
singleQuote: true,
|
|
8
|
+
trailingComma: 'es5',
|
|
9
|
+
plugins: ['prettier-plugin-organize-imports'],
|
|
10
|
+
};
|
|
11
|
+
for (const config of configs) {
|
|
12
|
+
for (const key in config) {
|
|
13
|
+
const value = config[key];
|
|
14
|
+
if (key === 'plugins') {
|
|
15
|
+
const plugins = defaultConfig.plugins || [];
|
|
16
|
+
defaultConfig.plugins = uniq([...plugins, ...value]);
|
|
17
|
+
}
|
|
18
|
+
// if (isJSONArray(value)) {
|
|
19
|
+
// const array = (defaultConfig[key] as undefined) || [];
|
|
20
|
+
// defaultConfig[key] = uniq([...array, ...value]);
|
|
21
|
+
// } else if (isJSONObject(value)) {
|
|
22
|
+
// const object = (defaultConfig[key] as undefined) || {};
|
|
23
|
+
// defaultConfig[key] = { ...object, ...value };
|
|
24
|
+
// } else {
|
|
25
|
+
// defaultConfig[key] = value;
|
|
26
|
+
// }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return defaultConfig;
|
|
30
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Options {
|
|
2
|
+
tailwindFunctions: string[];
|
|
3
|
+
tailwindConfig?: string;
|
|
4
|
+
tailwindStylesheet?: string;
|
|
5
|
+
tailwindAttributes?: string[];
|
|
6
|
+
tailwindPreserveWhitespace?: boolean;
|
|
7
|
+
tailwindPreserveDuplicates?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function tailwind(options: Options): import("prettier").Config;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import pages from 'vite-plugin-pages';
|
|
2
|
+
import paths from 'vite-tsconfig-paths';
|
|
3
|
+
import react from '@vitejs/plugin-react-swc';
|
|
4
|
+
interface SpaOptions {
|
|
5
|
+
react: Parameters<typeof react>[0];
|
|
6
|
+
pages: Parameters<typeof pages>[0];
|
|
7
|
+
paths: Parameters<typeof paths>[0];
|
|
8
|
+
}
|
|
9
|
+
export declare function spa(options?: SpaOptions): {
|
|
10
|
+
name: string;
|
|
11
|
+
config: () => {
|
|
12
|
+
root: string;
|
|
13
|
+
build: {
|
|
14
|
+
outDir: string;
|
|
15
|
+
};
|
|
16
|
+
plugins: (import("vite").Plugin<any> | import("vite").PluginOption[])[];
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare function lib(): {};
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pages from 'vite-plugin-pages';
|
|
2
|
+
import paths from 'vite-tsconfig-paths';
|
|
3
|
+
import react from '@vitejs/plugin-react-swc';
|
|
4
|
+
export function spa(options) {
|
|
5
|
+
return {
|
|
6
|
+
name: 'react-app',
|
|
7
|
+
config: () => ({
|
|
8
|
+
root: './src',
|
|
9
|
+
build: { outDir: '../dist' },
|
|
10
|
+
plugins: [paths(options === null || options === void 0 ? void 0 : options.paths), pages(options === null || options === void 0 ? void 0 : options.pages), react(options === null || options === void 0 ? void 0 : options.react)],
|
|
11
|
+
}),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function lib() {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
package/src/cli.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env -S tsx
|
|
2
|
-
|
|
3
|
-
import { confirm } from '@inquirer/prompts';
|
|
4
|
-
import { spawnSync } from 'node:child_process';
|
|
5
|
-
|
|
6
|
-
type Command = 'dev' | 'build' | 'start' | 'test' | 'lint' | 'update';
|
|
7
|
-
type Commands = Record<Command, { description: string; action: () => void }>;
|
|
8
|
-
|
|
9
|
-
const args = process.argv.slice(3);
|
|
10
|
-
const command: Command = process.argv[2] as any;
|
|
11
|
-
|
|
12
|
-
function exec(command: string, args: string[] = []) {
|
|
13
|
-
// console.log(`> ${command} ${args.join(' ')}`);
|
|
14
|
-
|
|
15
|
-
spawnSync(command, [...args], { cwd: process.cwd(), stdio: 'inherit', shell: true });
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const commands: Commands = {
|
|
19
|
-
dev: {
|
|
20
|
-
description: 'start dev server',
|
|
21
|
-
action: () => {
|
|
22
|
-
exec('vite', [...args]);
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
build: {
|
|
26
|
-
description: 'build for production',
|
|
27
|
-
action: () => {
|
|
28
|
-
exec('tsc --noEmit');
|
|
29
|
-
exec('tsup', [...args]);
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
start: {
|
|
33
|
-
description: 'serve production build',
|
|
34
|
-
action: () => {
|
|
35
|
-
exec('vite', ['preview', ...args]);
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
lint: {
|
|
39
|
-
description: 'lint and format code',
|
|
40
|
-
action: () => {
|
|
41
|
-
const include = (yes: boolean) => `'${(yes ? '' : '!') + '**/*.?(c|m)[jt]s?(x)'}'`;
|
|
42
|
-
|
|
43
|
-
exec('eslint', ['--ignore-path', '.gitignore', ...args, include(true)]);
|
|
44
|
-
|
|
45
|
-
let fmtArg = '';
|
|
46
|
-
|
|
47
|
-
if (args.includes('--fix')) {
|
|
48
|
-
fmtArg = '--write';
|
|
49
|
-
} else if (args.includes('--fix-dry-run')) {
|
|
50
|
-
fmtArg = '--list-different';
|
|
51
|
-
} else {
|
|
52
|
-
fmtArg = '--check';
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
exec('prettier', ['--log-level', 'warn', fmtArg, '.', include(false)]);
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
test: {
|
|
59
|
-
description: 'start test runner',
|
|
60
|
-
action: () => {
|
|
61
|
-
exec('vitest', [...args]);
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
update: {
|
|
65
|
-
description: 'check and update packages',
|
|
66
|
-
action: async () => {
|
|
67
|
-
let answer = await confirm({ message: 'Yes to update safely or No to update to the latest:' });
|
|
68
|
-
|
|
69
|
-
exec('ncu', ['--interactive', '--target', answer ? 'semver' : 'latest']);
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
// cover: {
|
|
73
|
-
// description: 'print coverage reports',
|
|
74
|
-
// action: () => {
|
|
75
|
-
// exec('vitest', ['run', '--coverage', ...args]);
|
|
76
|
-
// },
|
|
77
|
-
// },
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
if (commands[command]) {
|
|
81
|
-
commands[command].action();
|
|
82
|
-
} else {
|
|
83
|
-
console.log('A tool for building single-page apps.\n');
|
|
84
|
-
|
|
85
|
-
for (const [command, { description }] of Object.entries(commands)) {
|
|
86
|
-
console.log(`spa ${command.padEnd(7, ' ')} ${description}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
console.log('\nDocs: https://create-spa-app.deno.dev/');
|
|
90
|
-
}
|
package/template/package.json
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "esmate",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"exports": {
|
|
7
|
-
".": {
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"import": "./dist/index.js"
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
"module": "./dist/index.js",
|
|
13
|
-
"types": "./dist/index.d.ts",
|
|
14
|
-
"files": [
|
|
15
|
-
"dist"
|
|
16
|
-
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"dev": "tsup --watch",
|
|
19
|
-
"build": "tsup"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@types/node": "^22.14.0",
|
|
23
|
-
"typescript": "^5.8.2"
|
|
24
|
-
}
|
|
25
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"lib": ["ES2021"],
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"noEmit": true,
|
|
6
|
-
"strict": true,
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"isolatedModules": true,
|
|
9
|
-
"resolveJsonModule": true,
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"useDefineForClassFields": true,
|
|
12
|
-
"allowImportingTsExtensions": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src"]
|
|
15
|
-
}
|