@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.
@@ -123,14 +123,64 @@ export default [
123
123
  },
124
124
  },
125
125
  {
126
- files: ['src/pages/intro/index.tsx'],
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/intro/index) 仍为默认占位页面,这会导致用户无法进入新增页面,请根据用户需求开发实际的首页功能 and 界面。如果已经开发了新的首页,也需要删除旧首页,并更新 src/app.config.ts 文件',
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.43776c";
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/blog/index.vue -> /blog
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 both app/pages/ and pages/) and .vue extension
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.startsWith('server/api/')) {
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
- * Scans for:
4035
- * - app/pages/**\/*.vue OR pages/**\/*.vue - Page routes (both structures supported)
4036
- * - server/api/**\/*.{ts,js} - API routes
4037
- * - server/routes/**\/*.{ts,js} - Server routes
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
- * - app/layouts/, layouts/ - Layout components (NOT routes)
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 both app/pages/ and pages/ directories
4051
- const pageFiles = await fastGlob.glob(['{app/,}pages/**/*.vue'], {
4052
- cwd,
4053
- ignore: [
4054
- '**/node_modules/**',
4055
- '**/.nuxt/**',
4056
- '**/dist/**',
4057
- '**/.output/**',
4058
- // Exclude layouts directory (not routes)
4059
- '**/layouts/**',
4060
- 'app/layouts/**',
4061
- // Exclude special files
4062
- 'app.vue',
4063
- 'error.vue',
4064
- ],
4065
- onlyFiles: true,
4066
- followSymbolicLinks: false,
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('server/routes/**/*.{ts,js}', {
4119
- cwd,
4120
- ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
4121
- onlyFiles: true,
4122
- followSymbolicLinks: false,
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 scanNextjsRoutes = async (cwd) => {
4241
- log$3('Scanning Next.js routes in:', cwd);
4266
+ const scanAppRouter = async (cwd) => {
4267
+ log$3('Scanning App Router routes');
4242
4268
 
4243
- // Scan for page and route files only (NOT layout, loading, error, etc.)
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-arch/cli",
3
- "version": "0.0.6-alpha.43776c",
3
+ "version": "0.0.6-alpha.dd6b66",
4
4
  "private": false,
5
5
  "description": "coze coding devtools cli",
6
6
  "license": "MIT",