@coze-arch/cli 0.0.6-alpha.43776c → 0.0.6-alpha.dd6b66
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/lib/__templates__/taro/eslint.config.mjs +52 -2
- package/lib/cli.js +194 -51
- package/package.json +1 -1
- package/lib/__templates__/taro/components.md +0 -1686
|
@@ -123,14 +123,64 @@ export default [
|
|
|
123
123
|
},
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
|
-
files: ['src/pages/
|
|
126
|
+
files: ['src/pages/index/index.tsx'],
|
|
127
127
|
rules: {
|
|
128
128
|
'no-restricted-syntax': [
|
|
129
129
|
'error',
|
|
130
130
|
{
|
|
131
131
|
selector: 'JSXText[value=/应用开发中/]',
|
|
132
132
|
message:
|
|
133
|
-
'工程规范:检测到首页 (src/pages/
|
|
133
|
+
'工程规范:检测到首页 (src/pages/index/index.tsx) 仍为默认占位页面,这会导致用户无法进入新增页面,请根据用户需求开发实际的首页功能 and 界面。如果已经开发了新的首页,也需要删除旧首页,并更新 src/app.config.ts 文件',
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
files: ['src/pages/**/*.tsx'],
|
|
140
|
+
rules: {
|
|
141
|
+
'no-restricted-syntax': [
|
|
142
|
+
'error',
|
|
143
|
+
{
|
|
144
|
+
selector:
|
|
145
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Button']",
|
|
146
|
+
message:
|
|
147
|
+
"组件规范:Button 优先使用 '@/components/ui/button',不要在页面中直接使用 '@tarojs/components' 的 Button。",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
selector:
|
|
151
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Input']",
|
|
152
|
+
message:
|
|
153
|
+
"组件规范:Input 优先使用 '@/components/ui/input',不要在页面中直接使用 '@tarojs/components' 的 Input。",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
selector:
|
|
157
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Textarea']",
|
|
158
|
+
message:
|
|
159
|
+
"组件规范:Textarea 优先使用 '@/components/ui/textarea',不要在页面中直接使用 '@tarojs/components' 的 Textarea。",
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
selector:
|
|
163
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Label']",
|
|
164
|
+
message:
|
|
165
|
+
"组件规范:Label 优先使用 '@/components/ui/label',不要在页面中直接使用 '@tarojs/components' 的 Label。",
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
selector:
|
|
169
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Switch']",
|
|
170
|
+
message:
|
|
171
|
+
"组件规范:Switch 优先使用 '@/components/ui/switch',不要在页面中直接使用 '@tarojs/components' 的 Switch。",
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
selector:
|
|
175
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Slider']",
|
|
176
|
+
message:
|
|
177
|
+
"组件规范:Slider 优先使用 '@/components/ui/slider',不要在页面中直接使用 '@tarojs/components' 的 Slider。",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
selector:
|
|
181
|
+
"ImportDeclaration[source.value='@tarojs/components'] ImportSpecifier[imported.name='Progress']",
|
|
182
|
+
message:
|
|
183
|
+
"组件规范:Progress 优先使用 '@/components/ui/progress',不要在页面中直接使用 '@tarojs/components' 的 Progress。",
|
|
134
184
|
},
|
|
135
185
|
],
|
|
136
186
|
},
|
package/lib/cli.js
CHANGED
|
@@ -2106,7 +2106,7 @@ const EventBuilder = {
|
|
|
2106
2106
|
};
|
|
2107
2107
|
|
|
2108
2108
|
var name = "@coze-arch/cli";
|
|
2109
|
-
var version = "0.0.6-alpha.
|
|
2109
|
+
var version = "0.0.6-alpha.dd6b66";
|
|
2110
2110
|
var description = "coze coding devtools cli";
|
|
2111
2111
|
var license = "MIT";
|
|
2112
2112
|
var author = "fanwenjie.fe@bytedance.com";
|
|
@@ -3946,9 +3946,10 @@ const log$4 = debug('coze:routes:nuxt');
|
|
|
3946
3946
|
/**
|
|
3947
3947
|
* Convert Nuxt file path to route path
|
|
3948
3948
|
* Examples:
|
|
3949
|
-
* - app/pages/index.vue -> /
|
|
3950
3949
|
* - pages/index.vue -> /
|
|
3951
|
-
* - app/pages/
|
|
3950
|
+
* - app/pages/index.vue -> /
|
|
3951
|
+
* - src/pages/index.vue -> /
|
|
3952
|
+
* - src/app/pages/index.vue -> /
|
|
3952
3953
|
* - pages/blog/[id].vue -> /blog/[id]
|
|
3953
3954
|
* - server/api/users.ts -> /api/users
|
|
3954
3955
|
* - server/routes/webhook.ts -> /webhook
|
|
@@ -3960,10 +3961,12 @@ const nuxtFilePathToRoute = (
|
|
|
3960
3961
|
let route;
|
|
3961
3962
|
|
|
3962
3963
|
if (type === 'page') {
|
|
3963
|
-
// Remove pages prefix (supports
|
|
3964
|
+
// Remove pages prefix (supports all variations) and .vue extension
|
|
3964
3965
|
route = filePath
|
|
3965
|
-
.replace(/^app\/pages\//, '')
|
|
3966
|
-
.replace(/^pages\//, '')
|
|
3966
|
+
.replace(/^src\/app\/pages\//, '') // src/app/pages/
|
|
3967
|
+
.replace(/^src\/pages\//, '') // src/pages/
|
|
3968
|
+
.replace(/^app\/pages\//, '') // app/pages/
|
|
3969
|
+
.replace(/^pages\//, '') // pages/
|
|
3967
3970
|
.replace(/\.vue$/, '')
|
|
3968
3971
|
.replace(/\/index$/, ''); // Remove trailing /index
|
|
3969
3972
|
|
|
@@ -3972,14 +3975,16 @@ const nuxtFilePathToRoute = (
|
|
|
3972
3975
|
return '/';
|
|
3973
3976
|
}
|
|
3974
3977
|
} else {
|
|
3975
|
-
// API routes
|
|
3976
|
-
if (filePath.
|
|
3978
|
+
// API routes - support both server/ and src/server/
|
|
3979
|
+
if (filePath.includes('/api/')) {
|
|
3977
3980
|
route = `/api/${filePath
|
|
3981
|
+
.replace(/^src\/server\/api\//, '')
|
|
3978
3982
|
.replace(/^server\/api\//, '')
|
|
3979
3983
|
.replace(/\.(ts|js)$/, '')}`;
|
|
3980
3984
|
} else {
|
|
3981
|
-
// server/routes
|
|
3985
|
+
// server/routes - support both server/ and src/server/
|
|
3982
3986
|
route = `/${filePath
|
|
3987
|
+
.replace(/^src\/server\/routes\//, '')
|
|
3983
3988
|
.replace(/^server\/routes\//, '')
|
|
3984
3989
|
.replace(/\.(ts|js)$/, '')}`;
|
|
3985
3990
|
}
|
|
@@ -4031,13 +4036,23 @@ const extractParams$1 = (routePath) => {
|
|
|
4031
4036
|
/**
|
|
4032
4037
|
* Scan Nuxt routes from pages and server directories
|
|
4033
4038
|
*
|
|
4034
|
-
*
|
|
4035
|
-
* -
|
|
4036
|
-
*
|
|
4037
|
-
*
|
|
4039
|
+
* Supports multiple directory structures:
|
|
4040
|
+
* - **Page routes**:
|
|
4041
|
+
* - pages/**\/*.vue (default)
|
|
4042
|
+
* - app/pages/**\/*.vue (Nuxt 3 app directory)
|
|
4043
|
+
* - src/pages/**\/*.vue (srcDir: 'src/')
|
|
4044
|
+
* - src/app/pages/**\/*.vue (srcDir: 'src/' + app directory)
|
|
4045
|
+
*
|
|
4046
|
+
* - **API routes**:
|
|
4047
|
+
* - server/api/**\/*.{ts,js} (default)
|
|
4048
|
+
* - src/server/api/**\/*.{ts,js} (srcDir: 'src/')
|
|
4049
|
+
*
|
|
4050
|
+
* - **Server routes**:
|
|
4051
|
+
* - server/routes/**\/*.{ts,js} (default)
|
|
4052
|
+
* - src/server/routes/**\/*.{ts,js} (srcDir: 'src/')
|
|
4038
4053
|
*
|
|
4039
4054
|
* Excludes:
|
|
4040
|
-
* -
|
|
4055
|
+
* - layouts/ directories - Layout components (NOT routes)
|
|
4041
4056
|
* - app.vue, error.vue - Special files (NOT regular routes)
|
|
4042
4057
|
*
|
|
4043
4058
|
* @param cwd - Current working directory
|
|
@@ -4047,24 +4062,35 @@ const scanNuxtRoutes = async (cwd) => {
|
|
|
4047
4062
|
log$4('Scanning Nuxt routes in:', cwd);
|
|
4048
4063
|
const routes = [];
|
|
4049
4064
|
|
|
4050
|
-
// Scan page routes - support
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4065
|
+
// Scan page routes - support multiple directory structures:
|
|
4066
|
+
// - pages/ (default)
|
|
4067
|
+
// - app/pages/ (Nuxt 3 app directory)
|
|
4068
|
+
// - src/pages/ (srcDir: 'src/')
|
|
4069
|
+
// - src/app/pages/ (srcDir: 'src/' + app directory)
|
|
4070
|
+
const pageFiles = await fastGlob.glob(
|
|
4071
|
+
['{pages,app/pages,src/pages,src/app/pages}/**/*.vue'],
|
|
4072
|
+
{
|
|
4073
|
+
cwd,
|
|
4074
|
+
ignore: [
|
|
4075
|
+
'**/node_modules/**',
|
|
4076
|
+
'**/.nuxt/**',
|
|
4077
|
+
'**/dist/**',
|
|
4078
|
+
'**/.output/**',
|
|
4079
|
+
// Exclude layouts directory (not routes)
|
|
4080
|
+
'**/layouts/**',
|
|
4081
|
+
'app/layouts/**',
|
|
4082
|
+
'src/layouts/**',
|
|
4083
|
+
'src/app/layouts/**',
|
|
4084
|
+
// Exclude special files
|
|
4085
|
+
'app.vue',
|
|
4086
|
+
'error.vue',
|
|
4087
|
+
'src/app.vue',
|
|
4088
|
+
'src/error.vue',
|
|
4089
|
+
],
|
|
4090
|
+
onlyFiles: true,
|
|
4091
|
+
followSymbolicLinks: false,
|
|
4092
|
+
},
|
|
4093
|
+
);
|
|
4068
4094
|
|
|
4069
4095
|
log$4('Found %d page files', pageFiles.length);
|
|
4070
4096
|
|
|
@@ -4086,8 +4112,8 @@ const scanNuxtRoutes = async (cwd) => {
|
|
|
4086
4112
|
}),
|
|
4087
4113
|
);
|
|
4088
4114
|
|
|
4089
|
-
// Scan API routes
|
|
4090
|
-
const apiFiles = await fastGlob.glob('server/api/**/*.{ts,js}', {
|
|
4115
|
+
// Scan API routes - support both server/ and src/server/
|
|
4116
|
+
const apiFiles = await fastGlob.glob('{server,src/server}/api/**/*.{ts,js}', {
|
|
4091
4117
|
cwd,
|
|
4092
4118
|
ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
|
|
4093
4119
|
onlyFiles: true,
|
|
@@ -4114,13 +4140,16 @@ const scanNuxtRoutes = async (cwd) => {
|
|
|
4114
4140
|
}),
|
|
4115
4141
|
);
|
|
4116
4142
|
|
|
4117
|
-
// Scan server routes
|
|
4118
|
-
const serverRouteFiles = await fastGlob.glob(
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4143
|
+
// Scan server routes - support both server/ and src/server/
|
|
4144
|
+
const serverRouteFiles = await fastGlob.glob(
|
|
4145
|
+
'{server,src/server}/routes/**/*.{ts,js}',
|
|
4146
|
+
{
|
|
4147
|
+
cwd,
|
|
4148
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
|
|
4149
|
+
onlyFiles: true,
|
|
4150
|
+
followSymbolicLinks: false,
|
|
4151
|
+
},
|
|
4152
|
+
);
|
|
4124
4153
|
|
|
4125
4154
|
log$4('Found %d server route files', serverRouteFiles.length);
|
|
4126
4155
|
|
|
@@ -4226,22 +4255,18 @@ const getRouteType = (filePath) => {
|
|
|
4226
4255
|
};
|
|
4227
4256
|
|
|
4228
4257
|
/**
|
|
4229
|
-
* Scan Next.js routes from src/app directory
|
|
4258
|
+
* Scan Next.js App Router routes from app/ or src/app/ directory
|
|
4230
4259
|
*
|
|
4231
4260
|
* Scans for:
|
|
4232
4261
|
* - page.tsx/jsx/ts/js - Page routes
|
|
4233
4262
|
* - route.ts/js - API routes
|
|
4234
4263
|
*
|
|
4235
4264
|
* Note: layout.tsx, loading.tsx, error.tsx are NOT routes, they are UI components
|
|
4236
|
-
*
|
|
4237
|
-
* @param cwd - Current working directory
|
|
4238
|
-
* @returns List of detected routes
|
|
4239
4265
|
*/
|
|
4240
|
-
const
|
|
4241
|
-
log$3('Scanning
|
|
4266
|
+
const scanAppRouter = async (cwd) => {
|
|
4267
|
+
log$3('Scanning App Router routes');
|
|
4242
4268
|
|
|
4243
|
-
|
|
4244
|
-
const files = await fastGlob.glob('src/app/**/{page,route}.{tsx,ts,jsx,js}', {
|
|
4269
|
+
const files = await fastGlob.glob('{app,src/app}/**/{page,route}.{tsx,ts,jsx,js}', {
|
|
4245
4270
|
cwd,
|
|
4246
4271
|
ignore: [
|
|
4247
4272
|
'**/node_modules/**',
|
|
@@ -4254,10 +4279,9 @@ const scanNextjsRoutes = async (cwd) => {
|
|
|
4254
4279
|
followSymbolicLinks: false,
|
|
4255
4280
|
});
|
|
4256
4281
|
|
|
4257
|
-
log$3('Found %d files', files.length);
|
|
4282
|
+
log$3('Found %d App Router files', files.length);
|
|
4258
4283
|
|
|
4259
4284
|
return files.map(file => {
|
|
4260
|
-
log$3('Processing file:', file);
|
|
4261
4285
|
const routePath = filePathToRoute(file);
|
|
4262
4286
|
const isDynamic = routePath.includes('[');
|
|
4263
4287
|
const params = extractParams(routePath);
|
|
@@ -4274,6 +4298,125 @@ const scanNextjsRoutes = async (cwd) => {
|
|
|
4274
4298
|
});
|
|
4275
4299
|
};
|
|
4276
4300
|
|
|
4301
|
+
/**
|
|
4302
|
+
* Convert Pages Router file path to route path
|
|
4303
|
+
* Examples:
|
|
4304
|
+
* - pages/index.tsx -> /
|
|
4305
|
+
* - src/pages/index.tsx -> /
|
|
4306
|
+
* - pages/blog/[id].tsx -> /blog/[id]
|
|
4307
|
+
* - pages/api/users.ts -> /api/users
|
|
4308
|
+
*/
|
|
4309
|
+
const pagesFilePathToRoute = (filePath) => {
|
|
4310
|
+
// Remove pages prefix and file extension
|
|
4311
|
+
let route = filePath
|
|
4312
|
+
.replace(/^src\/pages\//, '')
|
|
4313
|
+
.replace(/^pages\//, '')
|
|
4314
|
+
.replace(/\.(tsx?|jsx?)$/, '')
|
|
4315
|
+
.replace(/\/index$/, ''); // pages/blog/index.tsx -> /blog
|
|
4316
|
+
|
|
4317
|
+
// Handle root index
|
|
4318
|
+
if (route === 'index' || route === '') {
|
|
4319
|
+
return '/';
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
// Ensure leading slash
|
|
4323
|
+
if (!route.startsWith('/')) {
|
|
4324
|
+
route = `/${route}`;
|
|
4325
|
+
}
|
|
4326
|
+
|
|
4327
|
+
return route;
|
|
4328
|
+
};
|
|
4329
|
+
|
|
4330
|
+
/**
|
|
4331
|
+
* Determine if a Pages Router file is an API route
|
|
4332
|
+
*/
|
|
4333
|
+
const isPagesApiRoute = (filePath) =>
|
|
4334
|
+
filePath.includes('/api/') || !!filePath.match(/\/(pages|src\/pages)\/api\//);
|
|
4335
|
+
|
|
4336
|
+
/**
|
|
4337
|
+
* Scan Next.js Pages Router routes from pages/ or src/pages/ directory
|
|
4338
|
+
*
|
|
4339
|
+
* Scans for:
|
|
4340
|
+
* - pages/**\/*.tsx/jsx/ts/js - Page routes
|
|
4341
|
+
* - pages/api/**\/*.ts/js - API routes
|
|
4342
|
+
*
|
|
4343
|
+
* Note: _app.tsx, _document.tsx, _error.tsx are special files, NOT routes
|
|
4344
|
+
*/
|
|
4345
|
+
const scanPagesRouter = async (cwd) => {
|
|
4346
|
+
log$3('Scanning Pages Router routes');
|
|
4347
|
+
|
|
4348
|
+
const files = await fastGlob.glob('{pages,src/pages}/**/*.{tsx,ts,jsx,js}', {
|
|
4349
|
+
cwd,
|
|
4350
|
+
ignore: [
|
|
4351
|
+
'**/node_modules/**',
|
|
4352
|
+
'**/.next/**',
|
|
4353
|
+
'**/dist/**',
|
|
4354
|
+
'**/build/**',
|
|
4355
|
+
'**/.turbo/**',
|
|
4356
|
+
// Exclude special Next.js files (these are NOT routes)
|
|
4357
|
+
'**/_app.{tsx,ts,jsx,js}',
|
|
4358
|
+
'**/_document.{tsx,ts,jsx,js}',
|
|
4359
|
+
'**/_error.{tsx,ts,jsx,js}',
|
|
4360
|
+
'**/middleware.{ts,js}',
|
|
4361
|
+
],
|
|
4362
|
+
onlyFiles: true,
|
|
4363
|
+
followSymbolicLinks: false,
|
|
4364
|
+
});
|
|
4365
|
+
|
|
4366
|
+
log$3('Found %d Pages Router files', files.length);
|
|
4367
|
+
|
|
4368
|
+
return files.map(file => {
|
|
4369
|
+
const routePath = pagesFilePathToRoute(file);
|
|
4370
|
+
const isDynamic = routePath.includes('[');
|
|
4371
|
+
const params = extractParams(routePath);
|
|
4372
|
+
|
|
4373
|
+
return {
|
|
4374
|
+
path: normalizeRoutePath(routePath),
|
|
4375
|
+
rawPath: routePath,
|
|
4376
|
+
dynamic: isDynamic,
|
|
4377
|
+
params,
|
|
4378
|
+
type: isPagesApiRoute(file) ? 'api' : 'page',
|
|
4379
|
+
file,
|
|
4380
|
+
framework: 'nextjs',
|
|
4381
|
+
};
|
|
4382
|
+
});
|
|
4383
|
+
};
|
|
4384
|
+
|
|
4385
|
+
/**
|
|
4386
|
+
* Scan Next.js routes - supports both App Router and Pages Router
|
|
4387
|
+
*
|
|
4388
|
+
* Next.js supports two routing systems that can coexist:
|
|
4389
|
+
* 1. **App Router** (Next.js 13+): app/ or src/app/
|
|
4390
|
+
* - page.tsx/jsx/ts/js - Page routes
|
|
4391
|
+
* - route.ts/js - API routes
|
|
4392
|
+
*
|
|
4393
|
+
* 2. **Pages Router** (Traditional): pages/ or src/pages/
|
|
4394
|
+
* - **\/*.tsx/jsx/ts/js - Page routes
|
|
4395
|
+
* - api/**\/*.ts/js - API routes
|
|
4396
|
+
*
|
|
4397
|
+
* @param cwd - Current working directory
|
|
4398
|
+
* @returns List of detected routes from both routing systems
|
|
4399
|
+
*/
|
|
4400
|
+
const scanNextjsRoutes = async (cwd) => {
|
|
4401
|
+
log$3('Scanning Next.js routes in:', cwd);
|
|
4402
|
+
|
|
4403
|
+
// Scan both routing systems in parallel
|
|
4404
|
+
const [appRoutes, pagesRoutes] = await Promise.all([
|
|
4405
|
+
scanAppRouter(cwd),
|
|
4406
|
+
scanPagesRouter(cwd),
|
|
4407
|
+
]);
|
|
4408
|
+
|
|
4409
|
+
const totalRoutes = [...appRoutes, ...pagesRoutes];
|
|
4410
|
+
log$3(
|
|
4411
|
+
'Total routes found: %d (App Router: %d, Pages Router: %d)',
|
|
4412
|
+
totalRoutes.length,
|
|
4413
|
+
appRoutes.length,
|
|
4414
|
+
pagesRoutes.length,
|
|
4415
|
+
);
|
|
4416
|
+
|
|
4417
|
+
return totalRoutes;
|
|
4418
|
+
};
|
|
4419
|
+
|
|
4277
4420
|
// ABOUTME: Route manifest file writer
|
|
4278
4421
|
// ABOUTME: Writes route data to JSON file with proper formatting and directory creation
|
|
4279
4422
|
|