@l4yercak3/cli 1.3.1 → 2.0.0-alpha.0
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/README.md +10 -220
- package/dist/api/client.d.ts +12 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +37 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/platform.d.ts +161 -0
- package/dist/api/platform.d.ts.map +1 -0
- package/dist/api/platform.js +70 -0
- package/dist/api/platform.js.map +1 -0
- package/dist/bin/sevenlayers.d.ts +3 -0
- package/dist/bin/sevenlayers.d.ts.map +1 -0
- package/dist/bin/sevenlayers.js +198 -0
- package/dist/bin/sevenlayers.js.map +1 -0
- package/dist/commands/agent/catalog.d.ts +5 -0
- package/dist/commands/agent/catalog.d.ts.map +1 -0
- package/dist/commands/agent/catalog.js +142 -0
- package/dist/commands/agent/catalog.js.map +1 -0
- package/dist/commands/agent/drift.d.ts +5 -0
- package/dist/commands/agent/drift.d.ts.map +1 -0
- package/dist/commands/agent/drift.js +113 -0
- package/dist/commands/agent/drift.js.map +1 -0
- package/dist/commands/agent/init.d.ts +5 -0
- package/dist/commands/agent/init.d.ts.map +1 -0
- package/dist/commands/agent/init.js +75 -0
- package/dist/commands/agent/init.js.map +1 -0
- package/dist/commands/agent/permissions.d.ts +5 -0
- package/dist/commands/agent/permissions.d.ts.map +1 -0
- package/dist/commands/agent/permissions.js +88 -0
- package/dist/commands/agent/permissions.js.map +1 -0
- package/dist/commands/agent/runner.d.ts +14 -0
- package/dist/commands/agent/runner.d.ts.map +1 -0
- package/dist/commands/agent/runner.js +59 -0
- package/dist/commands/agent/runner.js.map +1 -0
- package/dist/commands/agent/shared.d.ts +13 -0
- package/dist/commands/agent/shared.d.ts.map +1 -0
- package/dist/commands/agent/shared.js +31 -0
- package/dist/commands/agent/shared.js.map +1 -0
- package/dist/commands/agent/template.d.ts +5 -0
- package/dist/commands/agent/template.d.ts.map +1 -0
- package/dist/commands/agent/template.js +104 -0
- package/dist/commands/agent/template.js.map +1 -0
- package/dist/commands/app/connect.d.ts +7 -0
- package/dist/commands/app/connect.d.ts.map +1 -0
- package/dist/commands/app/connect.js +12 -0
- package/dist/commands/app/connect.js.map +1 -0
- package/dist/commands/app/init.d.ts +7 -0
- package/dist/commands/app/init.d.ts.map +1 -0
- package/dist/commands/app/init.js +12 -0
- package/dist/commands/app/init.js.map +1 -0
- package/dist/commands/app/link.d.ts +3 -0
- package/dist/commands/app/link.d.ts.map +1 -0
- package/dist/commands/app/link.js +92 -0
- package/dist/commands/app/link.js.map +1 -0
- package/dist/commands/app/pages.d.ts +15 -0
- package/dist/commands/app/pages.d.ts.map +1 -0
- package/dist/commands/app/pages.js +180 -0
- package/dist/commands/app/pages.js.map +1 -0
- package/dist/commands/app/register.d.ts +3 -0
- package/dist/commands/app/register.d.ts.map +1 -0
- package/dist/commands/app/register.js +120 -0
- package/dist/commands/app/register.js.map +1 -0
- package/dist/commands/app/remote.d.ts +14 -0
- package/dist/commands/app/remote.d.ts.map +1 -0
- package/dist/commands/app/remote.js +44 -0
- package/dist/commands/app/remote.js.map +1 -0
- package/dist/commands/app/setup.d.ts +3 -0
- package/dist/commands/app/setup.d.ts.map +1 -0
- package/dist/commands/app/setup.js +299 -0
- package/dist/commands/app/setup.js.map +1 -0
- package/dist/commands/app/shared.d.ts +9 -0
- package/dist/commands/app/shared.d.ts.map +1 -0
- package/dist/commands/app/shared.js +122 -0
- package/dist/commands/app/shared.js.map +1 -0
- package/dist/commands/app/sync.d.ts +7 -0
- package/dist/commands/app/sync.d.ts.map +1 -0
- package/dist/commands/app/sync.js +107 -0
- package/dist/commands/app/sync.js.map +1 -0
- package/dist/commands/booking/check.d.ts +3 -0
- package/dist/commands/booking/check.d.ts.map +1 -0
- package/dist/commands/booking/check.js +68 -0
- package/dist/commands/booking/check.js.map +1 -0
- package/dist/commands/booking/setup.d.ts +3 -0
- package/dist/commands/booking/setup.d.ts.map +1 -0
- package/dist/commands/booking/setup.js +95 -0
- package/dist/commands/booking/setup.js.map +1 -0
- package/dist/commands/booking/shared.d.ts +31 -0
- package/dist/commands/booking/shared.d.ts.map +1 -0
- package/dist/commands/booking/shared.js +112 -0
- package/dist/commands/booking/shared.js.map +1 -0
- package/dist/commands/booking/smoke.d.ts +3 -0
- package/dist/commands/booking/smoke.d.ts.map +1 -0
- package/dist/commands/booking/smoke.js +101 -0
- package/dist/commands/booking/smoke.js.map +1 -0
- package/dist/commands/cms/bind.d.ts +3 -0
- package/dist/commands/cms/bind.d.ts.map +1 -0
- package/dist/commands/cms/bind.js +212 -0
- package/dist/commands/cms/bind.js.map +1 -0
- package/dist/commands/cms/content.d.ts +40 -0
- package/dist/commands/cms/content.d.ts.map +1 -0
- package/dist/commands/cms/content.js +169 -0
- package/dist/commands/cms/content.js.map +1 -0
- package/dist/commands/cms/doctor.d.ts +3 -0
- package/dist/commands/cms/doctor.d.ts.map +1 -0
- package/dist/commands/cms/doctor.js +69 -0
- package/dist/commands/cms/doctor.js.map +1 -0
- package/dist/commands/cms/migrate.d.ts +3 -0
- package/dist/commands/cms/migrate.d.ts.map +1 -0
- package/dist/commands/cms/migrate.js +78 -0
- package/dist/commands/cms/migrate.js.map +1 -0
- package/dist/commands/cms/registry.d.ts +3 -0
- package/dist/commands/cms/registry.d.ts.map +1 -0
- package/dist/commands/cms/registry.js +161 -0
- package/dist/commands/cms/registry.js.map +1 -0
- package/dist/commands/cms/seed.d.ts +3 -0
- package/dist/commands/cms/seed.d.ts.map +1 -0
- package/dist/commands/cms/seed.js +102 -0
- package/dist/commands/cms/seed.js.map +1 -0
- package/dist/commands/cms/shared.d.ts +22 -0
- package/dist/commands/cms/shared.d.ts.map +1 -0
- package/dist/commands/cms/shared.js +82 -0
- package/dist/commands/cms/shared.js.map +1 -0
- package/dist/commands/doctor/target.d.ts +3 -0
- package/dist/commands/doctor/target.d.ts.map +1 -0
- package/dist/commands/doctor/target.js +46 -0
- package/dist/commands/doctor/target.js.map +1 -0
- package/dist/commands/env/list.d.ts +3 -0
- package/dist/commands/env/list.d.ts.map +1 -0
- package/dist/commands/env/list.js +28 -0
- package/dist/commands/env/list.js.map +1 -0
- package/dist/commands/env/set.d.ts +3 -0
- package/dist/commands/env/set.d.ts.map +1 -0
- package/dist/commands/env/set.js +36 -0
- package/dist/commands/env/set.js.map +1 -0
- package/dist/commands/env/use.d.ts +3 -0
- package/dist/commands/env/use.d.ts.map +1 -0
- package/dist/commands/env/use.js +15 -0
- package/dist/commands/env/use.js.map +1 -0
- package/dist/commands/legacy/connect.d.ts +3 -0
- package/dist/commands/legacy/connect.d.ts.map +1 -0
- package/dist/commands/legacy/connect.js +8 -0
- package/dist/commands/legacy/connect.js.map +1 -0
- package/dist/commands/legacy/pages.d.ts +3 -0
- package/dist/commands/legacy/pages.d.ts.map +1 -0
- package/dist/commands/legacy/pages.js +16 -0
- package/dist/commands/legacy/pages.js.map +1 -0
- package/dist/commands/legacy/spread.d.ts +3 -0
- package/dist/commands/legacy/spread.d.ts.map +1 -0
- package/dist/commands/legacy/spread.js +8 -0
- package/dist/commands/legacy/spread.js.map +1 -0
- package/dist/commands/legacy/sync.d.ts +3 -0
- package/dist/commands/legacy/sync.d.ts.map +1 -0
- package/dist/commands/legacy/sync.js +8 -0
- package/dist/commands/legacy/sync.js.map +1 -0
- package/dist/config/env-diff.d.ts +10 -0
- package/dist/config/env-diff.d.ts.map +1 -0
- package/dist/config/env-diff.js +24 -0
- package/dist/config/env-diff.js.map +1 -0
- package/dist/config/env-parser.d.ts +20 -0
- package/dist/config/env-parser.d.ts.map +1 -0
- package/dist/config/env-parser.js +70 -0
- package/dist/config/env-parser.js.map +1 -0
- package/dist/config/env-writer.d.ts +22 -0
- package/dist/config/env-writer.d.ts.map +1 -0
- package/dist/config/env-writer.js +172 -0
- package/dist/config/env-writer.js.map +1 -0
- package/dist/config/profile-store.d.ts +29 -0
- package/dist/config/profile-store.d.ts.map +1 -0
- package/dist/config/profile-store.js +257 -0
- package/dist/config/profile-store.js.map +1 -0
- package/dist/core/args.d.ts +11 -0
- package/dist/core/args.d.ts.map +1 -0
- package/dist/core/args.js +106 -0
- package/dist/core/args.js.map +1 -0
- package/dist/core/colors.d.ts +6 -0
- package/dist/core/colors.d.ts.map +1 -0
- package/dist/core/colors.js +29 -0
- package/dist/core/colors.js.map +1 -0
- package/dist/safety/target-guard.d.ts +16 -0
- package/dist/safety/target-guard.d.ts.map +1 -0
- package/dist/safety/target-guard.js +55 -0
- package/dist/safety/target-guard.js.map +1 -0
- package/dist/testing/booking-smoke.d.ts +17 -0
- package/dist/testing/booking-smoke.d.ts.map +1 -0
- package/dist/testing/booking-smoke.js +43 -0
- package/dist/testing/booking-smoke.js.map +1 -0
- package/dist/tests/agent-commands.test.d.ts +2 -0
- package/dist/tests/agent-commands.test.d.ts.map +1 -0
- package/dist/tests/agent-commands.test.js +180 -0
- package/dist/tests/agent-commands.test.js.map +1 -0
- package/dist/tests/agent-governance.test.d.ts +2 -0
- package/dist/tests/agent-governance.test.d.ts.map +1 -0
- package/dist/tests/agent-governance.test.js +233 -0
- package/dist/tests/agent-governance.test.js.map +1 -0
- package/dist/tests/app-commands.test.d.ts +2 -0
- package/dist/tests/app-commands.test.d.ts.map +1 -0
- package/dist/tests/app-commands.test.js +462 -0
- package/dist/tests/app-commands.test.js.map +1 -0
- package/dist/tests/booking-commands.test.d.ts +2 -0
- package/dist/tests/booking-commands.test.d.ts.map +1 -0
- package/dist/tests/booking-commands.test.js +204 -0
- package/dist/tests/booking-commands.test.js.map +1 -0
- package/dist/tests/booking-smoke.test.d.ts +2 -0
- package/dist/tests/booking-smoke.test.d.ts.map +1 -0
- package/dist/tests/booking-smoke.test.js +183 -0
- package/dist/tests/booking-smoke.test.js.map +1 -0
- package/dist/tests/cms-commands.test.d.ts +2 -0
- package/dist/tests/cms-commands.test.d.ts.map +1 -0
- package/dist/tests/cms-commands.test.js +254 -0
- package/dist/tests/cms-commands.test.js.map +1 -0
- package/dist/tests/cms-ops.test.d.ts +2 -0
- package/dist/tests/cms-ops.test.d.ts.map +1 -0
- package/dist/tests/cms-ops.test.js +125 -0
- package/dist/tests/cms-ops.test.js.map +1 -0
- package/dist/tests/env-writer.test.d.ts +2 -0
- package/dist/tests/env-writer.test.d.ts.map +1 -0
- package/dist/tests/env-writer.test.js +90 -0
- package/dist/tests/env-writer.test.js.map +1 -0
- package/dist/tests/profile-store.test.d.ts +2 -0
- package/dist/tests/profile-store.test.d.ts.map +1 -0
- package/dist/tests/profile-store.test.js +88 -0
- package/dist/tests/profile-store.test.js.map +1 -0
- package/dist/tests/target-guard.test.d.ts +2 -0
- package/dist/tests/target-guard.test.d.ts.map +1 -0
- package/dist/tests/target-guard.test.js +132 -0
- package/dist/tests/target-guard.test.js.map +1 -0
- package/dist/ui/logo.d.ts +2 -0
- package/dist/ui/logo.d.ts.map +1 -0
- package/dist/ui/logo.js +22 -0
- package/dist/ui/logo.js.map +1 -0
- package/package.json +17 -53
- package/.claude/settings.local.json +0 -36
- package/.cursor/rules.md +0 -203
- package/.eslintrc.js +0 -31
- package/CLAUDE.md +0 -100
- package/bin/cli.js +0 -116
- package/docs/ADDING_FRAMEWORK_DETECTORS.md +0 -391
- package/docs/ADDING_NEW_PROJECT_TYPE.md +0 -156
- package/docs/ARCHITECTURE_RELATIONSHIPS.md +0 -411
- package/docs/CLI_AUTHENTICATION.md +0 -214
- package/docs/CLI_PAGE_DETECTION_REQUIREMENTS.md +0 -519
- package/docs/CRM-PIPELINES-SEQUENCES-SPEC.md +0 -429
- package/docs/DETECTOR_ARCHITECTURE.md +0 -326
- package/docs/DEVELOPMENT.md +0 -194
- package/docs/IMPLEMENTATION_PHASES.md +0 -468
- package/docs/INTEGRATION_PATHS_ARCHITECTURE.md +0 -1543
- package/docs/OAUTH_CLARIFICATION.md +0 -258
- package/docs/OAUTH_SETUP_GUIDE_TEMPLATE.md +0 -211
- package/docs/PHASE_0_PROGRESS.md +0 -120
- package/docs/PHASE_1_COMPLETE.md +0 -366
- package/docs/PHASE_SUMMARY.md +0 -149
- package/docs/PLAN.md +0 -511
- package/docs/README.md +0 -56
- package/docs/STRIPE_INTEGRATION.md +0 -447
- package/docs/SUMMARY.md +0 -230
- package/docs/UPDATED_PLAN.md +0 -447
- package/docs/mcp_server/MCP_EXTENSION_GUIDE.md +0 -1313
- package/docs/mcp_server/MCP_SERVER_ARCHITECTURE.md +0 -1481
- package/docs/mcp_server/applicationOntology.ts +0 -817
- package/docs/mcp_server/cliApplications.ts +0 -639
- package/docs/mcp_server/crmOntology.ts +0 -1063
- package/docs/mcp_server/eventOntology.ts +0 -1183
- package/docs/mcp_server/formsOntology.ts +0 -1401
- package/docs/mcp_server/ontologySchemas.ts +0 -185
- package/docs/mcp_server/schema.ts +0 -250
- package/docs/microsass_production_machine/CLI_API_REFERENCE.md +0 -1197
- package/docs/microsass_production_machine/CLI_PRODUCT_VISION.md +0 -676
- package/docs/microsass_production_machine/CLI_REQUIREMENTS.md +0 -606
- package/docs/microsass_production_machine/CONNECTED_APPLICATIONS_SPEC.md +0 -390
- package/docs/microsass_production_machine/IMPLEMENTATION_ROADMAP.md +0 -725
- package/docs/microsass_production_machine/OBJECT_MAPPINGS.md +0 -808
- package/docs/microsass_production_machine/REFERENCE_IMPLEMENTATION.md +0 -532
- package/src/api/backend-client.js +0 -449
- package/src/commands/api-keys.js +0 -119
- package/src/commands/connect.js +0 -243
- package/src/commands/login.js +0 -332
- package/src/commands/logout.js +0 -30
- package/src/commands/mcp-server.js +0 -85
- package/src/commands/mcp-setup.js +0 -686
- package/src/commands/pages.js +0 -317
- package/src/commands/scaffold.js +0 -409
- package/src/commands/spread.js +0 -861
- package/src/commands/status.js +0 -62
- package/src/commands/sync.js +0 -169
- package/src/commands/upgrade.js +0 -48
- package/src/config/config-manager.js +0 -206
- package/src/detectors/api-client-detector.js +0 -85
- package/src/detectors/base-detector.js +0 -77
- package/src/detectors/database-detector.js +0 -245
- package/src/detectors/expo-detector.js +0 -166
- package/src/detectors/github-detector.js +0 -74
- package/src/detectors/index.js +0 -106
- package/src/detectors/mapping-suggestor.js +0 -119
- package/src/detectors/model-detector.js +0 -318
- package/src/detectors/nextjs-detector.js +0 -139
- package/src/detectors/oauth-detector.js +0 -122
- package/src/detectors/page-detector.js +0 -480
- package/src/detectors/registry.js +0 -121
- package/src/generators/api-client-generator.js +0 -223
- package/src/generators/api-only/client.js +0 -683
- package/src/generators/api-only/index.js +0 -96
- package/src/generators/api-only/types.js +0 -618
- package/src/generators/api-only/webhooks.js +0 -377
- package/src/generators/env-generator.js +0 -191
- package/src/generators/expo-auth-generator.js +0 -1009
- package/src/generators/gitignore-generator.js +0 -92
- package/src/generators/index.js +0 -166
- package/src/generators/manifest-generator.js +0 -154
- package/src/generators/mcp-guide-generator.js +0 -256
- package/src/generators/nextauth-generator.js +0 -247
- package/src/generators/oauth-guide-generator.js +0 -277
- package/src/generators/quickstart/components/index.js +0 -1699
- package/src/generators/quickstart/components-mobile/index.js +0 -1440
- package/src/generators/quickstart/database/convex.js +0 -1257
- package/src/generators/quickstart/database/index.js +0 -34
- package/src/generators/quickstart/database/supabase.js +0 -1132
- package/src/generators/quickstart/hooks/index.js +0 -1065
- package/src/generators/quickstart/index.js +0 -191
- package/src/generators/quickstart/pages/index.js +0 -1466
- package/src/generators/quickstart/screens/index.js +0 -1498
- package/src/logo.js +0 -116
- package/src/mcp/auth.js +0 -127
- package/src/mcp/registry/domains/applications.js +0 -516
- package/src/mcp/registry/domains/benefits.js +0 -798
- package/src/mcp/registry/domains/codegen.js +0 -894
- package/src/mcp/registry/domains/core.js +0 -324
- package/src/mcp/registry/domains/crm.js +0 -591
- package/src/mcp/registry/domains/events.js +0 -649
- package/src/mcp/registry/domains/forms.js +0 -696
- package/src/mcp/registry/index.js +0 -164
- package/src/mcp/server.js +0 -116
- package/src/utils/file-utils.js +0 -117
- package/src/utils/init-helpers.js +0 -243
- package/src/utils/prompt-utils.js +0 -195
- package/templates/CLAUDE.md +0 -86
- package/tests/api-client-detector.test.js +0 -214
- package/tests/api-client-generator.test.js +0 -176
- package/tests/backend-client.test.js +0 -640
- package/tests/base-detector.test.js +0 -101
- package/tests/commands/login.test.js +0 -143
- package/tests/commands/logout.test.js +0 -84
- package/tests/commands/status.test.js +0 -167
- package/tests/config-manager.test.js +0 -321
- package/tests/database-detector.test.js +0 -221
- package/tests/detector-index.test.js +0 -209
- package/tests/detector-registry.test.js +0 -93
- package/tests/env-generator.test.js +0 -278
- package/tests/expo-detector.test.js +0 -263
- package/tests/file-utils.test.js +0 -194
- package/tests/generators-index.test.js +0 -454
- package/tests/github-detector.test.js +0 -145
- package/tests/gitignore-generator.test.js +0 -109
- package/tests/logo.test.js +0 -96
- package/tests/nextauth-generator.test.js +0 -255
- package/tests/nextjs-detector.test.js +0 -235
- package/tests/oauth-detector.test.js +0 -264
- package/tests/oauth-guide-generator.test.js +0 -273
- package/tests/page-detector.test.js +0 -371
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Page/Screen Detector
|
|
3
|
-
* Detects pages in Next.js projects and screens in Expo/React Native projects
|
|
4
|
-
* Used for syncing application structure with L4YERCAK3 backend
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
|
|
10
|
-
class PageDetector {
|
|
11
|
-
/**
|
|
12
|
-
* Detect all pages/screens in a project
|
|
13
|
-
* @param {string} projectPath - Path to project root
|
|
14
|
-
* @param {string} frameworkType - 'nextjs', 'expo', or 'react-native'
|
|
15
|
-
* @param {object} frameworkMetadata - Additional framework info (routerType, etc.)
|
|
16
|
-
* @returns {Array<{path: string, name: string, pageType: string, filePath: string}>}
|
|
17
|
-
*/
|
|
18
|
-
detect(projectPath, frameworkType, frameworkMetadata = {}) {
|
|
19
|
-
switch (frameworkType) {
|
|
20
|
-
case 'nextjs':
|
|
21
|
-
return this.detectNextJsPages(projectPath, frameworkMetadata);
|
|
22
|
-
case 'expo':
|
|
23
|
-
case 'react-native':
|
|
24
|
-
return this.detectExpoScreens(projectPath, frameworkMetadata);
|
|
25
|
-
default:
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Detect Next.js pages (supports both App Router and Pages Router)
|
|
32
|
-
*/
|
|
33
|
-
detectNextJsPages(projectPath, metadata) {
|
|
34
|
-
const routerType = metadata.routerType || 'pages';
|
|
35
|
-
const pages = [];
|
|
36
|
-
|
|
37
|
-
if (routerType === 'app') {
|
|
38
|
-
// App Router: look for page.tsx/page.js files in app/ or src/app/
|
|
39
|
-
const appDirs = [
|
|
40
|
-
path.join(projectPath, 'app'),
|
|
41
|
-
path.join(projectPath, 'src', 'app'),
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
for (const appDir of appDirs) {
|
|
45
|
-
if (fs.existsSync(appDir)) {
|
|
46
|
-
this.scanAppRouterDirectory(appDir, '', pages, appDir);
|
|
47
|
-
break; // Only use the first found app directory
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
} else {
|
|
51
|
-
// Pages Router: look for files in pages/ or src/pages/
|
|
52
|
-
const pagesDirs = [
|
|
53
|
-
path.join(projectPath, 'pages'),
|
|
54
|
-
path.join(projectPath, 'src', 'pages'),
|
|
55
|
-
];
|
|
56
|
-
|
|
57
|
-
for (const pagesDir of pagesDirs) {
|
|
58
|
-
if (fs.existsSync(pagesDir)) {
|
|
59
|
-
this.scanPagesRouterDirectory(pagesDir, '', pages, pagesDir);
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return pages;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Scan App Router directory structure
|
|
70
|
-
* In App Router, pages are defined by page.tsx/page.js files
|
|
71
|
-
* API routes are defined by route.tsx/route.js files
|
|
72
|
-
*/
|
|
73
|
-
scanAppRouterDirectory(dir, routePath, pages, baseDir) {
|
|
74
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
75
|
-
|
|
76
|
-
for (const entry of entries) {
|
|
77
|
-
const fullPath = path.join(dir, entry.name);
|
|
78
|
-
|
|
79
|
-
if (entry.isDirectory()) {
|
|
80
|
-
// Skip special directories
|
|
81
|
-
if (entry.name.startsWith('_') || entry.name.startsWith('.')) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Handle route groups (parentheses) - they don't add to URL
|
|
86
|
-
let newRoutePath = routePath;
|
|
87
|
-
if (!entry.name.startsWith('(') || !entry.name.endsWith(')')) {
|
|
88
|
-
// Handle dynamic segments [param] and catch-all [...param]
|
|
89
|
-
let segment = entry.name;
|
|
90
|
-
if (segment.startsWith('[') && segment.endsWith(']')) {
|
|
91
|
-
// Keep dynamic segment notation
|
|
92
|
-
newRoutePath = `${routePath}/${segment}`;
|
|
93
|
-
} else {
|
|
94
|
-
newRoutePath = `${routePath}/${segment}`;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
this.scanAppRouterDirectory(fullPath, newRoutePath, pages, baseDir);
|
|
99
|
-
} else if (entry.isFile()) {
|
|
100
|
-
const ext = path.extname(entry.name);
|
|
101
|
-
const baseName = path.basename(entry.name, ext);
|
|
102
|
-
|
|
103
|
-
// Check for page files
|
|
104
|
-
if (baseName === 'page' && ['.tsx', '.ts', '.jsx', '.js'].includes(ext)) {
|
|
105
|
-
const pagePath = routePath || '/';
|
|
106
|
-
pages.push({
|
|
107
|
-
path: pagePath,
|
|
108
|
-
name: this.generatePageName(pagePath),
|
|
109
|
-
pageType: this.detectPageType(pagePath),
|
|
110
|
-
filePath: path.relative(baseDir, fullPath),
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Check for API route files
|
|
115
|
-
if (baseName === 'route' && ['.tsx', '.ts', '.jsx', '.js'].includes(ext)) {
|
|
116
|
-
const apiPath = routePath || '/';
|
|
117
|
-
const methods = this.detectHttpMethods(fullPath, 'app');
|
|
118
|
-
pages.push({
|
|
119
|
-
path: apiPath,
|
|
120
|
-
name: this.generatePageName(apiPath, true),
|
|
121
|
-
pageType: 'api_route',
|
|
122
|
-
filePath: path.relative(baseDir, fullPath),
|
|
123
|
-
methods,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Detect HTTP methods exported from a route file
|
|
132
|
-
* @param {string} filePath - Absolute path to the route file
|
|
133
|
-
* @param {string} routerType - 'app' or 'pages'
|
|
134
|
-
* @returns {string[]} Array of HTTP methods (e.g., ['GET', 'POST'])
|
|
135
|
-
*/
|
|
136
|
-
detectHttpMethods(filePath, routerType) {
|
|
137
|
-
let content;
|
|
138
|
-
try {
|
|
139
|
-
content = fs.readFileSync(filePath, 'utf8');
|
|
140
|
-
} catch {
|
|
141
|
-
return ['GET', 'POST']; // Default fallback
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const methods = new Set();
|
|
145
|
-
|
|
146
|
-
if (routerType === 'app') {
|
|
147
|
-
// App Router: look for exported handler functions
|
|
148
|
-
// export async function GET(...) or export const GET = ...
|
|
149
|
-
const HTTP_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
|
|
150
|
-
for (const method of HTTP_METHODS) {
|
|
151
|
-
const funcPattern = new RegExp(`export\\s+(?:async\\s+)?function\\s+${method}\\b`);
|
|
152
|
-
const constPattern = new RegExp(`export\\s+const\\s+${method}\\s*=`);
|
|
153
|
-
if (funcPattern.test(content) || constPattern.test(content)) {
|
|
154
|
-
methods.add(method);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
// Pages Router: look for req.method checks
|
|
159
|
-
const methodCheckRegex = /req\.method\s*===?\s*['"](\w+)['"]/g;
|
|
160
|
-
let match;
|
|
161
|
-
while ((match = methodCheckRegex.exec(content)) !== null) {
|
|
162
|
-
methods.add(match[1].toUpperCase());
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Also check switch/case patterns: case 'GET':
|
|
166
|
-
const caseRegex = /case\s+['"](\w+)['"]\s*:/g;
|
|
167
|
-
while ((match = caseRegex.exec(content)) !== null) {
|
|
168
|
-
const val = match[1].toUpperCase();
|
|
169
|
-
if (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'].includes(val)) {
|
|
170
|
-
methods.add(val);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Default to GET/POST if no methods detected
|
|
176
|
-
if (methods.size === 0) {
|
|
177
|
-
return ['GET', 'POST'];
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return Array.from(methods).sort();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Scan Pages Router directory structure
|
|
185
|
-
* In Pages Router, each file is a page, and files in api/ are API routes
|
|
186
|
-
*/
|
|
187
|
-
scanPagesRouterDirectory(dir, routePath, pages, baseDir) {
|
|
188
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
189
|
-
|
|
190
|
-
for (const entry of entries) {
|
|
191
|
-
const fullPath = path.join(dir, entry.name);
|
|
192
|
-
|
|
193
|
-
if (entry.isDirectory()) {
|
|
194
|
-
// Skip special directories
|
|
195
|
-
if (entry.name.startsWith('_') || entry.name.startsWith('.')) {
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const newRoutePath = `${routePath}/${entry.name}`;
|
|
200
|
-
this.scanPagesRouterDirectory(fullPath, newRoutePath, pages, baseDir);
|
|
201
|
-
} else if (entry.isFile()) {
|
|
202
|
-
const ext = path.extname(entry.name);
|
|
203
|
-
const baseName = path.basename(entry.name, ext);
|
|
204
|
-
|
|
205
|
-
// Only process TypeScript/JavaScript files
|
|
206
|
-
if (!['.tsx', '.ts', '.jsx', '.js'].includes(ext)) {
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Skip special files
|
|
211
|
-
if (baseName.startsWith('_')) {
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Determine the route path
|
|
216
|
-
let pagePath;
|
|
217
|
-
if (baseName === 'index') {
|
|
218
|
-
pagePath = routePath || '/';
|
|
219
|
-
} else {
|
|
220
|
-
pagePath = `${routePath}/${baseName}`;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Check if this is an API route
|
|
224
|
-
const isApiRoute = routePath.startsWith('/api') || pagePath.startsWith('/api');
|
|
225
|
-
|
|
226
|
-
const entry_data = {
|
|
227
|
-
path: pagePath,
|
|
228
|
-
name: this.generatePageName(pagePath, isApiRoute),
|
|
229
|
-
pageType: isApiRoute ? 'api_route' : this.detectPageType(pagePath),
|
|
230
|
-
filePath: path.relative(baseDir, fullPath),
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
if (isApiRoute) {
|
|
234
|
-
entry_data.methods = this.detectHttpMethods(fullPath, 'pages');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
pages.push(entry_data);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Detect Expo/React Native screens
|
|
244
|
-
* Supports expo-router (file-based) and react-navigation
|
|
245
|
-
*/
|
|
246
|
-
detectExpoScreens(projectPath, metadata) {
|
|
247
|
-
const screens = [];
|
|
248
|
-
const routerType = metadata.routerType || 'native';
|
|
249
|
-
|
|
250
|
-
if (routerType === 'expo-router') {
|
|
251
|
-
// Expo Router uses file-based routing similar to Next.js App Router
|
|
252
|
-
const appDirs = [
|
|
253
|
-
path.join(projectPath, 'app'),
|
|
254
|
-
path.join(projectPath, 'src', 'app'),
|
|
255
|
-
];
|
|
256
|
-
|
|
257
|
-
for (const appDir of appDirs) {
|
|
258
|
-
if (fs.existsSync(appDir)) {
|
|
259
|
-
this.scanExpoRouterDirectory(appDir, '', screens, appDir);
|
|
260
|
-
break;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
} else {
|
|
264
|
-
// React Navigation or native - scan for screen files
|
|
265
|
-
const screenDirs = [
|
|
266
|
-
path.join(projectPath, 'src', 'screens'),
|
|
267
|
-
path.join(projectPath, 'screens'),
|
|
268
|
-
path.join(projectPath, 'src', 'views'),
|
|
269
|
-
path.join(projectPath, 'views'),
|
|
270
|
-
path.join(projectPath, 'app', 'screens'),
|
|
271
|
-
];
|
|
272
|
-
|
|
273
|
-
for (const screenDir of screenDirs) {
|
|
274
|
-
if (fs.existsSync(screenDir)) {
|
|
275
|
-
this.scanScreensDirectory(screenDir, screens, screenDir);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return screens;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Scan Expo Router directory structure
|
|
285
|
-
* Similar to Next.js App Router but with some differences
|
|
286
|
-
*/
|
|
287
|
-
scanExpoRouterDirectory(dir, routePath, screens, baseDir) {
|
|
288
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
289
|
-
|
|
290
|
-
for (const entry of entries) {
|
|
291
|
-
const fullPath = path.join(dir, entry.name);
|
|
292
|
-
|
|
293
|
-
if (entry.isDirectory()) {
|
|
294
|
-
// Skip special directories
|
|
295
|
-
if (entry.name.startsWith('_') || entry.name.startsWith('.')) {
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Handle route groups (parentheses)
|
|
300
|
-
let newRoutePath = routePath;
|
|
301
|
-
if (!entry.name.startsWith('(') || !entry.name.endsWith(')')) {
|
|
302
|
-
newRoutePath = `${routePath}/${entry.name}`;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
this.scanExpoRouterDirectory(fullPath, newRoutePath, screens, baseDir);
|
|
306
|
-
} else if (entry.isFile()) {
|
|
307
|
-
const ext = path.extname(entry.name);
|
|
308
|
-
const baseName = path.basename(entry.name, ext);
|
|
309
|
-
|
|
310
|
-
// Skip non-JS/TS files and special files
|
|
311
|
-
if (!['.tsx', '.ts', '.jsx', '.js'].includes(ext)) {
|
|
312
|
-
continue;
|
|
313
|
-
}
|
|
314
|
-
if (baseName.startsWith('_')) {
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Determine the route path
|
|
319
|
-
let screenPath;
|
|
320
|
-
if (baseName === 'index') {
|
|
321
|
-
screenPath = routePath || '/';
|
|
322
|
-
} else if (baseName === '+not-found') {
|
|
323
|
-
screenPath = '/*'; // Catch-all not found
|
|
324
|
-
} else if (baseName.startsWith('+')) {
|
|
325
|
-
// Skip Expo Router special files like +html.tsx, +native-intent.tsx
|
|
326
|
-
continue;
|
|
327
|
-
} else {
|
|
328
|
-
screenPath = `${routePath}/${baseName}`;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
screens.push({
|
|
332
|
-
path: screenPath,
|
|
333
|
-
name: this.generatePageName(screenPath),
|
|
334
|
-
pageType: this.detectPageType(screenPath),
|
|
335
|
-
filePath: path.relative(baseDir, fullPath),
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Scan traditional screens directory for React Navigation setup
|
|
343
|
-
*/
|
|
344
|
-
scanScreensDirectory(dir, screens, baseDir) {
|
|
345
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
346
|
-
|
|
347
|
-
for (const entry of entries) {
|
|
348
|
-
const fullPath = path.join(dir, entry.name);
|
|
349
|
-
|
|
350
|
-
if (entry.isDirectory()) {
|
|
351
|
-
// Recurse into subdirectories
|
|
352
|
-
this.scanScreensDirectory(fullPath, screens, baseDir);
|
|
353
|
-
} else if (entry.isFile()) {
|
|
354
|
-
const ext = path.extname(entry.name);
|
|
355
|
-
const baseName = path.basename(entry.name, ext);
|
|
356
|
-
|
|
357
|
-
// Only process screen files
|
|
358
|
-
if (!['.tsx', '.ts', '.jsx', '.js'].includes(ext)) {
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Skip index files and non-screen files
|
|
363
|
-
if (baseName === 'index' || baseName.startsWith('_')) {
|
|
364
|
-
continue;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Try to extract a meaningful path from the file name
|
|
368
|
-
// e.g., HomeScreen.tsx -> /home, ProfileScreen.tsx -> /profile
|
|
369
|
-
let screenPath = this.fileNameToPath(baseName);
|
|
370
|
-
|
|
371
|
-
screens.push({
|
|
372
|
-
path: screenPath,
|
|
373
|
-
name: this.generatePageName(screenPath),
|
|
374
|
-
pageType: 'static',
|
|
375
|
-
filePath: path.relative(baseDir, fullPath),
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Convert a file name to a route path
|
|
383
|
-
* e.g., "HomeScreen" -> "/home", "UserProfileScreen" -> "/user-profile"
|
|
384
|
-
*/
|
|
385
|
-
fileNameToPath(fileName) {
|
|
386
|
-
// Remove common suffixes
|
|
387
|
-
let name = fileName
|
|
388
|
-
.replace(/Screen$/, '')
|
|
389
|
-
.replace(/View$/, '')
|
|
390
|
-
.replace(/Page$/, '');
|
|
391
|
-
|
|
392
|
-
// Convert camelCase/PascalCase to kebab-case
|
|
393
|
-
name = name
|
|
394
|
-
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
395
|
-
.toLowerCase();
|
|
396
|
-
|
|
397
|
-
// Handle "Home" or "Index" specially
|
|
398
|
-
if (name === 'home' || name === 'index' || name === 'main') {
|
|
399
|
-
return '/';
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
return `/${name}`;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Generate a human-readable name from a path
|
|
407
|
-
*/
|
|
408
|
-
generatePageName(routePath, isApiRoute = false) {
|
|
409
|
-
if (routePath === '/') {
|
|
410
|
-
return isApiRoute ? 'API: Root' : 'Home';
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Handle catch-all not found (Expo +not-found)
|
|
414
|
-
if (routePath === '/*') {
|
|
415
|
-
return 'Not Found';
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Remove leading slash and split
|
|
419
|
-
const segments = routePath.slice(1).split('/');
|
|
420
|
-
|
|
421
|
-
// Handle API routes
|
|
422
|
-
if (isApiRoute || segments[0] === 'api') {
|
|
423
|
-
const apiSegments = segments.filter(s => s !== 'api');
|
|
424
|
-
if (apiSegments.length === 0) {
|
|
425
|
-
return 'API: Root';
|
|
426
|
-
}
|
|
427
|
-
const name = this.formatSegment(apiSegments[apiSegments.length - 1]);
|
|
428
|
-
return `API: ${name}`;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// Get the last segment for the name
|
|
432
|
-
const lastSegment = segments[segments.length - 1];
|
|
433
|
-
|
|
434
|
-
// Check if it's a dynamic segment
|
|
435
|
-
if (lastSegment.startsWith('[') && lastSegment.endsWith(']')) {
|
|
436
|
-
// Use the parent segment + "Detail"
|
|
437
|
-
if (segments.length > 1) {
|
|
438
|
-
const parentSegment = segments[segments.length - 2];
|
|
439
|
-
return `${this.formatSegment(parentSegment)} Detail`;
|
|
440
|
-
}
|
|
441
|
-
return 'Detail';
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
// Check for catch-all
|
|
445
|
-
if (lastSegment.startsWith('[...')) {
|
|
446
|
-
return 'Catch All';
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
return this.formatSegment(lastSegment);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Format a URL segment into a readable name
|
|
454
|
-
*/
|
|
455
|
-
formatSegment(segment) {
|
|
456
|
-
// Handle dynamic segments
|
|
457
|
-
if (segment.startsWith('[') && segment.endsWith(']')) {
|
|
458
|
-
segment = segment.slice(1, -1);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// Convert kebab-case to Title Case
|
|
462
|
-
return segment
|
|
463
|
-
.split('-')
|
|
464
|
-
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
465
|
-
.join(' ');
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* Detect page type based on path
|
|
470
|
-
*/
|
|
471
|
-
detectPageType(routePath) {
|
|
472
|
-
// Check for dynamic segments
|
|
473
|
-
if (routePath.includes('[') && routePath.includes(']')) {
|
|
474
|
-
return 'dynamic';
|
|
475
|
-
}
|
|
476
|
-
return 'static';
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
module.exports = new PageDetector();
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Detector Registry
|
|
3
|
-
*
|
|
4
|
-
* Central registry for all project type detectors.
|
|
5
|
-
* Detectors are automatically sorted by priority (highest first).
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const nextJsDetector = require('./nextjs-detector');
|
|
9
|
-
const expoDetector = require('./expo-detector');
|
|
10
|
-
// Future detectors will be added here:
|
|
11
|
-
// const reactDetector = require('./react-detector');
|
|
12
|
-
// const vueDetector = require('./vue-detector');
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* All registered detectors
|
|
16
|
-
* Add new detectors here as they're implemented
|
|
17
|
-
*/
|
|
18
|
-
const detectors = [
|
|
19
|
-
nextJsDetector,
|
|
20
|
-
expoDetector,
|
|
21
|
-
// Future: reactDetector, vueDetector, etc.
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Sort detectors by priority (highest first)
|
|
26
|
-
*/
|
|
27
|
-
const sortedDetectors = [...detectors].sort((a, b) => b.priority - a.priority);
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Detect project type
|
|
31
|
-
*
|
|
32
|
-
* Runs all detectors in priority order and returns the first match
|
|
33
|
-
* with confidence > 0.8, or all results if no high-confidence match.
|
|
34
|
-
*
|
|
35
|
-
* @param {string} projectPath - Path to project directory
|
|
36
|
-
* @returns {object} Detection results
|
|
37
|
-
*/
|
|
38
|
-
function detectProjectType(projectPath = process.cwd()) {
|
|
39
|
-
const results = {
|
|
40
|
-
detected: null, // Best match detector
|
|
41
|
-
confidence: 0, // Confidence of best match
|
|
42
|
-
metadata: {}, // Metadata from best match
|
|
43
|
-
allResults: [], // All detector results (for debugging)
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const debug = process.env.L4YERCAK3_DEBUG;
|
|
47
|
-
|
|
48
|
-
if (debug) {
|
|
49
|
-
console.log('\n[DEBUG] Registry: Running detectors in priority order:');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Run all detectors
|
|
53
|
-
for (const detector of sortedDetectors) {
|
|
54
|
-
try {
|
|
55
|
-
const result = detector.detect(projectPath);
|
|
56
|
-
|
|
57
|
-
if (debug) {
|
|
58
|
-
console.log(` [${detector.name}] priority=${detector.priority}, detected=${result.detected}, confidence=${result.confidence}`);
|
|
59
|
-
if (result.metadata) {
|
|
60
|
-
console.log(` metadata: ${JSON.stringify(result.metadata)}`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
results.allResults.push({
|
|
65
|
-
detector: detector.name,
|
|
66
|
-
priority: detector.priority,
|
|
67
|
-
...result,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// If this detector found a match with high confidence, use it
|
|
71
|
-
if (result.detected && result.confidence > 0.8) {
|
|
72
|
-
if (result.confidence > results.confidence) {
|
|
73
|
-
if (debug) {
|
|
74
|
-
console.log(` → Selected as best match (confidence ${result.confidence} > ${results.confidence})`);
|
|
75
|
-
}
|
|
76
|
-
results.detected = detector.name;
|
|
77
|
-
results.confidence = result.confidence;
|
|
78
|
-
results.metadata = result.metadata;
|
|
79
|
-
} else if (debug) {
|
|
80
|
-
console.log(` → Skipped (confidence ${result.confidence} <= ${results.confidence})`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error(`Error in detector ${detector.name}:`, error);
|
|
85
|
-
// Continue with other detectors
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (debug) {
|
|
90
|
-
console.log(`\n[DEBUG] Registry: Final result: ${results.detected} (confidence: ${results.confidence})`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return results;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Get detector by name
|
|
98
|
-
*
|
|
99
|
-
* @param {string} name - Detector name
|
|
100
|
-
* @returns {object|null} Detector instance or null
|
|
101
|
-
*/
|
|
102
|
-
function getDetector(name) {
|
|
103
|
-
return detectors.find(d => d.name === name) || null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get all registered detectors
|
|
108
|
-
*
|
|
109
|
-
* @returns {array} Array of detector instances
|
|
110
|
-
*/
|
|
111
|
-
function getAllDetectors() {
|
|
112
|
-
return sortedDetectors;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
module.exports = {
|
|
116
|
-
detectProjectType,
|
|
117
|
-
getDetector,
|
|
118
|
-
getAllDetectors,
|
|
119
|
-
detectors: sortedDetectors, // Expose sorted list
|
|
120
|
-
};
|
|
121
|
-
|