@warlock.js/core 5.34.3 → 5.35.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/CHANGELOG.md +44 -0
- package/esm/cli/cli-commands.manager.mjs +1 -1
- package/esm/cli/cli-commands.manager.mjs.map +1 -1
- package/esm/cli/commands/add.command.mjs +1 -0
- package/esm/cli/commands/add.command.mjs.map +1 -1
- package/esm/cli/commands/build.command.mjs +30 -3
- package/esm/cli/commands/build.command.mjs.map +1 -1
- package/esm/cli/commands/check/check-command.action.mjs +1 -0
- package/esm/cli/commands/check/check-command.action.mjs.map +1 -1
- package/esm/cli/commands/check.command.mjs +5 -0
- package/esm/cli/commands/check.command.mjs.map +1 -1
- package/esm/cli/commands/explain/explain-command.action.mjs +21 -0
- package/esm/cli/commands/explain/explain-command.action.mjs.map +1 -1
- package/esm/cli/commands/explain.command.mjs +14 -4
- package/esm/cli/commands/explain.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generate.command.mjs +19 -1
- package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/web.generator.mjs +169 -0
- package/esm/cli/commands/generate/generators/web.generator.mjs.map +1 -0
- package/esm/cli/commands/generate/templates/web-stubs.mjs +231 -0
- package/esm/cli/commands/generate/templates/web-stubs.mjs.map +1 -0
- package/esm/cli/commands/inspect/inspect-command.action.mjs +4 -3
- package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -1
- package/esm/cli/commands/inspect.command.mjs +13 -8
- package/esm/cli/commands/inspect.command.mjs.map +1 -1
- package/esm/cli/commands/mcp/mcp-command.action.mjs +1 -1
- package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -1
- package/esm/config/config-loader.d.mts.map +1 -1
- package/esm/config/config-loader.mjs +2 -0
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/load-config-files.mjs +4 -0
- package/esm/config/load-config-files.mjs.map +1 -1
- package/esm/dev-server/file-event-handler.mjs +11 -1
- package/esm/dev-server/file-event-handler.mjs.map +1 -1
- package/esm/dev-server/file-manager.d.mts +1 -1
- package/esm/dev-server/file-manager.d.mts.map +1 -1
- package/esm/dev-server/file-manager.mjs.map +1 -1
- package/esm/dev-server/files-orchestrator.mjs +16 -1
- package/esm/dev-server/files-orchestrator.mjs.map +1 -1
- package/esm/dev-server/files-watcher.mjs +13 -4
- package/esm/dev-server/files-watcher.mjs.map +1 -1
- package/esm/dev-server/loader/loader-port-acks.mjs +21 -9
- package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -1
- package/esm/dev-server/loader/register-loader.mjs +31 -12
- package/esm/dev-server/loader/register-loader.mjs.map +1 -1
- package/esm/dev-server/module-loader.mjs +14 -0
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/dev-server/special-file-patterns.mjs +4 -1
- package/esm/dev-server/special-file-patterns.mjs.map +1 -1
- package/esm/e2e/index.d.mts +2 -2
- package/esm/e2e/page.d.mts +6 -1
- package/esm/e2e/page.d.mts.map +1 -1
- package/esm/e2e/page.mjs +36 -1
- package/esm/e2e/page.mjs.map +1 -1
- package/esm/e2e/types.d.mts +31 -0
- package/esm/e2e/types.d.mts.map +1 -1
- package/esm/e2e/types.mjs.map +1 -1
- package/esm/errors/error-codes.d.mts +48 -0
- package/esm/errors/error-codes.d.mts.map +1 -1
- package/esm/errors/error-codes.mjs +48 -0
- package/esm/errors/error-codes.mjs.map +1 -1
- package/esm/errors/index.d.mts +2 -2
- package/esm/errors/index.mjs +2 -2
- package/esm/generations/add-command.action.mjs +2 -0
- package/esm/generations/add-command.action.mjs.map +1 -1
- package/esm/generations/design-system-payload.mjs +53 -0
- package/esm/generations/design-system-payload.mjs.map +1 -0
- package/esm/generations/features/design-system.feature.mjs +38 -0
- package/esm/generations/features/design-system.feature.mjs.map +1 -0
- package/esm/generations/features/index.mjs +3 -1
- package/esm/generations/features/index.mjs.map +1 -1
- package/esm/generations/features/notifications.feature.mjs +13 -2
- package/esm/generations/features/notifications.feature.mjs.map +1 -1
- package/esm/generations/features/test.feature.mjs +48 -13
- package/esm/generations/features/test.feature.mjs.map +1 -1
- package/esm/generations/stubs.mjs +9 -5
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/error-mapper.d.mts +1 -1
- package/esm/http/error-mapper.mjs +3 -3
- package/esm/http/error-mapper.mjs.map +1 -1
- package/esm/http/error-response.d.mts +3 -0
- package/esm/http/error-response.d.mts.map +1 -1
- package/esm/http/error-response.mjs +8 -2
- package/esm/http/error-response.mjs.map +1 -1
- package/esm/http/errors/errors.d.mts +8 -0
- package/esm/http/errors/errors.d.mts.map +1 -1
- package/esm/http/errors/errors.mjs +13 -1
- package/esm/http/errors/errors.mjs.map +1 -1
- package/esm/http/index.d.mts +3 -2
- package/esm/http/index.mjs +3 -2
- package/esm/http/list-endpoint.d.mts +35 -0
- package/esm/http/list-endpoint.d.mts.map +1 -0
- package/esm/http/list-endpoint.mjs +28 -0
- package/esm/http/list-endpoint.mjs.map +1 -0
- package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
- package/esm/http/middleware/inject-request-context.mjs +12 -2
- package/esm/http/middleware/inject-request-context.mjs.map +1 -1
- package/esm/http/server.mjs +1 -1
- package/esm/index.d.mts +8 -6
- package/esm/index.mjs +3 -2
- package/esm/openapi/security.mjs +12 -4
- package/esm/openapi/security.mjs.map +1 -1
- package/esm/openapi/types.d.mts +2 -0
- package/esm/openapi/types.d.mts.map +1 -1
- package/esm/production/build-budgets.d.mts +46 -0
- package/esm/production/build-budgets.d.mts.map +1 -0
- package/esm/production/build-budgets.mjs +109 -0
- package/esm/production/build-budgets.mjs.map +1 -0
- package/esm/production/production-builder.mjs +13 -1
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/resolve-build-config.d.mts +1 -1
- package/esm/production/resolve-build-config.d.mts.map +1 -1
- package/esm/production/resolve-build-config.mjs.map +1 -1
- package/esm/restful/restful.d.mts +1 -1
- package/esm/tests/fakes/storage-fake.d.mts +3 -1
- package/esm/tests/fakes/storage-fake.d.mts.map +1 -1
- package/esm/tests/fakes/storage-fake.mjs +3 -3
- package/esm/tests/fakes/storage-fake.mjs.map +1 -1
- package/esm/tests/fakes/test-fakes.d.mts +3 -1
- package/esm/tests/fakes/test-fakes.d.mts.map +1 -1
- package/esm/tests/fakes/test-fakes.mjs +3 -2
- package/esm/tests/fakes/test-fakes.mjs.map +1 -1
- package/esm/tests/index.d.mts +4 -2
- package/esm/tests/index.mjs +3 -1
- package/esm/tests/load-unit-config.mjs +24 -0
- package/esm/tests/load-unit-config.mjs.map +1 -0
- package/esm/tests/response-contract.d.mts +32 -0
- package/esm/tests/response-contract.d.mts.map +1 -0
- package/esm/tests/response-contract.mjs +116 -0
- package/esm/tests/response-contract.mjs.map +1 -0
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +10 -2
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-lifecycle-state.mjs.map +1 -1
- package/esm/tests/test-locales.mjs +33 -0
- package/esm/tests/test-locales.mjs.map +1 -0
- package/esm/tests/test-runtime-scope.d.mts +15 -0
- package/esm/tests/test-runtime-scope.d.mts.map +1 -0
- package/esm/tests/test-runtime-scope.mjs +80 -0
- package/esm/tests/test-runtime-scope.mjs.map +1 -0
- package/esm/tests/vitest-setup.d.mts +13 -3
- package/esm/tests/vitest-setup.d.mts.map +1 -1
- package/esm/tests/vitest-setup.mjs +146 -18
- package/esm/tests/vitest-setup.mjs.map +1 -1
- package/esm/tooling/check/affected-files.d.mts +5 -0
- package/esm/tooling/check/affected-files.d.mts.map +1 -0
- package/esm/tooling/check/affected-files.mjs +56 -0
- package/esm/tooling/check/affected-files.mjs.map +1 -0
- package/esm/tooling/check/changed-files.d.mts +2 -0
- package/esm/tooling/check/changed-files.d.mts.map +1 -1
- package/esm/tooling/check/changed-files.mjs +2 -2
- package/esm/tooling/check/changed-files.mjs.map +1 -1
- package/esm/tooling/check/conventions-step.d.mts +2 -1
- package/esm/tooling/check/conventions-step.d.mts.map +1 -1
- package/esm/tooling/check/conventions-step.mjs +48 -6
- package/esm/tooling/check/conventions-step.mjs.map +1 -1
- package/esm/tooling/check/fixes.d.mts +8 -0
- package/esm/tooling/check/fixes.d.mts.map +1 -0
- package/esm/tooling/check/fixes.mjs +31 -0
- package/esm/tooling/check/fixes.mjs.map +1 -0
- package/esm/tooling/check/index.d.mts +12 -0
- package/esm/tooling/check/index.mjs +3 -2
- package/esm/tooling/check/run-check.d.mts +2 -0
- package/esm/tooling/check/run-check.d.mts.map +1 -1
- package/esm/tooling/check/run-check.mjs +20 -4
- package/esm/tooling/check/run-check.mjs.map +1 -1
- package/esm/tooling/check/run-tests.mjs +1 -1
- package/esm/tooling/check/source-ast.d.mts +1 -0
- package/esm/tooling/check/web-conventions.d.mts +10 -0
- package/esm/tooling/check/web-conventions.d.mts.map +1 -0
- package/esm/tooling/check/web-conventions.mjs +126 -0
- package/esm/tooling/check/web-conventions.mjs.map +1 -0
- package/esm/tooling/index.d.mts +7 -2
- package/esm/tooling/index.mjs +4 -2
- package/esm/tooling/inspect/collect-files.mjs +172 -0
- package/esm/tooling/inspect/collect-files.mjs.map +1 -0
- package/esm/tooling/inspect/collect-pages.mjs +3 -2
- package/esm/tooling/inspect/collect-pages.mjs.map +1 -1
- package/esm/tooling/inspect/collect-routes.mjs +1 -1
- package/esm/tooling/inspect/collect-routes.mjs.map +1 -1
- package/esm/tooling/inspect/explain-file.d.mts +12 -0
- package/esm/tooling/inspect/explain-file.d.mts.map +1 -0
- package/esm/tooling/inspect/explain-file.mjs +45 -0
- package/esm/tooling/inspect/explain-file.mjs.map +1 -0
- package/esm/tooling/inspect/index.d.mts +3 -2
- package/esm/tooling/inspect/index.mjs +2 -1
- package/esm/tooling/inspect/inspect-app.d.mts.map +1 -1
- package/esm/tooling/inspect/inspect-app.mjs +9 -3
- package/esm/tooling/inspect/inspect-app.mjs.map +1 -1
- package/esm/tooling/inspect/inspect-report.schema.mjs +34 -1
- package/esm/tooling/inspect/inspect-report.schema.mjs.map +1 -1
- package/esm/tooling/inspect/inspect-report.types.d.mts +17 -1
- package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -1
- package/esm/tooling/inspect/inspect-report.types.mjs +2 -1
- package/esm/tooling/inspect/inspect-report.types.mjs.map +1 -1
- package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -1
- package/esm/tooling/mcp/mcp-tools.mjs +8 -2
- package/esm/tooling/mcp/mcp-tools.mjs.map +1 -1
- package/esm/tooling/problem.d.mts +4 -0
- package/esm/tooling/problem.d.mts.map +1 -1
- package/esm/tooling/problem.mjs +1 -0
- package/esm/tooling/problem.mjs.map +1 -1
- package/esm/tooling/syntax/ast.d.mts +2 -0
- package/esm/tooling/typecheck/run-typecheck.mjs +5 -1
- package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -1
- package/esm/vite/index.d.mts +3 -1
- package/esm/vite/index.mjs +3 -1
- package/esm/vite/test-setup-reporter.d.mts +16 -0
- package/esm/vite/test-setup-reporter.d.mts.map +1 -0
- package/esm/vite/test-setup-reporter.mjs +55 -0
- package/esm/vite/test-setup-reporter.mjs.map +1 -0
- package/esm/vite/test-workers.d.mts +5 -0
- package/esm/vite/test-workers.d.mts.map +1 -0
- package/esm/vite/test-workers.mjs +38 -0
- package/esm/vite/test-workers.mjs.map +1 -0
- package/esm/warlock-config/index.d.mts +2 -1
- package/esm/warlock-config/types.d.mts +3 -0
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/llms-full.txt +763 -9
- package/llms.txt +2 -0
- package/package.json +15 -14
- package/schemas/inspect-report.schema.json +47 -1
- package/skills/build-budgets/SKILL.md +51 -0
- package/skills/build-restful/SKILL.md +56 -0
- package/skills/configure-app/SKILL.md +7 -0
- package/skills/create-module/SKILL.md +9 -0
- package/skills/generate-web-ui/SKILL.md +71 -0
- package/skills/index.md +2 -2
- package/skills/run-app/SKILL.md +1 -1
- package/skills/send-mail/SKILL.md +25 -0
- package/skills/send-response/SKILL.md +50 -0
- package/skills/test-browser/SKILL.md +53 -0
- package/skills/test-http/SKILL.md +91 -0
- package/skills/test-service/SKILL.md +161 -3
- package/skills/upgrade-from-5-29/SKILL.md +18 -0
- package/skills/use-localization/SKILL.md +21 -0
- package/skills/warlock-check/SKILL.md +72 -1
- package/skills/warlock-inspect/SKILL.md +45 -2
- package/skills/warlock-mcp/SKILL.md +4 -0
- package/skills/write-cli-command/SKILL.md +18 -0
- package/esm/production/build-app-production.mjs +0 -14
- package/esm/production/build-app-production.mjs.map +0 -1
package/esm/tooling/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AGENTS_MD_END, AGENTS_MD_FILE, AGENTS_MD_START, upsertGeneratedSection } from "./agents-md/agents-md-markers.mjs";
|
|
2
|
-
import { INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, InspectConfigKey, InspectEvent, InspectJob, InspectModel, InspectModelColumn, InspectModelRelation, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, JsonSchema } from "./inspect/inspect-report.types.mjs";
|
|
2
|
+
import { INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, InspectConfigKey, InspectEvent, InspectFile, InspectJob, InspectModel, InspectModelColumn, InspectModelRelation, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, JsonSchema } from "./inspect/inspect-report.types.mjs";
|
|
3
3
|
import { InstalledSkill, listInstalledSkills, parseSkillFrontMatter, shortSkillLine } from "./agents-md/installed-skills.mjs";
|
|
4
4
|
import { AgentsMdWriteStatus, WriteAgentsMdOptions, WriteAgentsMdResult, writeAgentsMd } from "./agents-md/write-agents-md.mjs";
|
|
5
5
|
import { AgentsMdRefresher, AgentsMdRefresherOptions, createAgentsMdRefresher } from "./agents-md/agents-md-refresher.mjs";
|
|
@@ -7,9 +7,11 @@ import { RenderAgentsMdOptions, listAppModules, renderAgentsMdSection } from "./
|
|
|
7
7
|
import { BOARD_DIRECTORY, BOARD_STATES, BOARD_TRANSITIONS, BOARD_VERDICT_LINES, BoardHistoryEntry, BoardInbox, BoardItem, BoardMessage, BoardState, BoardStatus, BoardVerdict, isBoardState, isBoardVerdict } from "./board/board.types.mjs";
|
|
8
8
|
import { AddBoardItemInput, InitBoardResult, MoveBoardItemOptions, SendBoardMessageInput, SendBoardMessageResult, WatchBoardOptions, WatchBoardResult, addBoardItem, assertAgentName, assertBoardTransition, boardSlug, gitignoreCoversBoard, initBoard, listBoardItems, listBoardMessages, moveBoardItem, nextBoardStates, readBoardCursor, readBoardItem, readBoardStatus, sendBoardMessage, watchBoard, writeBoardCursor } from "./board/board.mjs";
|
|
9
9
|
import { BoardMessageFields, ParsedBoardMessage, formatBoardMessage, parseBoardMessage } from "./board/board-message.mjs";
|
|
10
|
+
import { ProblemFix } from "./check/fixes.mjs";
|
|
10
11
|
import { ProblemInput, ProblemSource, ToolingProblem, createProblem } from "./problem.mjs";
|
|
11
12
|
import { GitResult, GitRunner, listChangedFiles, runGit } from "./check/changed-files.mjs";
|
|
12
13
|
import { CHECK_EXIT_CODES, CHECK_STEPS, CheckExitCode, CheckReport, CheckStep, CheckStepName, CheckStepStatus, checkExitCode } from "./check/check-report.types.mjs";
|
|
14
|
+
import { ConventionOptions } from "./check/web-conventions.mjs";
|
|
13
15
|
import { checkFileConventions, checkTsconfigConventions, isAutoLoadedFile, runConventions } from "./check/conventions-step.mjs";
|
|
14
16
|
import { MIN_NODE_VERSION, checkNodeVersion } from "./check/environment-step.mjs";
|
|
15
17
|
import { LintOutcome, runLint } from "./check/lint-step.mjs";
|
|
@@ -17,6 +19,8 @@ import { DEFAULT_TYPECHECK_BUILD_INFO, TypecheckOptions, TypecheckResult, diagno
|
|
|
17
19
|
import { VitestRun, VitestRunner, findVitest, parseVitestReport, runVitest } from "./check/tests-step.mjs";
|
|
18
20
|
import { CheckOptions, TypecheckRunner, runCheck } from "./check/run-check.mjs";
|
|
19
21
|
import { RunTestsOptions, TestRunReport, runTests, testRunArguments } from "./check/run-tests.mjs";
|
|
22
|
+
import { affectedFiles } from "./check/affected-files.mjs";
|
|
23
|
+
import "./check/index.mjs";
|
|
20
24
|
import { DEV_SERVER_STATE_FILE, DevServerState, parseDevServerState, readDevServerState, removeDevServerState, updateDevServerState, writeDevServerState } from "./dev-state/dev-server-state.mjs";
|
|
21
25
|
import { ConnectDevtoolsOptions, DEFAULT_DEVTOOLS_PATH, DevtoolsClient, DevtoolsEndpoint, DevtoolsFetch, DevtoolsPhaseRecord, DevtoolsRequestRecord, DevtoolsRequestSummaryRecord, connectDevtools, parseRequestRecord, parseRequestSummary, resolveDevServerEndpoint } from "./devtools/devtools-client.mjs";
|
|
22
26
|
import { GeneratorArgsOptions, GeneratorSpec, MAKE_GENERATORS, MAKE_GENERATOR_FLAGS, MakeGenerator, buildGeneratorArgs, isMakeGenerator } from "./generate/generator-spec.mjs";
|
|
@@ -29,6 +33,7 @@ import { AppModuleImporter } from "./inspect/collect-packages.mjs";
|
|
|
29
33
|
import { InspectOptions, inspectApp, isInspectSection, parseInspectSections } from "./inspect/inspect-app.mjs";
|
|
30
34
|
import { InspectBootResult, bootForInspect, inspectOptionsFromBoot } from "./inspect/boot-for-inspect.mjs";
|
|
31
35
|
import { INSPECT_REPORT_JSON_SCHEMA } from "./inspect/inspect-report.schema.mjs";
|
|
36
|
+
import { ExplainedFile, explainFile } from "./inspect/explain-file.mjs";
|
|
32
37
|
import "./inspect/index.mjs";
|
|
33
38
|
import { DbSchema, DbSchemaColumn, DbSchemaTable, buildDbSchema } from "./mcp/db-schema.mjs";
|
|
34
39
|
import { DOCS_CORPUS_GLOBS, DocsCorpus, DocsSearchHit, DocsSection, loadDocsCorpus, readDocsFile, searchDocs, searchTerms, splitSections } from "./mcp/docs-search.mjs";
|
|
@@ -39,4 +44,4 @@ import { AiToolsServeModule, MCP_INSTALL_HINT, ServeToolContract, isAiToolsServe
|
|
|
39
44
|
import { StartWarlockMcpServerOptions, WarlockMcpServerHandle, WarlockMcpTransport, isLoopbackHost, resolveMcpTransport, startWarlockMcpServer, toServeContract } from "./mcp/start-mcp-server.mjs";
|
|
40
45
|
import { TRACE_SCHEMA_VERSION, TraceMiddleware, TraceQuery, TraceReport, TraceValidation } from "./trace/trace-report.types.mjs";
|
|
41
46
|
import { BuildTraceReportInput, TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, TraceRequestOptions, TracedResponse, buildTraceReport, readResponseBody, redactHeaders, resolveTraceUrl, traceRequest } from "./trace/trace-request.mjs";
|
|
42
|
-
export { AGENTS_MD_END, AGENTS_MD_FILE, AGENTS_MD_START, type AddBoardItemInput, type AgentsMdRefresher, type AgentsMdRefresherOptions, type AgentsMdWriteStatus, type AiToolsServeModule, type AppModuleImporter, type ApplyGenerationOptions, BOARD_DIRECTORY, BOARD_STATES, BOARD_TRANSITIONS, BOARD_VERDICT_LINES, type BoardHistoryEntry, type BoardInbox, type BoardItem, type BoardMessage, type BoardMessageFields, type BoardState, type BoardStatus, type BoardVerdict, type BuildTraceReportInput, CHECK_EXIT_CODES, CHECK_STEPS, type CheckExitCode, type CheckOptions, type CheckReport, type CheckStep, type CheckStepName, type CheckStepStatus, type CliInvocation, type CliRun, type CliRunner, ConnectDevtoolsOptions, type CreateMcpContextOptions, DEFAULT_DEVTOOLS_PATH, DEFAULT_GENERATION_TIMEOUT_MS, DEFAULT_TYPECHECK_BUILD_INFO, DEV_SERVER_STATE_FILE, DIFF_CONTEXT_LINES, DOCS_CORPUS_GLOBS, type DbSchema, type DbSchemaColumn, type DbSchemaTable, DevServerState, DevtoolsClient, DevtoolsEndpoint, DevtoolsFetch, DevtoolsPhaseRecord, DevtoolsRequestRecord, DevtoolsRequestSummaryRecord, type DocsCorpus, type DocsSearchHit, type DocsSection, EventRecorder, type GeneratedFile, type GenerationBackend, type GenerationPlan, type GenerationPlanOptions, type GeneratorArgsOptions, type GeneratorSpec, type GitResult, type GitRunner, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, type InitBoardResult, type InspectBootResult, InspectConfigKey, InspectEvent, InspectJob, InspectModel, InspectModelColumn, type InspectModelModule, InspectModelRelation, type InspectOptions, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, type InstalledSkill, JsonSchema, type LintOutcome, MAKE_GENERATORS, MAKE_GENERATOR_FLAGS, MAX_FILE_DIFF_BYTES, MCP_INSTALL_HINT, MCP_MAKE_GENERATORS, MIN_NODE_VERSION, type MakeGenerator, type McpInputProperty, type McpInputSchema, type MoveBoardItemOptions, type ParsedBoardMessage, type ProblemInput, type ProblemSource, type RecordedListener, type RenderAgentsMdOptions, type RunTestsOptions, type SandboxBackendOptions, type SendBoardMessageInput, type SendBoardMessageResult, type ServeToolContract, type StartWarlockMcpServerOptions, TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, TRACE_SCHEMA_VERSION, type TestRunReport, type ToolingProblem, TraceMiddleware, TraceQuery, TraceReport, type TraceRequestOptions, TraceValidation, type TracedResponse, type TypecheckOptions, type TypecheckResult, type TypecheckRunner, type UnifiedDiffInput, type VitestRun, type VitestRunner, type WarlockMcpContext, type WarlockMcpServerHandle, type WarlockMcpTool, type WarlockMcpTransport, type WatchBoardOptions, type WatchBoardResult, type WriteAgentsMdOptions, type WriteAgentsMdResult, addBoardItem, applyGeneration, assertAgentName, assertBoardTransition, boardSlug, bootForInspect, buildDbSchema, buildGeneratorArgs, buildTraceReport, checkExitCode, checkFileConventions, checkNodeVersion, checkTsconfigConventions, connectDevtools, createAgentsMdRefresher, createMcpContext, createProblem, createWarlockMcpTools, describeRun, describeToolError, diagnosticToProblem, directImporters, findVitest, formatBoardMessage, gitignoreCoversBoard, groupListeners, initBoard, inputSchema, inspectApp, inspectOptionsFromBoot, isAiToolsServeModule, isAutoLoadedFile, isBoardState, isBoardVerdict, isInspectSection, isLoopbackHost, isMakeGenerator, listAppModules, listBoardItems, listBoardMessages, listChangedFiles, listInstalledSkills, loadAiToolsServe, loadDocsCorpus, makeSpecFromInput, moveBoardItem, nextBoardStates, parseBoardMessage, parseDevServerState, parseInspectSections, parseRequestRecord, parseRequestSummary, parseSkillFrontMatter, parseVitestReport, readBoardCursor, readBoardItem, readBoardStatus, readDevServerState, readDocsFile, readResponseBody, redactHeaders, removeDevServerState, renderAgentsMdSection, resolveCliEntry, resolveDevServerEndpoint, resolveMcpTransport, resolveTraceUrl, runCheck, runConventions, runGit, runLint, runTests, runTypecheck, runVitest, sandboxBackend, searchDocs, searchTerms, sendBoardMessage, shortSkillLine, spawnCli, splitSections, startWarlockMcpServer, testRunArguments, toServeContract, toStandardSchema, traceRequest, unifiedDiff, updateDevServerState, upsertGeneratedSection, validateToolInput, watchBoard, writeAgentsMd, writeBoardCursor, writeDevServerState };
|
|
47
|
+
export { AGENTS_MD_END, AGENTS_MD_FILE, AGENTS_MD_START, type AddBoardItemInput, type AgentsMdRefresher, type AgentsMdRefresherOptions, type AgentsMdWriteStatus, type AiToolsServeModule, type AppModuleImporter, type ApplyGenerationOptions, BOARD_DIRECTORY, BOARD_STATES, BOARD_TRANSITIONS, BOARD_VERDICT_LINES, type BoardHistoryEntry, type BoardInbox, type BoardItem, type BoardMessage, type BoardMessageFields, type BoardState, type BoardStatus, type BoardVerdict, type BuildTraceReportInput, CHECK_EXIT_CODES, CHECK_STEPS, type CheckExitCode, type CheckOptions, type CheckReport, type CheckStep, type CheckStepName, type CheckStepStatus, type CliInvocation, type CliRun, type CliRunner, ConnectDevtoolsOptions, type ConventionOptions, type CreateMcpContextOptions, DEFAULT_DEVTOOLS_PATH, DEFAULT_GENERATION_TIMEOUT_MS, DEFAULT_TYPECHECK_BUILD_INFO, DEV_SERVER_STATE_FILE, DIFF_CONTEXT_LINES, DOCS_CORPUS_GLOBS, type DbSchema, type DbSchemaColumn, type DbSchemaTable, DevServerState, DevtoolsClient, DevtoolsEndpoint, DevtoolsFetch, DevtoolsPhaseRecord, DevtoolsRequestRecord, DevtoolsRequestSummaryRecord, type DocsCorpus, type DocsSearchHit, type DocsSection, EventRecorder, type ExplainedFile, type GeneratedFile, type GenerationBackend, type GenerationPlan, type GenerationPlanOptions, type GeneratorArgsOptions, type GeneratorSpec, type GitResult, type GitRunner, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, type InitBoardResult, type InspectBootResult, InspectConfigKey, InspectEvent, InspectFile, InspectJob, InspectModel, InspectModelColumn, type InspectModelModule, InspectModelRelation, type InspectOptions, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, type InstalledSkill, JsonSchema, type LintOutcome, MAKE_GENERATORS, MAKE_GENERATOR_FLAGS, MAX_FILE_DIFF_BYTES, MCP_INSTALL_HINT, MCP_MAKE_GENERATORS, MIN_NODE_VERSION, type MakeGenerator, type McpInputProperty, type McpInputSchema, type MoveBoardItemOptions, type ParsedBoardMessage, type ProblemFix, type ProblemInput, type ProblemSource, type RecordedListener, type RenderAgentsMdOptions, type RunTestsOptions, type SandboxBackendOptions, type SendBoardMessageInput, type SendBoardMessageResult, type ServeToolContract, type StartWarlockMcpServerOptions, TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, TRACE_SCHEMA_VERSION, type TestRunReport, type ToolingProblem, TraceMiddleware, TraceQuery, TraceReport, type TraceRequestOptions, TraceValidation, type TracedResponse, type TypecheckOptions, type TypecheckResult, type TypecheckRunner, type UnifiedDiffInput, type VitestRun, type VitestRunner, type WarlockMcpContext, type WarlockMcpServerHandle, type WarlockMcpTool, type WarlockMcpTransport, type WatchBoardOptions, type WatchBoardResult, type WriteAgentsMdOptions, type WriteAgentsMdResult, addBoardItem, affectedFiles, applyGeneration, assertAgentName, assertBoardTransition, boardSlug, bootForInspect, buildDbSchema, buildGeneratorArgs, buildTraceReport, checkExitCode, checkFileConventions, checkNodeVersion, checkTsconfigConventions, connectDevtools, createAgentsMdRefresher, createMcpContext, createProblem, createWarlockMcpTools, describeRun, describeToolError, diagnosticToProblem, directImporters, explainFile, findVitest, formatBoardMessage, gitignoreCoversBoard, groupListeners, initBoard, inputSchema, inspectApp, inspectOptionsFromBoot, isAiToolsServeModule, isAutoLoadedFile, isBoardState, isBoardVerdict, isInspectSection, isLoopbackHost, isMakeGenerator, listAppModules, listBoardItems, listBoardMessages, listChangedFiles, listInstalledSkills, loadAiToolsServe, loadDocsCorpus, makeSpecFromInput, moveBoardItem, nextBoardStates, parseBoardMessage, parseDevServerState, parseInspectSections, parseRequestRecord, parseRequestSummary, parseSkillFrontMatter, parseVitestReport, readBoardCursor, readBoardItem, readBoardStatus, readDevServerState, readDocsFile, readResponseBody, redactHeaders, removeDevServerState, renderAgentsMdSection, resolveCliEntry, resolveDevServerEndpoint, resolveMcpTransport, resolveTraceUrl, runCheck, runConventions, runGit, runLint, runTests, runTypecheck, runVitest, sandboxBackend, searchDocs, searchTerms, sendBoardMessage, shortSkillLine, spawnCli, splitSections, startWarlockMcpServer, testRunArguments, toServeContract, toStandardSchema, traceRequest, unifiedDiff, updateDevServerState, upsertGeneratedSection, validateToolInput, watchBoard, writeAgentsMd, writeBoardCursor, writeDevServerState };
|
package/esm/tooling/index.mjs
CHANGED
|
@@ -11,15 +11,17 @@ import { formatBoardMessage, parseBoardMessage } from "./board/board-message.mjs
|
|
|
11
11
|
import { addBoardItem, assertAgentName, assertBoardTransition, boardSlug, gitignoreCoversBoard, initBoard, listBoardItems, listBoardMessages, moveBoardItem, nextBoardStates, readBoardCursor, readBoardItem, readBoardStatus, sendBoardMessage, watchBoard, writeBoardCursor } from "./board/board.mjs";
|
|
12
12
|
import { CHECK_EXIT_CODES, CHECK_STEPS, checkExitCode } from "./check/check-report.types.mjs";
|
|
13
13
|
import { createProblem } from "./problem.mjs";
|
|
14
|
+
import { checkFileConventions, checkTsconfigConventions, isAutoLoadedFile, runConventions } from "./check/conventions-step.mjs";
|
|
15
|
+
import { affectedFiles } from "./check/affected-files.mjs";
|
|
14
16
|
import { DEFAULT_TYPECHECK_BUILD_INFO, diagnosticToProblem, directImporters, runTypecheck } from "./typecheck/run-typecheck.mjs";
|
|
15
17
|
import { listChangedFiles, runGit } from "./check/changed-files.mjs";
|
|
16
|
-
import { checkFileConventions, checkTsconfigConventions, isAutoLoadedFile, runConventions } from "./check/conventions-step.mjs";
|
|
17
18
|
import { MIN_NODE_VERSION, checkNodeVersion } from "./check/environment-step.mjs";
|
|
18
19
|
import { runLint } from "./check/lint-step.mjs";
|
|
19
20
|
import { findVitest, parseVitestReport, runVitest } from "./check/tests-step.mjs";
|
|
20
21
|
import { runCheck } from "./check/run-check.mjs";
|
|
21
22
|
import { DEV_SERVER_STATE_FILE, parseDevServerState, readDevServerState, removeDevServerState, updateDevServerState, writeDevServerState } from "./dev-state/dev-server-state.mjs";
|
|
22
23
|
import { DEFAULT_DEVTOOLS_PATH, connectDevtools, parseRequestRecord, parseRequestSummary, resolveDevServerEndpoint } from "./devtools/devtools-client.mjs";
|
|
24
|
+
import { explainFile } from "./inspect/explain-file.mjs";
|
|
23
25
|
import { runTests, testRunArguments } from "./check/run-tests.mjs";
|
|
24
26
|
import { MAKE_GENERATORS, MAKE_GENERATOR_FLAGS, buildGeneratorArgs, isMakeGenerator } from "./generate/generator-spec.mjs";
|
|
25
27
|
import { DEFAULT_GENERATION_TIMEOUT_MS, describeRun, resolveCliEntry, spawnCli } from "./generate/run-cli.mjs";
|
|
@@ -42,4 +44,4 @@ import "./inspect/index.mjs";
|
|
|
42
44
|
import "./mcp/index.mjs";
|
|
43
45
|
import "./typecheck/index.mjs";
|
|
44
46
|
|
|
45
|
-
export { AGENTS_MD_END, AGENTS_MD_FILE, AGENTS_MD_START, BOARD_DIRECTORY, BOARD_STATES, BOARD_TRANSITIONS, BOARD_VERDICT_LINES, CHECK_EXIT_CODES, CHECK_STEPS, DEFAULT_DEVTOOLS_PATH, DEFAULT_GENERATION_TIMEOUT_MS, DEFAULT_TYPECHECK_BUILD_INFO, DEV_SERVER_STATE_FILE, DIFF_CONTEXT_LINES, DOCS_CORPUS_GLOBS, EventRecorder, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, MAKE_GENERATORS, MAKE_GENERATOR_FLAGS, MAX_FILE_DIFF_BYTES, MCP_INSTALL_HINT, MCP_MAKE_GENERATORS, MIN_NODE_VERSION, TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, TRACE_SCHEMA_VERSION, addBoardItem, applyGeneration, assertAgentName, assertBoardTransition, boardSlug, bootForInspect, buildDbSchema, buildGeneratorArgs, buildTraceReport, checkExitCode, checkFileConventions, checkNodeVersion, checkTsconfigConventions, connectDevtools, createAgentsMdRefresher, createMcpContext, createProblem, createWarlockMcpTools, describeRun, describeToolError, diagnosticToProblem, directImporters, findVitest, formatBoardMessage, gitignoreCoversBoard, groupListeners, initBoard, inputSchema, inspectApp, inspectOptionsFromBoot, isAiToolsServeModule, isAutoLoadedFile, isBoardState, isBoardVerdict, isInspectSection, isLoopbackHost, isMakeGenerator, listAppModules, listBoardItems, listBoardMessages, listChangedFiles, listInstalledSkills, loadAiToolsServe, loadDocsCorpus, makeSpecFromInput, moveBoardItem, nextBoardStates, parseBoardMessage, parseDevServerState, parseInspectSections, parseRequestRecord, parseRequestSummary, parseSkillFrontMatter, parseVitestReport, readBoardCursor, readBoardItem, readBoardStatus, readDevServerState, readDocsFile, readResponseBody, redactHeaders, removeDevServerState, renderAgentsMdSection, resolveCliEntry, resolveDevServerEndpoint, resolveMcpTransport, resolveTraceUrl, runCheck, runConventions, runGit, runLint, runTests, runTypecheck, runVitest, sandboxBackend, searchDocs, searchTerms, sendBoardMessage, shortSkillLine, spawnCli, splitSections, startWarlockMcpServer, testRunArguments, toServeContract, toStandardSchema, traceRequest, unifiedDiff, updateDevServerState, upsertGeneratedSection, validateToolInput, watchBoard, writeAgentsMd, writeBoardCursor, writeDevServerState };
|
|
47
|
+
export { AGENTS_MD_END, AGENTS_MD_FILE, AGENTS_MD_START, BOARD_DIRECTORY, BOARD_STATES, BOARD_TRANSITIONS, BOARD_VERDICT_LINES, CHECK_EXIT_CODES, CHECK_STEPS, DEFAULT_DEVTOOLS_PATH, DEFAULT_GENERATION_TIMEOUT_MS, DEFAULT_TYPECHECK_BUILD_INFO, DEV_SERVER_STATE_FILE, DIFF_CONTEXT_LINES, DOCS_CORPUS_GLOBS, EventRecorder, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, MAKE_GENERATORS, MAKE_GENERATOR_FLAGS, MAX_FILE_DIFF_BYTES, MCP_INSTALL_HINT, MCP_MAKE_GENERATORS, MIN_NODE_VERSION, TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, TRACE_SCHEMA_VERSION, addBoardItem, affectedFiles, applyGeneration, assertAgentName, assertBoardTransition, boardSlug, bootForInspect, buildDbSchema, buildGeneratorArgs, buildTraceReport, checkExitCode, checkFileConventions, checkNodeVersion, checkTsconfigConventions, connectDevtools, createAgentsMdRefresher, createMcpContext, createProblem, createWarlockMcpTools, describeRun, describeToolError, diagnosticToProblem, directImporters, explainFile, findVitest, formatBoardMessage, gitignoreCoversBoard, groupListeners, initBoard, inputSchema, inspectApp, inspectOptionsFromBoot, isAiToolsServeModule, isAutoLoadedFile, isBoardState, isBoardVerdict, isInspectSection, isLoopbackHost, isMakeGenerator, listAppModules, listBoardItems, listBoardMessages, listChangedFiles, listInstalledSkills, loadAiToolsServe, loadDocsCorpus, makeSpecFromInput, moveBoardItem, nextBoardStates, parseBoardMessage, parseDevServerState, parseInspectSections, parseRequestRecord, parseRequestSummary, parseSkillFrontMatter, parseVitestReport, readBoardCursor, readBoardItem, readBoardStatus, readDevServerState, readDocsFile, readResponseBody, redactHeaders, removeDevServerState, renderAgentsMdSection, resolveCliEntry, resolveDevServerEndpoint, resolveMcpTransport, resolveTraceUrl, runCheck, runConventions, runGit, runLint, runTests, runTypecheck, runVitest, sandboxBackend, searchDocs, searchTerms, sendBoardMessage, shortSkillLine, spawnCli, splitSections, startWarlockMcpServer, testRunArguments, toServeContract, toStandardSchema, traceRequest, unifiedDiff, updateDevServerState, upsertGeneratedSection, validateToolInput, watchBoard, writeAgentsMd, writeBoardCursor, writeDevServerState };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { isConfigFile, isEventFile, isLocaleFile, isMainFile, isRouteFile, isWorkerFile } from "../../dev-server/special-file-patterns.mjs";
|
|
2
|
+
import { forEachChild } from "../syntax/ast.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
|
+
import { readTsconfig, resolvePathAlias } from "get-tsconfig";
|
|
6
|
+
import { parseSync } from "oxc-parser";
|
|
7
|
+
|
|
8
|
+
//#region ../../packages/core/src/tooling/inspect/collect-files.ts
|
|
9
|
+
const CODE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
|
|
10
|
+
const EXTENSIONS = [
|
|
11
|
+
".ts",
|
|
12
|
+
".tsx",
|
|
13
|
+
".mts",
|
|
14
|
+
".cts",
|
|
15
|
+
".js",
|
|
16
|
+
".jsx",
|
|
17
|
+
".mjs",
|
|
18
|
+
".cjs",
|
|
19
|
+
".d.ts"
|
|
20
|
+
];
|
|
21
|
+
function projectFile(cwd, file) {
|
|
22
|
+
return path.relative(cwd, path.resolve(cwd, file)).split(path.sep).join("/");
|
|
23
|
+
}
|
|
24
|
+
/** Infer a role from file names and the framework's directory conventions. */
|
|
25
|
+
function fileRole(file) {
|
|
26
|
+
const stem = path.posix.basename(file).replace(CODE, "");
|
|
27
|
+
if (/(?:^|\.)(?:spec|test)$/.test(stem)) return "spec";
|
|
28
|
+
if (file.endsWith(".d.ts")) return "type";
|
|
29
|
+
if (isConfigFile(file)) return "config";
|
|
30
|
+
if (isRouteFile(file)) return "routes";
|
|
31
|
+
if (isMainFile(file)) return "main";
|
|
32
|
+
if (isWorkerFile(file)) return "worker";
|
|
33
|
+
if (isEventFile(file)) return "event";
|
|
34
|
+
if (isLocaleFile(file)) return "locale";
|
|
35
|
+
for (const role of [
|
|
36
|
+
"routes",
|
|
37
|
+
"page",
|
|
38
|
+
"setup",
|
|
39
|
+
"layout",
|
|
40
|
+
"root"
|
|
41
|
+
]) if (stem === role || stem.endsWith(`.${role}`)) return role;
|
|
42
|
+
for (const role of [
|
|
43
|
+
"controller",
|
|
44
|
+
"service",
|
|
45
|
+
"repository",
|
|
46
|
+
"model",
|
|
47
|
+
"migration",
|
|
48
|
+
"schema",
|
|
49
|
+
"resource",
|
|
50
|
+
"hook",
|
|
51
|
+
"component",
|
|
52
|
+
"util",
|
|
53
|
+
"type",
|
|
54
|
+
"config"
|
|
55
|
+
]) if (stem.endsWith(`.${role}`) || file.split("/").includes(role === "repository" ? "repositories" : `${role}s`)) return role;
|
|
56
|
+
if (file.startsWith("src/config/")) return "config";
|
|
57
|
+
if (file.split("/").includes("utils")) return "util";
|
|
58
|
+
if (/^use[A-Z]/.test(stem)) return "hook";
|
|
59
|
+
if (/\.tsx$|\.jsx$/.test(file)) return "component";
|
|
60
|
+
return "source";
|
|
61
|
+
}
|
|
62
|
+
function bindingNames(node) {
|
|
63
|
+
if (node.type === "Identifier") return [node.name];
|
|
64
|
+
if (node.type === "ObjectPattern") return node.properties.flatMap((property) => bindingNames(property.type === "RestElement" ? property.argument : property.value));
|
|
65
|
+
if (node.type === "ArrayPattern") return node.elements.flatMap((element) => element ? bindingNames(element) : []);
|
|
66
|
+
if (node.type === "AssignmentPattern") return bindingNames(node.left);
|
|
67
|
+
if (node.type === "RestElement") return bindingNames(node.argument);
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
/** Read each source module once; never import or execute application code. */
|
|
71
|
+
function collectFiles(cwd, warnings = []) {
|
|
72
|
+
cwd = path.resolve(cwd);
|
|
73
|
+
const paths = [];
|
|
74
|
+
const scan = (directory) => {
|
|
75
|
+
if (!existsSync(directory)) return;
|
|
76
|
+
try {
|
|
77
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
78
|
+
const file = path.join(directory, entry.name);
|
|
79
|
+
if (entry.isDirectory()) scan(file);
|
|
80
|
+
else if (entry.isFile()) paths.push(file);
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
warnings.push({
|
|
84
|
+
code: null,
|
|
85
|
+
source: projectFile(cwd, directory),
|
|
86
|
+
message: String(error)
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
scan(path.join(cwd, "src"));
|
|
91
|
+
paths.sort();
|
|
92
|
+
const known = new Set(paths);
|
|
93
|
+
let tsconfig;
|
|
94
|
+
try {
|
|
95
|
+
if (existsSync(path.join(cwd, "tsconfig.json"))) tsconfig = readTsconfig(path.join(cwd, "tsconfig.json"), { typescriptVersion: false });
|
|
96
|
+
} catch (error) {
|
|
97
|
+
warnings.push({
|
|
98
|
+
code: null,
|
|
99
|
+
source: "tsconfig.json",
|
|
100
|
+
message: String(error)
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const probe = (base) => {
|
|
104
|
+
const extension = path.extname(base);
|
|
105
|
+
const stem = /\.[cm]?jsx?$/.test(extension) ? base.slice(0, -extension.length) : base;
|
|
106
|
+
const candidates = stem !== base ? EXTENSIONS.map((ext) => stem + ext) : [];
|
|
107
|
+
candidates.push(base, ...EXTENSIONS.map((ext) => base + ext), ...EXTENSIONS.map((ext) => path.join(base, `index${ext}`)));
|
|
108
|
+
return candidates.find((candidate) => known.has(candidate));
|
|
109
|
+
};
|
|
110
|
+
const files = paths.map((absolute) => {
|
|
111
|
+
const file = projectFile(cwd, absolute);
|
|
112
|
+
const parts = file.split("/");
|
|
113
|
+
const record = {
|
|
114
|
+
file,
|
|
115
|
+
module: parts[1] === "app" && parts.length > 3 ? parts.slice(0, 3).join("/") : path.posix.dirname(file).split("/").slice(0, 2).join("/"),
|
|
116
|
+
role: fileRole(file),
|
|
117
|
+
exports: [],
|
|
118
|
+
imports: [],
|
|
119
|
+
importedBy: []
|
|
120
|
+
};
|
|
121
|
+
if (!CODE.test(file)) return record;
|
|
122
|
+
try {
|
|
123
|
+
const parsed = parseSync(absolute, readFileSync(absolute, "utf8"));
|
|
124
|
+
for (const error of parsed.errors) warnings.push({
|
|
125
|
+
code: null,
|
|
126
|
+
source: file,
|
|
127
|
+
message: error.message
|
|
128
|
+
});
|
|
129
|
+
const exports = /* @__PURE__ */ new Set();
|
|
130
|
+
const imports = /* @__PURE__ */ new Set();
|
|
131
|
+
for (const statement of parsed.program.body) {
|
|
132
|
+
if (statement.type === "ExportDefaultDeclaration") exports.add("default");
|
|
133
|
+
if (statement.type === "ExportAllDeclaration") exports.add(statement.exported ? statement.exported.type === "Identifier" ? statement.exported.name : String(statement.exported.value) : "*");
|
|
134
|
+
if (statement.type !== "ExportNamedDeclaration") continue;
|
|
135
|
+
for (const specifier of statement.specifiers) exports.add(specifier.exported.type === "Identifier" ? specifier.exported.name : String(specifier.exported.value));
|
|
136
|
+
const declaration = statement.declaration;
|
|
137
|
+
if (declaration?.type === "VariableDeclaration") for (const item of declaration.declarations) for (const name of bindingNames(item.id)) exports.add(name);
|
|
138
|
+
else if (declaration && "id" in declaration && declaration.id?.type === "Identifier") exports.add(declaration.id.name);
|
|
139
|
+
}
|
|
140
|
+
const visit = (node) => {
|
|
141
|
+
if ((node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration" || node.type === "TSImportType") && node.source) imports.add(String(node.source.value));
|
|
142
|
+
if (node.type === "ImportExpression" && node.source.type === "Literal" && typeof node.source.value === "string") imports.add(node.source.value);
|
|
143
|
+
if (node.type === "TSImportEqualsDeclaration" && node.moduleReference.type === "TSExternalModuleReference" && typeof node.moduleReference.expression.value === "string") imports.add(node.moduleReference.expression.value);
|
|
144
|
+
forEachChild(node, visit);
|
|
145
|
+
};
|
|
146
|
+
visit(parsed.program);
|
|
147
|
+
record.exports = [...exports].sort();
|
|
148
|
+
record.imports = [...imports].sort().map((specifier) => {
|
|
149
|
+
const resolved = (specifier.startsWith(".") ? [path.resolve(path.dirname(absolute), specifier)] : tsconfig ? resolvePathAlias(tsconfig, specifier) : []).map(probe).find((candidate) => candidate !== void 0);
|
|
150
|
+
return {
|
|
151
|
+
specifier,
|
|
152
|
+
file: resolved ? projectFile(cwd, resolved) : null
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
} catch (error) {
|
|
156
|
+
warnings.push({
|
|
157
|
+
code: null,
|
|
158
|
+
source: file,
|
|
159
|
+
message: String(error)
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return record;
|
|
163
|
+
});
|
|
164
|
+
const byFile = new Map(files.map((file) => [file.file, file]));
|
|
165
|
+
for (const file of files) for (const imported of file.imports) if (imported.file) byFile.get(imported.file)?.importedBy.push(file.file);
|
|
166
|
+
for (const file of files) file.importedBy = [...new Set(file.importedBy)].sort();
|
|
167
|
+
return files;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
export { collectFiles, fileRole, projectFile };
|
|
172
|
+
//# sourceMappingURL=collect-files.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect-files.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/collect-files.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { readTsconfig, resolvePathAlias } from \"get-tsconfig\";\nimport { parseSync, type Node } from \"oxc-parser\";\nimport {\n isConfigFile,\n isEventFile,\n isLocaleFile,\n isMainFile,\n isRouteFile,\n isWorkerFile,\n} from \"../../dev-server/special-file-patterns\";\nimport { forEachChild } from \"../syntax/ast\";\nimport type { InspectFile, InspectWarning } from \"./inspect-report.types\";\n\nconst CODE = /\\.(?:[cm]?[jt]s|[jt]sx)$/;\nconst EXTENSIONS = [\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".jsx\", \".mjs\", \".cjs\", \".d.ts\"];\n\nexport function projectFile(cwd: string, file: string): string {\n return path.relative(cwd, path.resolve(cwd, file)).split(path.sep).join(\"/\");\n}\n\n/** Infer a role from file names and the framework's directory conventions. */\nexport function fileRole(file: string): string {\n const stem = path.posix.basename(file).replace(CODE, \"\");\n if (/(?:^|\\.)(?:spec|test)$/.test(stem)) return \"spec\";\n if (file.endsWith(\".d.ts\")) return \"type\";\n if (isConfigFile(file)) return \"config\";\n if (isRouteFile(file)) return \"routes\";\n if (isMainFile(file)) return \"main\";\n if (isWorkerFile(file)) return \"worker\";\n if (isEventFile(file)) return \"event\";\n if (isLocaleFile(file)) return \"locale\";\n for (const role of [\"routes\", \"page\", \"setup\", \"layout\", \"root\"]) {\n if (stem === role || stem.endsWith(`.${role}`)) return role;\n }\n for (const role of [\n \"controller\",\n \"service\",\n \"repository\",\n \"model\",\n \"migration\",\n \"schema\",\n \"resource\",\n \"hook\",\n \"component\",\n \"util\",\n \"type\",\n \"config\",\n ]) {\n if (\n stem.endsWith(`.${role}`) ||\n file.split(\"/\").includes(role === \"repository\" ? \"repositories\" : `${role}s`)\n )\n return role;\n }\n if (file.startsWith(\"src/config/\")) return \"config\";\n if (file.split(\"/\").includes(\"utils\")) return \"util\";\n if (/^use[A-Z]/.test(stem)) return \"hook\";\n if (/\\.tsx$|\\.jsx$/.test(file)) return \"component\";\n return \"source\";\n}\n\nfunction bindingNames(node: Node): string[] {\n if (node.type === \"Identifier\") return [node.name];\n if (node.type === \"ObjectPattern\")\n return node.properties.flatMap((property) =>\n bindingNames(property.type === \"RestElement\" ? property.argument : property.value),\n );\n if (node.type === \"ArrayPattern\")\n return node.elements.flatMap((element) => (element ? bindingNames(element) : []));\n if (node.type === \"AssignmentPattern\") return bindingNames(node.left);\n if (node.type === \"RestElement\") return bindingNames(node.argument);\n return [];\n}\n\n/** Read each source module once; never import or execute application code. */\nexport function collectFiles(cwd: string, warnings: InspectWarning[] = []): InspectFile[] {\n cwd = path.resolve(cwd);\n const paths: string[] = [];\n const scan = (directory: string): void => {\n if (!existsSync(directory)) return;\n try {\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n const file = path.join(directory, entry.name);\n if (entry.isDirectory()) scan(file);\n else if (entry.isFile()) paths.push(file);\n }\n } catch (error) {\n warnings.push({ code: null, source: projectFile(cwd, directory), message: String(error) });\n }\n };\n scan(path.join(cwd, \"src\"));\n paths.sort();\n const known = new Set(paths);\n let tsconfig: ReturnType<typeof readTsconfig> | undefined;\n try {\n if (existsSync(path.join(cwd, \"tsconfig.json\")))\n tsconfig = readTsconfig(path.join(cwd, \"tsconfig.json\"), { typescriptVersion: false });\n } catch (error) {\n warnings.push({ code: null, source: \"tsconfig.json\", message: String(error) });\n }\n const probe = (base: string): string | undefined => {\n const extension = path.extname(base);\n const stem = /\\.[cm]?jsx?$/.test(extension) ? base.slice(0, -extension.length) : base;\n const candidates = stem !== base ? EXTENSIONS.map((ext) => stem + ext) : [];\n candidates.push(\n base,\n ...EXTENSIONS.map((ext) => base + ext),\n ...EXTENSIONS.map((ext) => path.join(base, `index${ext}`)),\n );\n return candidates.find((candidate) => known.has(candidate));\n };\n const files = paths.map((absolute): InspectFile => {\n const file = projectFile(cwd, absolute);\n const parts = file.split(\"/\");\n const record: InspectFile = {\n file,\n module:\n parts[1] === \"app\" && parts.length > 3\n ? parts.slice(0, 3).join(\"/\")\n : path.posix.dirname(file).split(\"/\").slice(0, 2).join(\"/\"),\n role: fileRole(file),\n exports: [],\n imports: [],\n importedBy: [],\n };\n if (!CODE.test(file)) return record;\n try {\n const parsed = parseSync(absolute, readFileSync(absolute, \"utf8\"));\n for (const error of parsed.errors)\n warnings.push({ code: null, source: file, message: error.message });\n const exports = new Set<string>();\n const imports = new Set<string>();\n for (const statement of parsed.program.body) {\n if (statement.type === \"ExportDefaultDeclaration\") exports.add(\"default\");\n if (statement.type === \"ExportAllDeclaration\")\n exports.add(\n statement.exported\n ? statement.exported.type === \"Identifier\"\n ? statement.exported.name\n : String(statement.exported.value)\n : \"*\",\n );\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n for (const specifier of statement.specifiers)\n exports.add(\n specifier.exported.type === \"Identifier\"\n ? specifier.exported.name\n : String(specifier.exported.value),\n );\n const declaration = statement.declaration;\n if (declaration?.type === \"VariableDeclaration\") {\n for (const item of declaration.declarations)\n for (const name of bindingNames(item.id)) exports.add(name);\n } else if (declaration && \"id\" in declaration && declaration.id?.type === \"Identifier\")\n exports.add(declaration.id.name);\n }\n const visit = (node: Node): void => {\n if (\n (node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportAllDeclaration\" ||\n node.type === \"TSImportType\") &&\n node.source\n )\n imports.add(String(node.source.value));\n if (\n node.type === \"ImportExpression\" &&\n node.source.type === \"Literal\" &&\n typeof node.source.value === \"string\"\n )\n imports.add(node.source.value);\n if (\n node.type === \"TSImportEqualsDeclaration\" &&\n node.moduleReference.type === \"TSExternalModuleReference\" &&\n typeof node.moduleReference.expression.value === \"string\"\n )\n imports.add(node.moduleReference.expression.value);\n forEachChild(node, visit);\n };\n visit(parsed.program);\n record.exports = [...exports].sort();\n record.imports = [...imports].sort().map((specifier) => {\n const bases = specifier.startsWith(\".\")\n ? [path.resolve(path.dirname(absolute), specifier)]\n : tsconfig\n ? resolvePathAlias(tsconfig, specifier)\n : [];\n const resolved = bases.map(probe).find((candidate) => candidate !== undefined);\n return { specifier, file: resolved ? projectFile(cwd, resolved) : null };\n });\n } catch (error) {\n warnings.push({ code: null, source: file, message: String(error) });\n }\n return record;\n });\n const byFile = new Map(files.map((file) => [file.file, file]));\n for (const file of files)\n for (const imported of file.imports) {\n if (imported.file) byFile.get(imported.file)?.importedBy.push(file.file);\n }\n for (const file of files) file.importedBy = [...new Set(file.importedBy)].sort();\n return files;\n}\n"],"mappings":"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"}
|
|
@@ -71,9 +71,10 @@ function exportsName(file, name) {
|
|
|
71
71
|
*
|
|
72
72
|
* @param pages The connector's installed page records; see {@link installedPagesFromConnectors}.
|
|
73
73
|
*/
|
|
74
|
-
function collectPages(pages, cwd, warnings) {
|
|
74
|
+
function collectPages(pages, cwd, warnings, files) {
|
|
75
75
|
if (!pages) return [];
|
|
76
76
|
const collected = [];
|
|
77
|
+
const exports = files ? new Map(files.map((file) => [file.file, file.exports])) : void 0;
|
|
77
78
|
for (const page of pages) {
|
|
78
79
|
if (!isInstalledPage(page)) {
|
|
79
80
|
warnings.push({
|
|
@@ -85,7 +86,7 @@ function collectPages(pages, cwd, warnings) {
|
|
|
85
86
|
}
|
|
86
87
|
const pageFile = path.isAbsolute(page.file) ? page.file : path.join(cwd, page.file);
|
|
87
88
|
const layouts = layoutChainOf(pageFile, cwd);
|
|
88
|
-
const loaders = [...layouts, pageFile].filter((file) => exportsName(file, "loader"));
|
|
89
|
+
const loaders = [...layouts, pageFile].filter((file) => exports ? exports.get(relativeTo(cwd, file))?.includes("loader") === true : exportsName(file, "loader"));
|
|
89
90
|
const actions = Array.isArray(page.actions) ? page.actions.filter((action) => typeof action === "string") : [];
|
|
90
91
|
collected.push({
|
|
91
92
|
path: page.path,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect-pages.mjs","names":["ast.parseSourceFile","ast.topLevelDeclarations","ast.hasModifier","ast.isVariableStatement","ast.isIdentifier","ast.nameNode","ast.valueText","ast.isFunctionDeclaration","ast.declarationName","ast.isExportDeclaration"],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/collect-pages.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport * as ast from \"../syntax/ast\";\nimport { connectorsManager } from \"../../connectors/connectors-manager\";\nimport type { InspectPage, InspectWarning } from \"./inspect-report.types\";\n\n/** The fields of `@warlock.js/web`'s installed page record that inspect reads. */\ntype InstalledPageLike = {\n path: string;\n name?: unknown;\n file: string;\n actions?: unknown;\n guard?: unknown;\n};\n\nfunction isInstalledPage(value: unknown): value is InstalledPageLike {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof Reflect.get(value, \"path\") === \"string\" &&\n typeof Reflect.get(value, \"file\") === \"string\"\n );\n}\n\n/**\n * The pages the `web` connector installed, read through its public\n * `getInstalledPages()` without importing `@warlock.js/web`. `undefined` when\n * no such connector is registered (an API-only app).\n */\nexport function installedPagesFromConnectors(): unknown[] | undefined {\n const web = connectorsManager.list().find((connector) => connector.name === \"web\");\n const read = web ? Reflect.get(web, \"getInstalledPages\") : undefined;\n\n if (typeof read !== \"function\") return undefined;\n\n const pages: unknown = read.call(web);\n\n return Array.isArray(pages) ? pages : undefined;\n}\n\nfunction toPosix(file: string): string {\n return file.split(path.sep).join(\"/\");\n}\n\nfunction relativeTo(cwd: string, file: string): string {\n return toPosix(path.isAbsolute(file) ? path.relative(cwd, file) : file);\n}\n\n/**\n * The page's layout chain, outermost first: every `layout.tsx` from the web\n * root (the nearest ancestor holding `root.tsx`, else `src/`) down to the\n * page's own directory — the rule `@warlock.js/web` applies.\n */\nexport function layoutChainOf(pageFile: string, cwd: string): string[] {\n const srcRoot = path.join(cwd, \"src\");\n const directories: string[] = [];\n let current = path.dirname(pageFile);\n\n while (current.startsWith(srcRoot)) {\n directories.unshift(current);\n\n if (existsSync(path.join(current, \"root.tsx\")) || current === srcRoot) break;\n\n const parent = path.dirname(current);\n\n if (parent === current) break;\n\n current = parent;\n }\n\n return directories\n .map((directory) => path.join(directory, \"layout.tsx\"))\n .filter((candidate) => existsSync(candidate));\n}\n\n/**\n * Whether a module's source exports a binding named `name`, read with the\n * OXC parser (the page files are TSX that Node cannot import directly).\n */\nexport function exportsName(file: string, name: string): boolean {\n let source: string;\n\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n return false;\n }\n\n const sourceFile = ast.parseSourceFile(file, source);\n\n for (const statement of ast.topLevelDeclarations(sourceFile)) {\n const exported = ast.hasModifier(statement, \"export\");\n\n if (exported && ast.isVariableStatement(statement)) {\n if (\n statement.declarations.some(\n (declaration) =>\n ast.isIdentifier(ast.nameNode(declaration)) && ast.valueText(declaration.id) === name,\n )\n ) {\n return true;\n }\n }\n\n if (\n exported &&\n ast.isFunctionDeclaration(statement) &&\n ast.declarationName(statement) === name\n ) {\n return true;\n }\n\n if (\n ast.isExportDeclaration(statement) &&\n statement.specifiers.some((element) => ast.valueText(element.exported) === name)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Describe the installed pages: route path and name, page file, layout chain,\n * the files on that chain exporting a `loader`, actions and guard.\n *\n * @param pages The connector's installed page records; see {@link installedPagesFromConnectors}.\n */\nexport function collectPages(\n pages: readonly unknown[] | undefined,\n cwd: string,\n warnings: InspectWarning[],\n): InspectPage[] {\n if (!pages) return [];\n\n const collected: InspectPage[] = [];\n\n for (const page of pages) {\n if (!isInstalledPage(page)) {\n warnings.push({ code: null, message: \"A page record has no path or file.\", source: \"pages\" });\n continue;\n }\n\n const pageFile = path.isAbsolute(page.file) ? page.file : path.join(cwd, page.file);\n const layouts = layoutChainOf(pageFile, cwd);\n const loaders = [...layouts, pageFile].filter((file)
|
|
1
|
+
{"version":3,"file":"collect-pages.mjs","names":["ast.parseSourceFile","ast.topLevelDeclarations","ast.hasModifier","ast.isVariableStatement","ast.isIdentifier","ast.nameNode","ast.valueText","ast.isFunctionDeclaration","ast.declarationName","ast.isExportDeclaration"],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/collect-pages.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport * as ast from \"../syntax/ast\";\nimport { connectorsManager } from \"../../connectors/connectors-manager\";\nimport type { InspectFile, InspectPage, InspectWarning } from \"./inspect-report.types\";\n\n/** The fields of `@warlock.js/web`'s installed page record that inspect reads. */\ntype InstalledPageLike = {\n path: string;\n name?: unknown;\n file: string;\n actions?: unknown;\n guard?: unknown;\n};\n\nfunction isInstalledPage(value: unknown): value is InstalledPageLike {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof Reflect.get(value, \"path\") === \"string\" &&\n typeof Reflect.get(value, \"file\") === \"string\"\n );\n}\n\n/**\n * The pages the `web` connector installed, read through its public\n * `getInstalledPages()` without importing `@warlock.js/web`. `undefined` when\n * no such connector is registered (an API-only app).\n */\nexport function installedPagesFromConnectors(): unknown[] | undefined {\n const web = connectorsManager.list().find((connector) => connector.name === \"web\");\n const read = web ? Reflect.get(web, \"getInstalledPages\") : undefined;\n\n if (typeof read !== \"function\") return undefined;\n\n const pages: unknown = read.call(web);\n\n return Array.isArray(pages) ? pages : undefined;\n}\n\nfunction toPosix(file: string): string {\n return file.split(path.sep).join(\"/\");\n}\n\nfunction relativeTo(cwd: string, file: string): string {\n return toPosix(path.isAbsolute(file) ? path.relative(cwd, file) : file);\n}\n\n/**\n * The page's layout chain, outermost first: every `layout.tsx` from the web\n * root (the nearest ancestor holding `root.tsx`, else `src/`) down to the\n * page's own directory — the rule `@warlock.js/web` applies.\n */\nexport function layoutChainOf(pageFile: string, cwd: string): string[] {\n const srcRoot = path.join(cwd, \"src\");\n const directories: string[] = [];\n let current = path.dirname(pageFile);\n\n while (current.startsWith(srcRoot)) {\n directories.unshift(current);\n\n if (existsSync(path.join(current, \"root.tsx\")) || current === srcRoot) break;\n\n const parent = path.dirname(current);\n\n if (parent === current) break;\n\n current = parent;\n }\n\n return directories\n .map((directory) => path.join(directory, \"layout.tsx\"))\n .filter((candidate) => existsSync(candidate));\n}\n\n/**\n * Whether a module's source exports a binding named `name`, read with the\n * OXC parser (the page files are TSX that Node cannot import directly).\n */\nexport function exportsName(file: string, name: string): boolean {\n let source: string;\n\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n return false;\n }\n\n const sourceFile = ast.parseSourceFile(file, source);\n\n for (const statement of ast.topLevelDeclarations(sourceFile)) {\n const exported = ast.hasModifier(statement, \"export\");\n\n if (exported && ast.isVariableStatement(statement)) {\n if (\n statement.declarations.some(\n (declaration) =>\n ast.isIdentifier(ast.nameNode(declaration)) && ast.valueText(declaration.id) === name,\n )\n ) {\n return true;\n }\n }\n\n if (\n exported &&\n ast.isFunctionDeclaration(statement) &&\n ast.declarationName(statement) === name\n ) {\n return true;\n }\n\n if (\n ast.isExportDeclaration(statement) &&\n statement.specifiers.some((element) => ast.valueText(element.exported) === name)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Describe the installed pages: route path and name, page file, layout chain,\n * the files on that chain exporting a `loader`, actions and guard.\n *\n * @param pages The connector's installed page records; see {@link installedPagesFromConnectors}.\n */\nexport function collectPages(\n pages: readonly unknown[] | undefined,\n cwd: string,\n warnings: InspectWarning[],\n files?: readonly InspectFile[],\n): InspectPage[] {\n if (!pages) return [];\n\n const collected: InspectPage[] = [];\n const exports = files ? new Map(files.map((file) => [file.file, file.exports])) : undefined;\n\n for (const page of pages) {\n if (!isInstalledPage(page)) {\n warnings.push({ code: null, message: \"A page record has no path or file.\", source: \"pages\" });\n continue;\n }\n\n const pageFile = path.isAbsolute(page.file) ? page.file : path.join(cwd, page.file);\n const layouts = layoutChainOf(pageFile, cwd);\n const loaders = [...layouts, pageFile].filter((file) =>\n exports\n ? exports.get(relativeTo(cwd, file))?.includes(\"loader\") === true\n : exportsName(file, \"loader\"),\n );\n const actions = Array.isArray(page.actions)\n ? page.actions.filter((action): action is string => typeof action === \"string\")\n : [];\n\n collected.push({\n path: page.path,\n name: typeof page.name === \"string\" && page.name.length > 0 ? page.name : null,\n file: relativeTo(cwd, pageFile),\n layouts: layouts.map((file) => relativeTo(cwd, file)),\n loaders: loaders.map((file) => relativeTo(cwd, file)),\n actions: [...actions].sort(),\n guard: typeof page.guard === \"string\" ? page.guard : null,\n });\n }\n\n return collected.sort((first, second) => {\n if (first.path !== second.path) return first.path < second.path ? -1 : 1;\n\n return first.file.localeCompare(second.file);\n });\n}\n"],"mappings":"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"}
|
|
@@ -134,7 +134,7 @@ function collectRoutes(routes, registry, warnings) {
|
|
|
134
134
|
isPage: route.isPage === true,
|
|
135
135
|
middleware: (route.middleware ?? []).map(functionName),
|
|
136
136
|
auth: auth ? {
|
|
137
|
-
required:
|
|
137
|
+
required: auth.required !== false,
|
|
138
138
|
sources: auth.sources,
|
|
139
139
|
userTypes: auth.userTypes
|
|
140
140
|
} : {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect-routes.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/collect-routes.ts"],"sourcesContent":["import { config } from \"../../config/config-getter\";\nimport { buildRateLimitOptions } from \"../../http/build-rate-limit-options\";\nimport type { HttpLoggingConfig } from \"../../http/request-log-snapshot\";\nimport { expandMethods } from \"../../openapi/paths\";\nimport { buildRequestParts } from \"../../openapi/request-schemas\";\nimport { buildDeclaredResponses } from \"../../openapi/response-schemas\";\nimport type { SchemaRegistry } from \"../../openapi/schema-registry\";\nimport { readRouteAuth } from \"../../openapi/security\";\nimport type { Route } from \"../../router/types\";\nimport type {\n InspectRoute,\n InspectRouteLogging,\n InspectRouteRateLimit,\n InspectWarning,\n JsonSchema,\n} from \"./inspect-report.types\";\n\n/** Display order of methods within one path, matching `warlock routes`. */\nconst METHOD_ORDER = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\", \"HEAD\", \"ALL\"];\n\nfunction methodRank(method: string): number {\n const index = METHOD_ORDER.indexOf(method);\n\n return index === -1 ? METHOD_ORDER.length : index;\n}\n\n/** The name of a function, without the `bound ` prefix `bind()` adds. */\nexport function functionName(value: unknown): string {\n if (typeof value !== \"function\") return \"anonymous\";\n\n const name = value.name.replace(/^bound /, \"\").trim();\n\n return name.length > 0 ? name : \"anonymous\";\n}\n\nfunction limitValue(value: unknown): number | \"dynamic\" | null {\n if (typeof value === \"number\") return value;\n\n return value === undefined || value === null ? null : \"dynamic\";\n}\n\nfunction windowValue(value: unknown): number | string | null {\n if (typeof value === \"number\" || typeof value === \"string\") return value;\n\n return value === undefined || value === null ? null : \"dynamic\";\n}\n\n/**\n * The limiter a route runs under: its own `rateLimit` options, else the global\n * `http.rateLimit` limiter (built with the same defaults the HTTP connector\n * uses), else none. `rateLimit: false` exempts the route from the global\n * limiter; `rateLimit: true` keeps it under the global policy.\n */\nfunction readRateLimit(\n route: Route,\n global: Record<string, unknown> | null,\n): InspectRouteRateLimit {\n if (typeof route.rateLimit === \"object\" && route.rateLimit !== null) {\n return { source: \"route\", max: route.rateLimit.max, timeWindow: route.rateLimit.timeWindow };\n }\n\n if (!global || route.rateLimit === false) {\n return { source: \"none\", max: null, timeWindow: null };\n }\n\n return {\n source: \"global\",\n max: limitValue(global.max),\n timeWindow: windowValue(global.timeWindow),\n };\n}\n\n/**\n * What the route's request logs keep: the route's `logging` option over\n * `http.logging`, the same precedence `resolveRequestLoggingOptions` applies.\n * Private URL rules can only remove more, per URL, so they are flagged rather\n * than evaluated.\n */\nfunction readLogging(route: Route, global: HttpLoggingConfig): InspectRouteLogging {\n return {\n body: route.logging?.body ?? global.body ?? true,\n query: route.logging?.query ?? global.query ?? true,\n privateRules: (global.private?.length ?? 0) > 0,\n };\n}\n\nfunction globalRateLimit(warnings: InspectWarning[]): Record<string, unknown> | null {\n try {\n const options = buildRateLimitOptions(config.get(\"http.rateLimit\"));\n\n return options ? { max: options.max, timeWindow: options.timeWindow } : null;\n } catch (error) {\n warnings.push({\n code: null,\n message: `http.rateLimit could not be read: ${error instanceof Error ? error.message : String(error)}`,\n source: \"routes\",\n });\n\n return null;\n }\n}\n\n/**\n * Describe every route: identity, middleware chain, guard, limits, logging and\n * the request/response schemas the OpenAPI generator derives (the same\n * `buildRequestParts` / `buildDeclaredResponses` code, so `inspect` and\n * `generate.openapi` never disagree). Resource `$ref`s land in `registry`.\n */\nexport function collectRoutes(\n routes: readonly Route[],\n registry: SchemaRegistry,\n warnings: InspectWarning[],\n): InspectRoute[] {\n const rateLimit = globalRateLimit(warnings);\n const logging = (config.get(\"http.logging\") ?? {}) as HttpLoggingConfig;\n\n const collected = routes.map((route): InspectRoute => {\n const method = String(route.method).toUpperCase();\n const label = `${method} ${route.path}`;\n const warn = (message: string) => {\n warnings.push({\n code: message.includes(\"JSON Schema\") ? \"WL4001\" : null,\n message: `${label}: ${message}`,\n source: route.sourceFile || null,\n });\n };\n const handler = route.handler as Route[\"handler\"] | undefined;\n const validation = handler?.validation;\n const auth = readRouteAuth(route.middleware, warn);\n const request = buildRequestParts({\n method: expandMethods(route.method)[0] ?? \"get\",\n path: route.path,\n validation,\n warn,\n });\n const body = request.requestBody?.content[\"application/json\"]?.schema;\n const responses: InspectRoute[\"responses\"] = {};\n\n for (const [status, response] of Object.entries(\n buildDeclaredResponses(handler?.responseSchema, registry, warn),\n )) {\n const schema: JsonSchema | undefined = response.content?.[\"application/json\"]?.schema;\n\n responses[status] = { description: response.description, schema: schema ?? null };\n }\n\n return {\n method,\n path: route.path,\n name: route.name ? route.name : null,\n sourceFile: route.sourceFile ? route.sourceFile : null,\n handler: functionName(handler),\n description: route.description ?? handler?.description ?? null,\n isPage: route.isPage === true,\n middleware: (route.middleware ?? []).map(functionName),\n auth: auth\n ? { required:
|
|
1
|
+
{"version":3,"file":"collect-routes.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/collect-routes.ts"],"sourcesContent":["import { config } from \"../../config/config-getter\";\nimport { buildRateLimitOptions } from \"../../http/build-rate-limit-options\";\nimport type { HttpLoggingConfig } from \"../../http/request-log-snapshot\";\nimport { expandMethods } from \"../../openapi/paths\";\nimport { buildRequestParts } from \"../../openapi/request-schemas\";\nimport { buildDeclaredResponses } from \"../../openapi/response-schemas\";\nimport type { SchemaRegistry } from \"../../openapi/schema-registry\";\nimport { readRouteAuth } from \"../../openapi/security\";\nimport type { Route } from \"../../router/types\";\nimport type {\n InspectRoute,\n InspectRouteLogging,\n InspectRouteRateLimit,\n InspectWarning,\n JsonSchema,\n} from \"./inspect-report.types\";\n\n/** Display order of methods within one path, matching `warlock routes`. */\nconst METHOD_ORDER = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\", \"HEAD\", \"ALL\"];\n\nfunction methodRank(method: string): number {\n const index = METHOD_ORDER.indexOf(method);\n\n return index === -1 ? METHOD_ORDER.length : index;\n}\n\n/** The name of a function, without the `bound ` prefix `bind()` adds. */\nexport function functionName(value: unknown): string {\n if (typeof value !== \"function\") return \"anonymous\";\n\n const name = value.name.replace(/^bound /, \"\").trim();\n\n return name.length > 0 ? name : \"anonymous\";\n}\n\nfunction limitValue(value: unknown): number | \"dynamic\" | null {\n if (typeof value === \"number\") return value;\n\n return value === undefined || value === null ? null : \"dynamic\";\n}\n\nfunction windowValue(value: unknown): number | string | null {\n if (typeof value === \"number\" || typeof value === \"string\") return value;\n\n return value === undefined || value === null ? null : \"dynamic\";\n}\n\n/**\n * The limiter a route runs under: its own `rateLimit` options, else the global\n * `http.rateLimit` limiter (built with the same defaults the HTTP connector\n * uses), else none. `rateLimit: false` exempts the route from the global\n * limiter; `rateLimit: true` keeps it under the global policy.\n */\nfunction readRateLimit(\n route: Route,\n global: Record<string, unknown> | null,\n): InspectRouteRateLimit {\n if (typeof route.rateLimit === \"object\" && route.rateLimit !== null) {\n return { source: \"route\", max: route.rateLimit.max, timeWindow: route.rateLimit.timeWindow };\n }\n\n if (!global || route.rateLimit === false) {\n return { source: \"none\", max: null, timeWindow: null };\n }\n\n return {\n source: \"global\",\n max: limitValue(global.max),\n timeWindow: windowValue(global.timeWindow),\n };\n}\n\n/**\n * What the route's request logs keep: the route's `logging` option over\n * `http.logging`, the same precedence `resolveRequestLoggingOptions` applies.\n * Private URL rules can only remove more, per URL, so they are flagged rather\n * than evaluated.\n */\nfunction readLogging(route: Route, global: HttpLoggingConfig): InspectRouteLogging {\n return {\n body: route.logging?.body ?? global.body ?? true,\n query: route.logging?.query ?? global.query ?? true,\n privateRules: (global.private?.length ?? 0) > 0,\n };\n}\n\nfunction globalRateLimit(warnings: InspectWarning[]): Record<string, unknown> | null {\n try {\n const options = buildRateLimitOptions(config.get(\"http.rateLimit\"));\n\n return options ? { max: options.max, timeWindow: options.timeWindow } : null;\n } catch (error) {\n warnings.push({\n code: null,\n message: `http.rateLimit could not be read: ${error instanceof Error ? error.message : String(error)}`,\n source: \"routes\",\n });\n\n return null;\n }\n}\n\n/**\n * Describe every route: identity, middleware chain, guard, limits, logging and\n * the request/response schemas the OpenAPI generator derives (the same\n * `buildRequestParts` / `buildDeclaredResponses` code, so `inspect` and\n * `generate.openapi` never disagree). Resource `$ref`s land in `registry`.\n */\nexport function collectRoutes(\n routes: readonly Route[],\n registry: SchemaRegistry,\n warnings: InspectWarning[],\n): InspectRoute[] {\n const rateLimit = globalRateLimit(warnings);\n const logging = (config.get(\"http.logging\") ?? {}) as HttpLoggingConfig;\n\n const collected = routes.map((route): InspectRoute => {\n const method = String(route.method).toUpperCase();\n const label = `${method} ${route.path}`;\n const warn = (message: string) => {\n warnings.push({\n code: message.includes(\"JSON Schema\") ? \"WL4001\" : null,\n message: `${label}: ${message}`,\n source: route.sourceFile || null,\n });\n };\n const handler = route.handler as Route[\"handler\"] | undefined;\n const validation = handler?.validation;\n const auth = readRouteAuth(route.middleware, warn);\n const request = buildRequestParts({\n method: expandMethods(route.method)[0] ?? \"get\",\n path: route.path,\n validation,\n warn,\n });\n const body = request.requestBody?.content[\"application/json\"]?.schema;\n const responses: InspectRoute[\"responses\"] = {};\n\n for (const [status, response] of Object.entries(\n buildDeclaredResponses(handler?.responseSchema, registry, warn),\n )) {\n const schema: JsonSchema | undefined = response.content?.[\"application/json\"]?.schema;\n\n responses[status] = { description: response.description, schema: schema ?? null };\n }\n\n return {\n method,\n path: route.path,\n name: route.name ? route.name : null,\n sourceFile: route.sourceFile ? route.sourceFile : null,\n handler: functionName(handler),\n description: route.description ?? handler?.description ?? null,\n isPage: route.isPage === true,\n middleware: (route.middleware ?? []).map(functionName),\n auth: auth\n ? { required: auth.required !== false, sources: auth.sources, userTypes: auth.userTypes }\n : { required: false, sources: [], userTypes: [] },\n csrf: route.csrf !== false,\n rateLimit: readRateLimit(route, rateLimit),\n logging: readLogging(route, logging),\n request: {\n parameters: request.parameters.map((parameter) => ({\n name: parameter.name,\n in: parameter.in,\n required: parameter.required === true,\n schema: parameter.schema,\n })),\n body: body ?? null,\n customValidation: typeof validation?.validate === \"function\",\n },\n responses,\n };\n });\n\n return collected.sort((first, second) => {\n if (first.path !== second.path) return first.path < second.path ? -1 : 1;\n\n return methodRank(first.method) - methodRank(second.method);\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { InspectFile, InspectPage, InspectReport, InspectRoute } from "./inspect-report.types.mjs";
|
|
2
|
+
//#region ../../packages/core/src/tooling/inspect/explain-file.d.ts
|
|
3
|
+
export type ExplainedFile = InspectFile & {
|
|
4
|
+
/** Entry points whose static imports transitively reach this file. */
|
|
5
|
+
routes: InspectRoute[];
|
|
6
|
+
pages: InspectPage[];
|
|
7
|
+
warnings: InspectReport["warnings"];
|
|
8
|
+
};
|
|
9
|
+
/** Explain a project-relative or absolute source path against one inspect snapshot. */
|
|
10
|
+
export declare function explainFile(requested: string, report: InspectReport): ExplainedFile;
|
|
11
|
+
//#endregion
|
|
12
|
+
//# sourceMappingURL=explain-file.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain-file.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/explain-file.ts"],"mappings":";;YAGY,gBAAgB;;EAE1B,QAAQ;EACR,OAAO;EACP,UAAU;;;wBAII,YAAY,mBAAmB,QAAQ,gBAAgB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { projectFile } from "./collect-files.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../../packages/core/src/tooling/inspect/explain-file.ts
|
|
4
|
+
/** Explain a project-relative or absolute source path against one inspect snapshot. */
|
|
5
|
+
function explainFile(requested, report) {
|
|
6
|
+
const requestedFile = projectFile(report.app.root, requested);
|
|
7
|
+
const files = new Map((report.files ?? []).map((file) => [file.file, file]));
|
|
8
|
+
const file = files.get(requestedFile);
|
|
9
|
+
if (!file) throw new Error(`Source file ${JSON.stringify(requested)} was not found under src/.`);
|
|
10
|
+
const reached = /* @__PURE__ */ new Set();
|
|
11
|
+
const pending = [file.file];
|
|
12
|
+
while (pending.length > 0) {
|
|
13
|
+
const current = pending.pop();
|
|
14
|
+
if (current === void 0 || reached.has(current)) continue;
|
|
15
|
+
reached.add(current);
|
|
16
|
+
pending.push(...files.get(current)?.importedBy ?? []);
|
|
17
|
+
}
|
|
18
|
+
const reaches = (entry) => reached.has(projectFile(report.app.root, entry));
|
|
19
|
+
return {
|
|
20
|
+
...file,
|
|
21
|
+
routes: (report.routes ?? []).filter((route) => route.sourceFile !== null && reaches(route.sourceFile)),
|
|
22
|
+
pages: (report.pages ?? []).filter((page) => [
|
|
23
|
+
page.file,
|
|
24
|
+
...page.layouts,
|
|
25
|
+
...page.loaders
|
|
26
|
+
].some(reaches)),
|
|
27
|
+
warnings: report.warnings
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function formatFileExplanation(file) {
|
|
31
|
+
return [
|
|
32
|
+
`${file.file} (${file.role})`,
|
|
33
|
+
` Module: ${file.module}`,
|
|
34
|
+
` Exports: ${file.exports.join(", ") || "none"}`,
|
|
35
|
+
` Imports: ${file.imports.map((entry) => entry.file ?? entry.specifier).join(", ") || "none"}`,
|
|
36
|
+
` Imported by: ${file.importedBy.join(", ") || "none"}`,
|
|
37
|
+
` Routes: ${file.routes.map((route) => `${route.method} ${route.path}`).join(", ") || "none"}`,
|
|
38
|
+
` Pages: ${file.pages.map((page) => page.path).join(", ") || "none"}`,
|
|
39
|
+
...file.warnings.map((warning) => ` Warning: ${warning.message}`)
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { explainFile, formatFileExplanation };
|
|
45
|
+
//# sourceMappingURL=explain-file.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain-file.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/explain-file.ts"],"sourcesContent":["import type { InspectFile, InspectPage, InspectReport, InspectRoute } from \"./inspect-report.types\";\nimport { projectFile } from \"./collect-files\";\n\nexport type ExplainedFile = InspectFile & {\n /** Entry points whose static imports transitively reach this file. */\n routes: InspectRoute[];\n pages: InspectPage[];\n warnings: InspectReport[\"warnings\"];\n};\n\n/** Explain a project-relative or absolute source path against one inspect snapshot. */\nexport function explainFile(requested: string, report: InspectReport): ExplainedFile {\n const requestedFile = projectFile(report.app.root, requested);\n const files = new Map((report.files ?? []).map((file) => [file.file, file]));\n const file = files.get(requestedFile);\n if (!file) throw new Error(`Source file ${JSON.stringify(requested)} was not found under src/.`);\n\n // Walk reverse edges once, including cycles and the entry point itself.\n const reached = new Set<string>();\n const pending = [file.file];\n while (pending.length > 0) {\n const current = pending.pop();\n if (current === undefined || reached.has(current)) continue;\n reached.add(current);\n pending.push(...(files.get(current)?.importedBy ?? []));\n }\n const reaches = (entry: string): boolean => reached.has(projectFile(report.app.root, entry));\n return {\n ...file,\n routes: (report.routes ?? []).filter(\n (route) => route.sourceFile !== null && reaches(route.sourceFile),\n ),\n pages: (report.pages ?? []).filter((page) =>\n [page.file, ...page.layouts, ...page.loaders].some(reaches),\n ),\n warnings: report.warnings,\n };\n}\n\nexport function formatFileExplanation(file: ExplainedFile): string[] {\n return [\n `${file.file} (${file.role})`,\n ` Module: ${file.module}`,\n ` Exports: ${file.exports.join(\", \") || \"none\"}`,\n ` Imports: ${file.imports.map((entry) => entry.file ?? entry.specifier).join(\", \") || \"none\"}`,\n ` Imported by: ${file.importedBy.join(\", \") || \"none\"}`,\n ` Routes: ${file.routes.map((route) => `${route.method} ${route.path}`).join(\", \") || \"none\"}`,\n ` Pages: ${file.pages.map((page) => page.path).join(\", \") || \"none\"}`,\n ...file.warnings.map((warning) => ` Warning: ${warning.message}`),\n ];\n}\n"],"mappings":";;;;AAWA,SAAgB,YAAY,WAAmB,QAAsC;CACnF,MAAM,gBAAgB,YAAY,OAAO,IAAI,MAAM,SAAS;CAC5D,MAAM,QAAQ,IAAI,KAAK,OAAO,SAAS,CAAC,EAAC,CAAE,KAAK,SAAS,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;CAC3E,MAAM,OAAO,MAAM,IAAI,aAAa;CACpC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,eAAe,KAAK,UAAU,SAAS,EAAE,2BAA2B;CAG/F,MAAM,0BAAU,IAAI,IAAY;CAChC,MAAM,UAAU,CAAC,KAAK,IAAI;CAC1B,OAAO,QAAQ,SAAS,GAAG;EACzB,MAAM,UAAU,QAAQ,IAAI;EAC5B,IAAI,YAAY,UAAa,QAAQ,IAAI,OAAO,GAAG;EACnD,QAAQ,IAAI,OAAO;EACnB,QAAQ,KAAK,GAAI,MAAM,IAAI,OAAO,CAAC,EAAE,cAAc,CAAC,CAAE;CACxD;CACA,MAAM,WAAW,UAA2B,QAAQ,IAAI,YAAY,OAAO,IAAI,MAAM,KAAK,CAAC;CAC3F,OAAO;EACL,GAAG;EACH,SAAS,OAAO,UAAU,CAAC,EAAC,CAAE,QAC3B,UAAU,MAAM,eAAe,QAAQ,QAAQ,MAAM,UAAU,CAClE;EACA,QAAQ,OAAO,SAAS,CAAC,EAAC,CAAE,QAAQ,SAClC;GAAC,KAAK;GAAM,GAAG,KAAK;GAAS,GAAG,KAAK;EAAO,CAAC,CAAC,KAAK,OAAO,CAC5D;EACA,UAAU,OAAO;CACnB;AACF;AAEA,SAAgB,sBAAsB,MAA+B;CACnE,OAAO;EACL,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK;EAC5B,aAAa,KAAK;EAClB,cAAc,KAAK,QAAQ,KAAK,IAAI,KAAK;EACzC,cAAc,KAAK,QAAQ,KAAK,UAAU,MAAM,QAAQ,MAAM,SAAS,CAAC,CAAC,KAAK,IAAI,KAAK;EACvF,kBAAkB,KAAK,WAAW,KAAK,IAAI,KAAK;EAChD,aAAa,KAAK,OAAO,KAAK,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC,KAAK,IAAI,KAAK;EACvF,YAAY,KAAK,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK;EAC9D,GAAG,KAAK,SAAS,KAAK,YAAY,cAAc,QAAQ,SAAS;CACnE;AACF"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, InspectConfigKey, InspectEvent, InspectJob, InspectModel, InspectModelColumn, InspectModelRelation, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, JsonSchema } from "./inspect-report.types.mjs";
|
|
1
|
+
import { INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, InspectConfigKey, InspectEvent, InspectFile, InspectJob, InspectModel, InspectModelColumn, InspectModelRelation, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, JsonSchema } from "./inspect-report.types.mjs";
|
|
2
2
|
import { EventRecorder, RecordedListener, groupListeners } from "./event-recorder.mjs";
|
|
3
3
|
import { InspectModelModule } from "./collect-models.mjs";
|
|
4
4
|
import { AppModuleImporter } from "./collect-packages.mjs";
|
|
5
5
|
import { InspectOptions, inspectApp, isInspectSection, parseInspectSections } from "./inspect-app.mjs";
|
|
6
6
|
import { InspectBootResult, bootForInspect, inspectOptionsFromBoot } from "./boot-for-inspect.mjs";
|
|
7
7
|
import { INSPECT_REPORT_JSON_SCHEMA } from "./inspect-report.schema.mjs";
|
|
8
|
-
|
|
8
|
+
import { ExplainedFile, explainFile } from "./explain-file.mjs";
|
|
9
|
+
export { type AppModuleImporter, EventRecorder, type ExplainedFile, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, type InspectBootResult, InspectConfigKey, InspectEvent, InspectFile, InspectJob, InspectModel, InspectModelColumn, type InspectModelModule, InspectModelRelation, type InspectOptions, InspectPackage, InspectPage, InspectParameter, InspectReport, InspectResource, InspectRoute, InspectRouteAuth, InspectRouteLogging, InspectRouteRateLimit, InspectSchedule, InspectSection, InspectWarning, JsonSchema, type RecordedListener, bootForInspect, explainFile, groupListeners, inspectApp, inspectOptionsFromBoot, isInspectSection, parseInspectSections };
|
|
@@ -2,6 +2,7 @@ import { EventRecorder, groupListeners } from "./event-recorder.mjs";
|
|
|
2
2
|
import { bootForInspect, inspectOptionsFromBoot } from "./boot-for-inspect.mjs";
|
|
3
3
|
import { INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS } from "./inspect-report.types.mjs";
|
|
4
4
|
import { inspectApp, isInspectSection, parseInspectSections } from "./inspect-app.mjs";
|
|
5
|
+
import { explainFile } from "./explain-file.mjs";
|
|
5
6
|
import { INSPECT_REPORT_JSON_SCHEMA } from "./inspect-report.schema.mjs";
|
|
6
7
|
|
|
7
|
-
export { EventRecorder, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, bootForInspect, groupListeners, inspectApp, inspectOptionsFromBoot, isInspectSection, parseInspectSections };
|
|
8
|
+
export { EventRecorder, INSPECT_REPORT_JSON_SCHEMA, INSPECT_SCHEMA_VERSION, INSPECT_SECTIONS, bootForInspect, explainFile, groupListeners, inspectApp, inspectOptionsFromBoot, isInspectSection, parseInspectSections };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect-app.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/inspect-app.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"inspect-app.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/inspect/inspect-app.ts"],"mappings":";;;;;;;YA2BY;;EAEV;;EAEA,oBAAoB;;EAEpB,kBAAkB;;EAElB,wBAAwB;;EAExB,kBAAkB;;EAElB,oBAAoB;;EAEpB;IAA4B;IAAc;;;EAE1C;;;;;EAKA,uBAAuB;;EAEvB,SAAS;;EAET,gBAAgB;;EAEhB,YAAY;;;wBAIE,iBAAiB,gBAAgB,SAAS;;;;;wBAQ1C,qBAAqB,4BAA4B;;;;;;;;;;;;;;wBA+B3C,WAAW,UAAS,iBAAsB,QAAQ"}
|
|
@@ -2,6 +2,7 @@ import { Application } from "../../application/application.mjs";
|
|
|
2
2
|
import { router } from "../../router/router.mjs";
|
|
3
3
|
import { SchemaRegistry } from "../../openapi/schema-registry.mjs";
|
|
4
4
|
import { groupListeners } from "./event-recorder.mjs";
|
|
5
|
+
import { collectFiles } from "./collect-files.mjs";
|
|
5
6
|
import { collectConfig } from "./collect-config.mjs";
|
|
6
7
|
import { collectModels, collectResources } from "./collect-models.mjs";
|
|
7
8
|
import { collectJobs, collectPackages, collectSchedules, createAppModuleImporter, readAppPackage } from "./collect-packages.mjs";
|
|
@@ -72,14 +73,19 @@ async function inspectApp(options = {}) {
|
|
|
72
73
|
components: { schemas: {} },
|
|
73
74
|
warnings
|
|
74
75
|
};
|
|
75
|
-
const
|
|
76
|
-
const
|
|
76
|
+
const filesOnly = sections.every((section) => section === "files");
|
|
77
|
+
const routes = !filesOnly ? collectRoutes(options.routes ?? router.list(), registry, warnings) : [];
|
|
78
|
+
const { models, resourceModels } = !filesOnly ? collectModels(options.modelModules ?? [], registry, warnings) : {
|
|
79
|
+
models: [],
|
|
80
|
+
resourceModels: /* @__PURE__ */ new Map()
|
|
81
|
+
};
|
|
82
|
+
if (wants.has("files")) report.files = collectFiles(cwd, warnings);
|
|
77
83
|
if (wants.has("routes")) report.routes = routes;
|
|
78
84
|
if (wants.has("models")) report.models = models;
|
|
79
85
|
if (wants.has("resources")) report.resources = collectResources(registry, resourceModels);
|
|
80
86
|
if (wants.has("config")) report.config = collectConfig(cwd, options.config);
|
|
81
87
|
if (wants.has("events")) report.events = groupListeners(options.events ?? []);
|
|
82
|
-
if (wants.has("pages")) report.pages = collectPages(options.pages ?? installedPagesFromConnectors(), cwd, warnings);
|
|
88
|
+
if (wants.has("pages")) report.pages = collectPages(options.pages ?? installedPagesFromConnectors(), cwd, warnings, report.files);
|
|
83
89
|
if (wants.has("jobs")) report.jobs = await collectJobs(importFromApp, warnings);
|
|
84
90
|
if (wants.has("schedules")) report.schedules = await collectSchedules(importFromApp, warnings);
|
|
85
91
|
if (wants.has("packages")) report.packages = collectPackages(cwd);
|