@ankhorage/doctor 0.7.3 → 0.9.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 +12 -0
- package/dist/analysis.d.ts +2 -0
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js.map +1 -1
- package/dist/authReadinessAnalysis.d.ts +8 -0
- package/dist/authReadinessAnalysis.d.ts.map +1 -0
- package/dist/authReadinessAnalysis.js +38 -0
- package/dist/authReadinessAnalysis.js.map +1 -0
- package/dist/authReadinessDiagnostic.d.ts +9 -0
- package/dist/authReadinessDiagnostic.d.ts.map +1 -0
- package/dist/authReadinessDiagnostic.js +11 -0
- package/dist/authReadinessDiagnostic.js.map +1 -0
- package/dist/authReadinessEnvironment.d.ts +16 -0
- package/dist/authReadinessEnvironment.d.ts.map +1 -0
- package/dist/authReadinessEnvironment.js +29 -0
- package/dist/authReadinessEnvironment.js.map +1 -0
- package/dist/authReadinessFileAnalysis.d.ts +3 -0
- package/dist/authReadinessFileAnalysis.d.ts.map +1 -0
- package/dist/authReadinessFileAnalysis.js +12 -0
- package/dist/authReadinessFileAnalysis.js.map +1 -0
- package/dist/authReadinessNativeDiagnostic.d.ts +4 -0
- package/dist/authReadinessNativeDiagnostic.d.ts.map +1 -0
- package/dist/authReadinessNativeDiagnostic.js +11 -0
- package/dist/authReadinessNativeDiagnostic.js.map +1 -0
- package/dist/authReadinessProvider.d.ts +15 -0
- package/dist/authReadinessProvider.d.ts.map +1 -0
- package/dist/authReadinessProvider.js +44 -0
- package/dist/authReadinessProvider.js.map +1 -0
- package/dist/authReadinessProviderEnvironment.d.ts +15 -0
- package/dist/authReadinessProviderEnvironment.d.ts.map +1 -0
- package/dist/authReadinessProviderEnvironment.js +35 -0
- package/dist/authReadinessProviderEnvironment.js.map +1 -0
- package/dist/authReadinessRequirements.d.ts +10 -0
- package/dist/authReadinessRequirements.d.ts.map +1 -0
- package/dist/authReadinessRequirements.js +34 -0
- package/dist/authReadinessRequirements.js.map +1 -0
- package/dist/authReadinessTargetFallback.d.ts +3 -0
- package/dist/authReadinessTargetFallback.d.ts.map +1 -0
- package/dist/authReadinessTargetFallback.js +32 -0
- package/dist/authReadinessTargetFallback.js.map +1 -0
- package/dist/authReadinessTargetResolution.d.ts +8 -0
- package/dist/authReadinessTargetResolution.d.ts.map +1 -0
- package/dist/authReadinessTargetResolution.js +2 -0
- package/dist/authReadinessTargetResolution.js.map +1 -0
- package/dist/authReadinessTargets.d.ts +3 -0
- package/dist/authReadinessTargets.d.ts.map +1 -0
- package/dist/authReadinessTargets.js +26 -0
- package/dist/authReadinessTargets.js.map +1 -0
- package/dist/authReadinessUnsupported.d.ts +13 -0
- package/dist/authReadinessUnsupported.d.ts.map +1 -0
- package/dist/authReadinessUnsupported.js +22 -0
- package/dist/authReadinessUnsupported.js.map +1 -0
- package/dist/authReadinessUnsupportedBackend.d.ts +12 -0
- package/dist/authReadinessUnsupportedBackend.d.ts.map +1 -0
- package/dist/authReadinessUnsupportedBackend.js +18 -0
- package/dist/authReadinessUnsupportedBackend.js.map +1 -0
- package/dist/bunPolicyAnalysis.d.ts +3 -0
- package/dist/bunPolicyAnalysis.d.ts.map +1 -0
- package/dist/bunPolicyAnalysis.js +190 -0
- package/dist/bunPolicyAnalysis.js.map +1 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +14 -0
- package/dist/commands.js.map +1 -1
- package/dist/dependencyPolicyAnalysis.d.ts.map +1 -1
- package/dist/dependencyPolicyAnalysis.js +6 -2
- package/dist/dependencyPolicyAnalysis.js.map +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/manifestAnalysis.d.ts.map +1 -1
- package/dist/manifestAnalysis.js +4 -1
- package/dist/manifestAnalysis.js.map +1 -1
- package/dist/readiness.d.ts +13 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +2 -0
- package/dist/readiness.js.map +1 -0
- package/package.json +3 -2
- package/src/analysis.ts +2 -0
- package/src/authReadinessAnalysis.ts +50 -0
- package/src/authReadinessDiagnostic.ts +18 -0
- package/src/authReadinessEnvironment.ts +51 -0
- package/src/authReadinessFileAnalysis.ts +14 -0
- package/src/authReadinessNativeDiagnostic.ts +17 -0
- package/src/authReadinessProvider.ts +61 -0
- package/src/authReadinessProviderEnvironment.ts +54 -0
- package/src/authReadinessRequirements.ts +50 -0
- package/src/authReadinessTargetFallback.ts +38 -0
- package/src/authReadinessTargetResolution.ts +9 -0
- package/src/authReadinessTargets.ts +35 -0
- package/src/authReadinessUnsupported.ts +34 -0
- package/src/authReadinessUnsupportedBackend.ts +34 -0
- package/src/bunPolicyAnalysis.ts +261 -0
- package/src/commands.ts +16 -0
- package/src/dependencyPolicyAnalysis.ts +9 -4
- package/src/diagnostics.ts +9 -0
- package/src/index.ts +3 -0
- package/src/manifestAnalysis.ts +4 -1
- package/src/readiness.ts +14 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunPolicyAnalysis.js","sourceRoot":"","sources":["../src/bunPolicyAnalysis.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport type { DoctorAnalysisResult } from './analysis.js';\nimport type { DoctorDiagnostic, DoctorRuleId } from './diagnostics.js';\n\ninterface BunRuntimePolicySnapshot {\n readonly packageManager: string;\n readonly typesRange: string;\n readonly version: string;\n}\n\nconst DEVTOOLS_POLICY_SPECIFIER = '@ankhorage/devtools/policy';\nconst REPAIR_HINT = 'Run \"ankh devtools sync\" to repair the managed Bun state.';\nconst BUN_VERSION_PATTERN = /^\\s*bun-version:\\s*['\"]?([^'\"\\s#]+)['\"]?\\s*(?:#.*)?$/mu;\nconst WORKFLOWS = [\n {\n relativePath: path.join('.github', 'workflows', 'ci.yml'),\n ruleId: 'repo.workflows.ci.bun-policy',\n },\n {\n relativePath: path.join('.github', 'workflows', 'release.yml'),\n ruleId: 'repo.workflows.release.bun-policy',\n },\n] as const satisfies readonly { readonly relativePath: string; readonly ruleId: DoctorRuleId }[];\n\nexport async function applyBunRuntimePolicy(\n result: DoctorAnalysisResult,\n): Promise<DoctorAnalysisResult> {\n if (result.profile !== 'public-package' || !result.hasPackageJson) {\n return result;\n }\n\n const policy = await loadTargetBunRuntimePolicy(result.targetPath);\n const packageJsonPath = path.join(result.targetPath, 'package.json');\n const packageJson = await readPackageJson(packageJsonPath);\n if (policy === null || packageJson === null) {\n return result;\n }\n\n const diagnostics = [\n ...result.diagnostics,\n ...analyzePackageBunPolicy(packageJson, packageJsonPath, result, policy),\n ...(await analyzeWorkflowBunPolicy(result, policy)),\n ];\n\n return withDiagnostics(result, diagnostics);\n}\n\nasync function loadTargetBunRuntimePolicy(\n targetPath: string,\n): Promise<BunRuntimePolicySnapshot | null> {\n const requireFromTarget = createRequire(path.join(targetPath, 'package.json'));\n try {\n const modulePath = requireFromTarget.resolve(DEVTOOLS_POLICY_SPECIFIER);\n const importedModule = (await import(pathToFileURL(modulePath).href)) as unknown;\n return parseBunRuntimePolicy(importedModule);\n } catch (error) {\n if (isUnavailablePolicyError(error)) {\n return null;\n }\n throw error;\n }\n}\n\nfunction analyzePackageBunPolicy(\n packageJson: Record<string, unknown>,\n packageJsonPath: string,\n result: DoctorAnalysisResult,\n policy: BunRuntimePolicySnapshot,\n): DoctorDiagnostic[] {\n const diagnostics: DoctorDiagnostic[] = [];\n const { packageManager } = packageJson;\n if (isNonEmptyString(packageManager) && packageManager.startsWith('bun@')) {\n pushMismatch(diagnostics, {\n actual: packageManager,\n expected: policy.packageManager,\n location: 'package.json#packageManager',\n path: packageJsonPath,\n profile: result.profile,\n ruleId: 'package.json.package-manager.policy',\n });\n }\n\n const devDependencies = isRecord(packageJson.devDependencies)\n ? packageJson.devDependencies\n : null;\n const bunTypes = devDependencies?.['@types/bun'];\n if (isNonEmptyString(bunTypes)) {\n pushMismatch(diagnostics, {\n actual: bunTypes,\n expected: policy.typesRange,\n location: 'package.json#devDependencies.@types/bun',\n path: packageJsonPath,\n profile: result.profile,\n ruleId: 'package.dependencies.types-bun.policy',\n });\n }\n\n return diagnostics;\n}\n\nasync function analyzeWorkflowBunPolicy(\n result: DoctorAnalysisResult,\n policy: BunRuntimePolicySnapshot,\n): Promise<DoctorDiagnostic[]> {\n const diagnostics = await Promise.all(\n WORKFLOWS.map(async (workflow) => await analyzeWorkflow(result, workflow, policy)),\n );\n return diagnostics.flat();\n}\n\nasync function analyzeWorkflow(\n result: DoctorAnalysisResult,\n workflow: (typeof WORKFLOWS)[number],\n policy: BunRuntimePolicySnapshot,\n): Promise<DoctorDiagnostic[]> {\n const workflowPath = path.join(result.targetPath, workflow.relativePath);\n const contents = await readTextOrNull(workflowPath);\n if (contents === null) {\n return [createWorkflowDiagnostic(result, workflow, policy, workflowPath, 'missing-path')];\n }\n\n const match = BUN_VERSION_PATTERN.exec(contents);\n const actual = match?.[1];\n if (!isNonEmptyString(actual)) {\n return [createWorkflowDiagnostic(result, workflow, policy, workflowPath, 'field-missing')];\n }\n\n const diagnostics: DoctorDiagnostic[] = [];\n pushMismatch(diagnostics, {\n actual,\n expected: policy.version,\n location: `${workflow.relativePath}#bun-version`,\n path: workflowPath,\n profile: result.profile,\n ruleId: workflow.ruleId,\n });\n return diagnostics;\n}\n\nfunction createWorkflowDiagnostic(\n result: DoctorAnalysisResult,\n workflow: (typeof WORKFLOWS)[number],\n policy: BunRuntimePolicySnapshot,\n workflowPath: string,\n code: DoctorDiagnostic['code'],\n): DoctorDiagnostic {\n const detail =\n code === 'missing-path'\n ? `Managed workflow is missing: ${workflow.relativePath}.`\n : `${workflow.relativePath} does not define bun-version.`;\n return {\n code,\n message: `${detail} Expected Bun ${policy.version}. ${REPAIR_HINT}`,\n path: workflowPath,\n profile: result.profile,\n ruleId: workflow.ruleId,\n severity: 'error',\n };\n}\n\nfunction pushMismatch(\n diagnostics: DoctorDiagnostic[],\n input: {\n readonly actual: string;\n readonly expected: string;\n readonly location: string;\n readonly path: string;\n readonly profile: DoctorAnalysisResult['profile'];\n readonly ruleId: DoctorRuleId;\n },\n): void {\n if (input.actual === input.expected) {\n return;\n }\n diagnostics.push({\n code: 'field-invalid',\n message: `Bun policy drift at ${input.location}: expected \"${input.expected}\", found \"${input.actual}\". ${REPAIR_HINT}`,\n path: input.path,\n profile: input.profile,\n ruleId: input.ruleId,\n severity: 'error',\n });\n}\n\nfunction parseBunRuntimePolicy(importedModule: unknown): BunRuntimePolicySnapshot | null {\n if (!isRecord(importedModule) || !isRecord(importedModule.bunRuntimePolicy)) {\n return null;\n }\n const { packageManager, typesRange, version } = importedModule.bunRuntimePolicy;\n return isNonEmptyString(packageManager) &&\n isNonEmptyString(typesRange) &&\n isNonEmptyString(version)\n ? { packageManager, typesRange, version }\n : null;\n}\n\nfunction withDiagnostics(\n result: DoctorAnalysisResult,\n diagnostics: readonly DoctorDiagnostic[],\n): DoctorAnalysisResult {\n return {\n ...result,\n diagnostics,\n fixPlan: result.fixPlan === null ? null : { ...result.fixPlan, diagnostics },\n };\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<Record<string, unknown> | null> {\n try {\n const parsed = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')) as unknown;\n return isRecord(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n\nasync function readTextOrNull(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch (error) {\n if (isNodeError(error) && error.code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n}\n\nfunction isUnavailablePolicyError(error: unknown): boolean {\n if (\n isNodeError(error) &&\n (error.code === 'MODULE_NOT_FOUND' ||\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED')\n ) {\n return true;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return (\n message.includes(DEVTOOLS_POLICY_SPECIFIER) &&\n (message.includes('Cannot find module') ||\n message.includes('not exported') ||\n message.includes('Package subpath'))\n );\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && 'code' in error;\n}\n"]}
|
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAExF,OAAO,KAAK,EAA6C,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,gCAAgC,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAExF,OAAO,KAAK,EAA6C,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,gCAAgC,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AASxF,KAAK,iBAAiB,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjE,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,KAAK,2BAA2B,GAAG,CACjC,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,KAC5B,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAErC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,2BAA2B,CAAC;CAC3C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,OAAO,gCAAgC,CAAC;CACjE;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACpD;AAED,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,uBAAuB,EAChC,OAAO,CAAC,EAAE,uBAAuB,KAC9B,OAAO,CAAC,sBAAsB,CAAC,CAAC;AASrC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC2B,CAAC;AAExD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,EAChC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAqBjC;AAED,wBAAgB,gCAAgC,IAAI,SAAS,qBAAqB,EAAE,CAMnF;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAE/F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBtD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AA4CD,iBAAe,kBAAkB,CAC/B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,iBAAe,aAAa,CAC1B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,iBAAe,cAAc,CAC3B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,iBAAe,iBAAiB,CAC9B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC"}
|
package/dist/commands.js
CHANGED
|
@@ -182,6 +182,17 @@ function renderAnalysisReport(commandName, result) {
|
|
|
182
182
|
lines.push(renderDiagnosticLine(diagnostic));
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
+
const readiness = result.readiness ?? [];
|
|
186
|
+
lines.push('');
|
|
187
|
+
lines.push('Readiness:');
|
|
188
|
+
if (readiness.length === 0) {
|
|
189
|
+
lines.push(' none');
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
for (const item of readiness) {
|
|
193
|
+
lines.push(renderReadinessLine(item));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
185
196
|
if (commandName === 'fix') {
|
|
186
197
|
lines.push('');
|
|
187
198
|
lines.push('Planned changes:');
|
|
@@ -204,6 +215,9 @@ function renderAnalysisReport(commandName, result) {
|
|
|
204
215
|
function renderDiagnosticLine(diagnostic) {
|
|
205
216
|
return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.ruleId} (${diagnostic.code}): ${diagnostic.message}`;
|
|
206
217
|
}
|
|
218
|
+
function renderReadinessLine(item) {
|
|
219
|
+
return ` - ${item.target} ${item.environment} ${item.provider} ${item.transport}: ${item.status} — ${item.message}`;
|
|
220
|
+
}
|
|
207
221
|
function renderPlannedChangeLine(change) {
|
|
208
222
|
return ` - ${change.ruleId} [${change.kind}]: ${change.description}`;
|
|
209
223
|
}
|
package/dist/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnkhCapabilityId, AnkhCommandDescriptor } from '@ankhorage/contracts/cli';\n\nimport type { DoctorAnalysisResult, DoctorPlannedChange, DoctorTargetMode } from './analysis.js';\nimport { analyzeDoctorTargetWithCliLayout } from './cliLayoutAnalysis.js';\nimport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nimport {\n countErrorDiagnostics,\n countWarningDiagnostics,\n type DoctorDiagnostic,\n} from './diagnostics.js';\nimport { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY } from './packageMetadata.js';\n\ntype DoctorCommandName = 'fix' | 'package' | 'repo' | 'validate';\n\ninterface DoctorCommandRunRequest {\n readonly context: DoctorCommandContext;\n readonly inputPath?: string;\n}\n\ntype DoctorCommandImplementation = (\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n) => Promise<DoctorCommandRunResult>;\n\nexport interface DoctorCommandDefinition {\n readonly capability: AnkhCapabilityId;\n readonly mode: DoctorTargetMode;\n readonly path: readonly [DoctorCommandName];\n readonly standaloneName: DoctorCommandName;\n readonly summary: string;\n readonly run: DoctorCommandImplementation;\n}\n\nexport interface DoctorCommandInvocation {\n readonly argv: readonly string[];\n readonly command: DoctorCommandDefinition;\n readonly context: DoctorCommandContext;\n}\n\nexport interface DoctorCommandServices {\n readonly analyzeTarget: typeof analyzeDoctorTargetWithCliLayout;\n}\n\nexport interface RunDoctorCommandOptions {\n readonly runCommandImpl?: RunDoctorCommandImpl;\n readonly services?: Partial<DoctorCommandServices>;\n}\n\nexport type RunDoctorCommandImpl = (\n request: DoctorCommandInvocation,\n options?: RunDoctorCommandOptions,\n) => Promise<DoctorCommandRunResult>;\n\nconst COMMAND_CAPABILITIES = {\n validate: DOCTOR_CAPABILITIES[0],\n fix: DOCTOR_CAPABILITIES[1],\n repo: DOCTOR_CAPABILITIES[2],\n package: DOCTOR_CAPABILITIES[3],\n} as const satisfies Record<DoctorCommandName, AnkhCapabilityId>;\n\nexport const DOCTOR_COMMANDS = [\n {\n standaloneName: 'validate',\n path: ['validate'],\n capability: COMMAND_CAPABILITIES.validate,\n mode: 'validate',\n summary:\n 'Validate a repo, package, or app-manifest JSON path with the applicable Doctor profile.',\n run: runValidateCommand,\n },\n {\n standaloneName: 'fix',\n path: ['fix'],\n capability: COMMAND_CAPABILITIES.fix,\n mode: 'fix',\n summary: 'Build a non-mutating fix plan for deterministic doctor policy violations.',\n run: runFixCommand,\n },\n {\n standaloneName: 'repo',\n path: ['repo'],\n capability: COMMAND_CAPABILITIES.repo,\n mode: 'repo',\n summary: 'Force repo-light diagnostics for a repo/workspace-root candidate path.',\n run: runRepoCommand,\n },\n {\n standaloneName: 'package',\n path: ['package'],\n capability: COMMAND_CAPABILITIES.package,\n mode: 'package',\n summary: 'Force package-light diagnostics for a directory containing package.json.',\n run: runPackageCommand,\n },\n] as const satisfies readonly DoctorCommandDefinition[];\n\nexport async function runDoctorCommand(\n request: DoctorCommandInvocation,\n options: RunDoctorCommandOptions = {},\n): Promise<DoctorCommandRunResult> {\n const services = createDoctorCommandServices(options.services);\n\n try {\n const parsedArgs = parseCommandArguments(request.command, request.argv);\n if (parsedArgs.kind === 'help') {\n request.context.writeStdout(renderCommandHelp(request.command));\n return { exitCode: 0 };\n }\n\n return await request.command.run(\n {\n context: request.context,\n inputPath: parsedArgs.inputPath,\n },\n services,\n );\n } catch (error) {\n request.context.writeStderr(renderCommandFailure(request.command.standaloneName, error));\n return { exitCode: 1 };\n }\n}\n\nexport function createProviderCommandDescriptors(): readonly AnkhCommandDescriptor[] {\n return DOCTOR_COMMANDS.map((command) => ({\n capability: command.capability,\n path: command.path,\n summary: command.summary,\n }));\n}\n\nexport function findDoctorCommandByStandaloneName(value: string): DoctorCommandDefinition | null {\n return DOCTOR_COMMANDS.find((command) => command.standaloneName === value) ?? null;\n}\n\nexport function renderRootHelp(version: string): string {\n const commandLines = DOCTOR_COMMANDS.map(\n (command) => ` ${command.standaloneName.padEnd(8, ' ')} ${command.summary}`,\n ).join('\\n');\n\n return [\n `@ankhorage/doctor v${version}`,\n '',\n 'Usage:',\n ' ankhorage-doctor <command> [path]',\n ` ankh ${DOCTOR_COMMAND_CATEGORY} <command> [path]`,\n '',\n 'Commands:',\n commandLines,\n '',\n 'Path resolution:',\n ' Pass a repo/package directory or app-manifest JSON file, or omit [path] to inspect the current directory.',\n '',\n ].join('\\n');\n}\n\nexport function renderUnknownCommand(value: string): string {\n return [`Unknown doctor command: ${value}`, '', 'Run ankhorage-doctor --help', ''].join('\\n');\n}\n\nfunction renderCommandHelp(command: DoctorCommandDefinition): string {\n return [\n command.summary,\n '',\n 'Usage:',\n ` ankhorage-doctor ${command.standaloneName} [path]`,\n ` ankh ${DOCTOR_COMMAND_CATEGORY} ${command.path.join(' ')} [path]`,\n '',\n 'Path resolution:',\n ' Pass a repo/package directory or app-manifest JSON file, or omit [path] to inspect the current directory.',\n '',\n ].join('\\n');\n}\n\nfunction createDoctorCommandServices(\n overrides: Partial<DoctorCommandServices> = {},\n): DoctorCommandServices {\n return {\n analyzeTarget: overrides.analyzeTarget ?? analyzeDoctorTargetWithCliLayout,\n };\n}\n\nfunction parseCommandArguments(\n command: DoctorCommandDefinition,\n argv: readonly string[],\n): { readonly kind: 'help' } | { readonly kind: 'run'; readonly inputPath?: string } {\n const [firstArg] = argv;\n\n if (argv.length === 1 && firstArg !== undefined && isHelpToken(firstArg)) {\n return { kind: 'help' };\n }\n\n if (argv.length > 1) {\n throw new Error(`Doctor ${command.standaloneName} accepts at most one path argument.`);\n }\n\n return {\n kind: 'run',\n inputPath: firstArg,\n };\n}\n\nasync function runValidateCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'validate',\n });\n\n request.context.writeStdout(renderAnalysisReport('validate', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runFixCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'fix',\n });\n\n request.context.writeStdout(renderAnalysisReport('fix', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runRepoCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'repo',\n });\n\n request.context.writeStdout(renderAnalysisReport('repo', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runPackageCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'package',\n });\n\n request.context.writeStdout(renderAnalysisReport('package', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nfunction renderAnalysisReport(\n commandName: DoctorCommandName,\n result: DoctorAnalysisResult,\n): string {\n const lines = [\n `doctor ${commandName}`,\n `target: ${result.targetPath}`,\n `profile: ${result.profile}`,\n `checks: ${result.appliedChecks.length > 0 ? result.appliedChecks.join(', ') : 'none'}`,\n `repoMarkers: ${result.repoMarkers.length > 0 ? result.repoMarkers.join(', ') : 'none'}`,\n '',\n 'Diagnostics:',\n ];\n\n if (result.diagnostics.length === 0) {\n lines.push(' none');\n } else {\n for (const diagnostic of result.diagnostics) {\n lines.push(renderDiagnosticLine(diagnostic));\n }\n }\n\n if (commandName === 'fix') {\n lines.push('');\n lines.push('Planned changes:');\n\n if (result.plannedChanges.length === 0) {\n lines.push(' none');\n } else {\n for (const change of result.plannedChanges) {\n lines.push(renderPlannedChangeLine(change));\n }\n }\n }\n\n const errorCount = countErrorDiagnostics(result.diagnostics);\n const warningCount = countWarningDiagnostics(result.diagnostics);\n\n lines.push('');\n lines.push(`Summary: ${errorCount} error(s), ${warningCount} warning(s)`);\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction renderDiagnosticLine(diagnostic: DoctorDiagnostic): string {\n return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.ruleId} (${diagnostic.code}): ${diagnostic.message}`;\n}\n\nfunction renderPlannedChangeLine(change: DoctorPlannedChange): string {\n return ` - ${change.ruleId} [${change.kind}]: ${change.description}`;\n}\n\nfunction renderCommandFailure(commandName: DoctorCommandName, error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n return [`Failed to run doctor ${commandName}: ${message}`, ''].join('\\n');\n}\n\nfunction isHelpToken(value: string): boolean {\n return value === '--help' || value === '-h' || value === 'help';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnkhCapabilityId, AnkhCommandDescriptor } from '@ankhorage/contracts/cli';\n\nimport type { DoctorAnalysisResult, DoctorPlannedChange, DoctorTargetMode } from './analysis.js';\nimport { analyzeDoctorTargetWithCliLayout } from './cliLayoutAnalysis.js';\nimport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nimport {\n countErrorDiagnostics,\n countWarningDiagnostics,\n type DoctorDiagnostic,\n} from './diagnostics.js';\nimport { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY } from './packageMetadata.js';\nimport type { DoctorReadiness } from './readiness.js';\n\ntype DoctorCommandName = 'fix' | 'package' | 'repo' | 'validate';\n\ninterface DoctorCommandRunRequest {\n readonly context: DoctorCommandContext;\n readonly inputPath?: string;\n}\n\ntype DoctorCommandImplementation = (\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n) => Promise<DoctorCommandRunResult>;\n\nexport interface DoctorCommandDefinition {\n readonly capability: AnkhCapabilityId;\n readonly mode: DoctorTargetMode;\n readonly path: readonly [DoctorCommandName];\n readonly standaloneName: DoctorCommandName;\n readonly summary: string;\n readonly run: DoctorCommandImplementation;\n}\n\nexport interface DoctorCommandInvocation {\n readonly argv: readonly string[];\n readonly command: DoctorCommandDefinition;\n readonly context: DoctorCommandContext;\n}\n\nexport interface DoctorCommandServices {\n readonly analyzeTarget: typeof analyzeDoctorTargetWithCliLayout;\n}\n\nexport interface RunDoctorCommandOptions {\n readonly runCommandImpl?: RunDoctorCommandImpl;\n readonly services?: Partial<DoctorCommandServices>;\n}\n\nexport type RunDoctorCommandImpl = (\n request: DoctorCommandInvocation,\n options?: RunDoctorCommandOptions,\n) => Promise<DoctorCommandRunResult>;\n\nconst COMMAND_CAPABILITIES = {\n validate: DOCTOR_CAPABILITIES[0],\n fix: DOCTOR_CAPABILITIES[1],\n repo: DOCTOR_CAPABILITIES[2],\n package: DOCTOR_CAPABILITIES[3],\n} as const satisfies Record<DoctorCommandName, AnkhCapabilityId>;\n\nexport const DOCTOR_COMMANDS = [\n {\n standaloneName: 'validate',\n path: ['validate'],\n capability: COMMAND_CAPABILITIES.validate,\n mode: 'validate',\n summary:\n 'Validate a repo, package, or app-manifest JSON path with the applicable Doctor profile.',\n run: runValidateCommand,\n },\n {\n standaloneName: 'fix',\n path: ['fix'],\n capability: COMMAND_CAPABILITIES.fix,\n mode: 'fix',\n summary: 'Build a non-mutating fix plan for deterministic doctor policy violations.',\n run: runFixCommand,\n },\n {\n standaloneName: 'repo',\n path: ['repo'],\n capability: COMMAND_CAPABILITIES.repo,\n mode: 'repo',\n summary: 'Force repo-light diagnostics for a repo/workspace-root candidate path.',\n run: runRepoCommand,\n },\n {\n standaloneName: 'package',\n path: ['package'],\n capability: COMMAND_CAPABILITIES.package,\n mode: 'package',\n summary: 'Force package-light diagnostics for a directory containing package.json.',\n run: runPackageCommand,\n },\n] as const satisfies readonly DoctorCommandDefinition[];\n\nexport async function runDoctorCommand(\n request: DoctorCommandInvocation,\n options: RunDoctorCommandOptions = {},\n): Promise<DoctorCommandRunResult> {\n const services = createDoctorCommandServices(options.services);\n\n try {\n const parsedArgs = parseCommandArguments(request.command, request.argv);\n if (parsedArgs.kind === 'help') {\n request.context.writeStdout(renderCommandHelp(request.command));\n return { exitCode: 0 };\n }\n\n return await request.command.run(\n {\n context: request.context,\n inputPath: parsedArgs.inputPath,\n },\n services,\n );\n } catch (error) {\n request.context.writeStderr(renderCommandFailure(request.command.standaloneName, error));\n return { exitCode: 1 };\n }\n}\n\nexport function createProviderCommandDescriptors(): readonly AnkhCommandDescriptor[] {\n return DOCTOR_COMMANDS.map((command) => ({\n capability: command.capability,\n path: command.path,\n summary: command.summary,\n }));\n}\n\nexport function findDoctorCommandByStandaloneName(value: string): DoctorCommandDefinition | null {\n return DOCTOR_COMMANDS.find((command) => command.standaloneName === value) ?? null;\n}\n\nexport function renderRootHelp(version: string): string {\n const commandLines = DOCTOR_COMMANDS.map(\n (command) => ` ${command.standaloneName.padEnd(8, ' ')} ${command.summary}`,\n ).join('\\n');\n\n return [\n `@ankhorage/doctor v${version}`,\n '',\n 'Usage:',\n ' ankhorage-doctor <command> [path]',\n ` ankh ${DOCTOR_COMMAND_CATEGORY} <command> [path]`,\n '',\n 'Commands:',\n commandLines,\n '',\n 'Path resolution:',\n ' Pass a repo/package directory or app-manifest JSON file, or omit [path] to inspect the current directory.',\n '',\n ].join('\\n');\n}\n\nexport function renderUnknownCommand(value: string): string {\n return [`Unknown doctor command: ${value}`, '', 'Run ankhorage-doctor --help', ''].join('\\n');\n}\n\nfunction renderCommandHelp(command: DoctorCommandDefinition): string {\n return [\n command.summary,\n '',\n 'Usage:',\n ` ankhorage-doctor ${command.standaloneName} [path]`,\n ` ankh ${DOCTOR_COMMAND_CATEGORY} ${command.path.join(' ')} [path]`,\n '',\n 'Path resolution:',\n ' Pass a repo/package directory or app-manifest JSON file, or omit [path] to inspect the current directory.',\n '',\n ].join('\\n');\n}\n\nfunction createDoctorCommandServices(\n overrides: Partial<DoctorCommandServices> = {},\n): DoctorCommandServices {\n return {\n analyzeTarget: overrides.analyzeTarget ?? analyzeDoctorTargetWithCliLayout,\n };\n}\n\nfunction parseCommandArguments(\n command: DoctorCommandDefinition,\n argv: readonly string[],\n): { readonly kind: 'help' } | { readonly kind: 'run'; readonly inputPath?: string } {\n const [firstArg] = argv;\n\n if (argv.length === 1 && firstArg !== undefined && isHelpToken(firstArg)) {\n return { kind: 'help' };\n }\n\n if (argv.length > 1) {\n throw new Error(`Doctor ${command.standaloneName} accepts at most one path argument.`);\n }\n\n return {\n kind: 'run',\n inputPath: firstArg,\n };\n}\n\nasync function runValidateCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'validate',\n });\n\n request.context.writeStdout(renderAnalysisReport('validate', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runFixCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'fix',\n });\n\n request.context.writeStdout(renderAnalysisReport('fix', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runRepoCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'repo',\n });\n\n request.context.writeStdout(renderAnalysisReport('repo', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runPackageCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: 'package',\n });\n\n request.context.writeStdout(renderAnalysisReport('package', result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nfunction renderAnalysisReport(\n commandName: DoctorCommandName,\n result: DoctorAnalysisResult,\n): string {\n const lines = [\n `doctor ${commandName}`,\n `target: ${result.targetPath}`,\n `profile: ${result.profile}`,\n `checks: ${result.appliedChecks.length > 0 ? result.appliedChecks.join(', ') : 'none'}`,\n `repoMarkers: ${result.repoMarkers.length > 0 ? result.repoMarkers.join(', ') : 'none'}`,\n '',\n 'Diagnostics:',\n ];\n\n if (result.diagnostics.length === 0) {\n lines.push(' none');\n } else {\n for (const diagnostic of result.diagnostics) {\n lines.push(renderDiagnosticLine(diagnostic));\n }\n }\n\n const readiness = result.readiness ?? [];\n lines.push('');\n lines.push('Readiness:');\n if (readiness.length === 0) {\n lines.push(' none');\n } else {\n for (const item of readiness) {\n lines.push(renderReadinessLine(item));\n }\n }\n\n if (commandName === 'fix') {\n lines.push('');\n lines.push('Planned changes:');\n\n if (result.plannedChanges.length === 0) {\n lines.push(' none');\n } else {\n for (const change of result.plannedChanges) {\n lines.push(renderPlannedChangeLine(change));\n }\n }\n }\n\n const errorCount = countErrorDiagnostics(result.diagnostics);\n const warningCount = countWarningDiagnostics(result.diagnostics);\n\n lines.push('');\n lines.push(`Summary: ${errorCount} error(s), ${warningCount} warning(s)`);\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction renderDiagnosticLine(diagnostic: DoctorDiagnostic): string {\n return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.ruleId} (${diagnostic.code}): ${diagnostic.message}`;\n}\n\nfunction renderReadinessLine(item: DoctorReadiness): string {\n return ` - ${item.target} ${item.environment} ${item.provider} ${item.transport}: ${item.status} — ${item.message}`;\n}\n\nfunction renderPlannedChangeLine(change: DoctorPlannedChange): string {\n return ` - ${change.ruleId} [${change.kind}]: ${change.description}`;\n}\n\nfunction renderCommandFailure(commandName: DoctorCommandName, error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n return [`Failed to run doctor ${commandName}: ${message}`, ''].join('\\n');\n}\n\nfunction isHelpToken(value: string): boolean {\n return value === '--help' || value === '-h' || value === 'help';\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencyPolicyAnalysis.d.ts","sourceRoot":"","sources":["../src/dependencyPolicyAnalysis.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"dependencyPolicyAnalysis.d.ts","sourceRoot":"","sources":["../src/dependencyPolicyAnalysis.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,eAAe,CAAC;AASvB,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { analyzeDoctorTarget as analyzeBaseDoctorTarget, } from './analysis.js';
|
|
4
|
+
import { applyBunRuntimePolicy } from './bunPolicyAnalysis.js';
|
|
4
5
|
import { analyzeDoctorTargetWithCliLayout as analyzeBaseDoctorTargetWithCliLayout } from './cliLayoutAnalysis.js';
|
|
5
6
|
const ANKH_PACKAGE_NAME = '@ankhorage/ankh';
|
|
6
7
|
const DEVTOOLS_PACKAGE_NAME = '@ankhorage/devtools';
|
|
7
8
|
const DEVTOOLS_REQUIRED_RULE_ID = 'package.dependencies.devtools.required';
|
|
8
9
|
export async function analyzeDoctorTarget(request) {
|
|
9
|
-
return
|
|
10
|
+
return applyRepositoryPolicies(await analyzeBaseDoctorTarget(request));
|
|
10
11
|
}
|
|
11
12
|
export async function analyzeDoctorTargetWithCliLayout(request) {
|
|
12
|
-
return
|
|
13
|
+
return applyRepositoryPolicies(await analyzeBaseDoctorTargetWithCliLayout(request));
|
|
14
|
+
}
|
|
15
|
+
async function applyRepositoryPolicies(result) {
|
|
16
|
+
return applyBunRuntimePolicy(await applyDevtoolsDependencyPlacementPolicy(result));
|
|
13
17
|
}
|
|
14
18
|
async function applyDevtoolsDependencyPlacementPolicy(result) {
|
|
15
19
|
if (!result.hasPackageJson) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencyPolicyAnalysis.js","sourceRoot":"","sources":["../src/dependencyPolicyAnalysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,mBAAmB,IAAI,uBAAuB,GAG/C,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gCAAgC,IAAI,oCAAoC,EAAE,MAAM,wBAAwB,CAAC;AAGlH,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAC5C,MAAM,qBAAqB,GAAG,qBAAqB,CAAC;AACpD,MAAM,yBAAyB,GAAG,wCAAwC,CAAC;AAE3E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAA8B;IAE9B,OAAO,
|
|
1
|
+
{"version":3,"file":"dependencyPolicyAnalysis.js","sourceRoot":"","sources":["../src/dependencyPolicyAnalysis.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport {\n analyzeDoctorTarget as analyzeBaseDoctorTarget,\n type DoctorAnalysisRequest,\n type DoctorAnalysisResult,\n} from './analysis.js';\nimport { applyBunRuntimePolicy } from './bunPolicyAnalysis.js';\nimport { analyzeDoctorTargetWithCliLayout as analyzeBaseDoctorTargetWithCliLayout } from './cliLayoutAnalysis.js';\nimport type { DoctorDiagnostic } from './diagnostics.js';\n\nconst ANKH_PACKAGE_NAME = '@ankhorage/ankh';\nconst DEVTOOLS_PACKAGE_NAME = '@ankhorage/devtools';\nconst DEVTOOLS_REQUIRED_RULE_ID = 'package.dependencies.devtools.required';\n\nexport async function analyzeDoctorTarget(\n request: DoctorAnalysisRequest,\n): Promise<DoctorAnalysisResult> {\n return applyRepositoryPolicies(await analyzeBaseDoctorTarget(request));\n}\n\nexport async function analyzeDoctorTargetWithCliLayout(\n request: DoctorAnalysisRequest,\n): Promise<DoctorAnalysisResult> {\n return applyRepositoryPolicies(await analyzeBaseDoctorTargetWithCliLayout(request));\n}\n\nasync function applyRepositoryPolicies(\n result: DoctorAnalysisResult,\n): Promise<DoctorAnalysisResult> {\n return applyBunRuntimePolicy(await applyDevtoolsDependencyPlacementPolicy(result));\n}\n\nasync function applyDevtoolsDependencyPlacementPolicy(\n result: DoctorAnalysisResult,\n): Promise<DoctorAnalysisResult> {\n if (!result.hasPackageJson) {\n return result;\n }\n\n const packageJsonPath = path.join(result.targetPath, 'package.json');\n const packageJson = await readPackageJson(packageJsonPath);\n if (packageJson?.name !== ANKH_PACKAGE_NAME || !expectsDevtools(packageJson)) {\n return result;\n }\n\n const dependencies = isRecord(packageJson.dependencies) ? packageJson.dependencies : null;\n const hasRuntimeDevtools = hasDependency(dependencies, DEVTOOLS_PACKAGE_NAME);\n const diagnosticsWithoutPlacementRule = result.diagnostics.filter(\n (diagnostic) => diagnostic.ruleId !== DEVTOOLS_REQUIRED_RULE_ID,\n );\n const diagnostics = hasRuntimeDevtools\n ? diagnosticsWithoutPlacementRule\n : [\n ...diagnosticsWithoutPlacementRule,\n createMissingRuntimeDevtoolsDiagnostic(packageJsonPath, result),\n ];\n\n return {\n ...result,\n diagnostics,\n fixPlan: result.fixPlan === null ? null : { ...result.fixPlan, diagnostics },\n };\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<Record<string, unknown> | null> {\n try {\n const parsed = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')) as unknown;\n return isRecord(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n\nfunction createMissingRuntimeDevtoolsDiagnostic(\n packageJsonPath: string,\n result: DoctorAnalysisResult,\n): DoctorDiagnostic {\n return {\n code: 'missing-dependency',\n message:\n '@ankhorage/ankh bundles @ankhorage/devtools as a runtime core provider and must declare it in dependencies.',\n path: packageJsonPath,\n profile: result.profile,\n ruleId: DEVTOOLS_REQUIRED_RULE_ID,\n severity: 'error',\n };\n}\n\nfunction expectsDevtools(packageJson: Record<string, unknown>): boolean {\n const scripts = isRecord(packageJson.scripts) ? packageJson.scripts : null;\n if (scripts === null) {\n return false;\n }\n\n return Object.values(scripts).some(\n (scriptValue) =>\n isNonEmptyString(scriptValue) &&\n (scriptValue.includes('ankhorage-eslint') ||\n scriptValue.includes('ankhorage-prettier') ||\n scriptValue.includes('ankhorage-knip')),\n );\n}\n\nfunction hasDependency(\n dependencyMap: Record<string, unknown> | null,\n dependencyName: string,\n): boolean {\n return dependencyMap !== null && isNonEmptyString(dependencyMap[dependencyName]);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type DoctorDiagnosticCode = 'field-invalid' | 'field-missing' | 'invalid-ankh-metadata' | 'invalid-app-manifest-json' | 'invalid-package-json' | 'missing-dependency' | 'missing-path' | 'missing-script' | 'provider-source-import-failed' | 'provider-source-missing' | 'target-not-directory' | 'target-not-found' | 'unsupported-target';
|
|
2
2
|
export type DoctorDiagnosticSeverity = 'error' | 'warning';
|
|
3
3
|
export type DoctorPolicyProfile = 'app-manifest' | 'integration-monorepo' | 'public-package' | 'unknown';
|
|
4
|
-
export type DoctorRuleId = 'integration.package.ankh.disallowed' | 'integration.package.private.required' | 'integration.package.workspaces.required' | 'manifest.auth.authorization.engine.valid' | 'manifest.auth.authorization.kind.valid' | 'manifest.auth.authorization.valid-shape' | 'manifest.auth.flow.post-sign-in.distinct' | 'manifest.auth.flow.route.required' | 'manifest.auth.flow.route.unique' | 'manifest.auth.flow.route.valid' | 'manifest.auth.flow.unauthorized-route.valid' | 'manifest.auth.flow.valid-shape' | 'manifest.auth.oauth.callback-route.valid' | 'manifest.auth.oauth.provider.credentials-ref.required' | 'manifest.auth.oauth.provider.credentials-ref.valid' | 'manifest.auth.oauth.provider.duplicate' | 'manifest.auth.oauth.provider.inline-secret.disallowed' | 'manifest.auth.oauth.providers.valid' | 'manifest.auth.oauth.valid-shape' | 'manifest.auth.valid-shape' | 'manifest.infra.valid-shape' | 'manifest.json.readable' | 'manifest.json.valid' | 'manifest.root.valid-shape' | 'manifest.secret-store.provider.required' | 'manifest.secret-store.provider.valid' | 'manifest.secret-store.valid-shape' | 'manifest.settings.auth-flow.removed' | 'package.ankh.capabilities.match-provider' | 'package.ankh.present.valid-shape' | 'package.ankh.provider-path.required' | 'package.ankh.required-for-provider' | 'package.cli.export.required' | 'package.cli.index.required' | 'package.cli.root-file.disallowed' | 'package.dependencies.ankh-workspace-alias.disallowed' | 'package.dependencies.ankhorage4-source.disallowed' | 'package.dependencies.changesets.required' | 'package.dependencies.devtools.required' | 'package.dependencies.paradox.required' | 'package.dependencies.types-bun.required' | 'package.dependencies.types-node.required' | 'package.dependencies.typescript.required' | 'package.imports.ankh-workspace-alias.disallowed' | 'package.imports.ankhorage4-source.disallowed' | 'package.json.bugs.required' | 'package.json.description.required' | 'package.json.exports.required' | 'package.json.files.required' | 'package.json.homepage.required' | 'package.json.keywords.required' | 'package.json.license.required' | 'package.json.name.required' | 'package.json.package-manager.bun' | 'package.json.package-manager.required' | 'package.json.private.public-package-disallowed' | 'package.json.publish-config.public' | 'package.json.publish-config.required' | 'package.json.repository.required' | 'package.json.type.module' | 'package.json.type.required' | 'package.json.version.required' | 'package.scripts.build.required' | 'package.scripts.changeset-status.required' | 'package.scripts.changeset.required' | 'package.scripts.docs.required' | 'package.scripts.format-check.required' | 'package.scripts.format.required' | 'package.scripts.knip.required' | 'package.scripts.lint-fix.required' | 'package.scripts.lint.required' | 'package.scripts.test.required' | 'package.scripts.typecheck.required' | 'package.scripts.version-packages.required' | 'provider.commands.match-capabilities' | 'provider.commands.match-handlers' | 'provider.source.importable' | 'provider.source.required' | 'repo.changelog.required' | 'repo.changeset.required' | 'repo.license.required' | 'repo.readme.required' | 'repo.workflows.required' | 'studio.dependencies.dnd.required' | 'studio.dependencies.runtime.required' | 'studio.imports.dnd.required' | 'studio.imports.runtime.required' | 'target.package-json.required' | 'target.path.directory' | 'target.path.exists' | 'target.profile.supported' | 'target.repo-markers.required';
|
|
4
|
+
export type DoctorRuleId = 'integration.package.ankh.disallowed' | 'integration.package.private.required' | 'integration.package.workspaces.required' | 'manifest.auth.authorization.engine.valid' | 'manifest.auth.authorization.kind.valid' | 'manifest.auth.authorization.valid-shape' | 'manifest.auth.flow.post-sign-in.distinct' | 'manifest.auth.flow.route.required' | 'manifest.auth.flow.route.unique' | 'manifest.auth.flow.route.valid' | 'manifest.auth.flow.unauthorized-route.valid' | 'manifest.auth.flow.valid-shape' | 'manifest.auth.oauth.callback-route.valid' | 'manifest.auth.oauth.callback-target.configured' | 'manifest.auth.oauth.provider.credentials-ref.required' | 'manifest.auth.oauth.provider.credentials-ref.valid' | 'manifest.auth.oauth.provider.duplicate' | 'manifest.auth.oauth.provider.inline-secret.disallowed' | 'manifest.auth.oauth.providers.valid' | 'manifest.auth.oauth.setup.supported' | 'manifest.auth.oauth.valid-shape' | 'manifest.auth.valid-shape' | 'manifest.deploy.targets.enabled' | 'manifest.deploy.targets.legacy-web' | 'manifest.deploy.valid-shape' | 'manifest.infra.valid-shape' | 'manifest.json.readable' | 'manifest.json.valid' | 'manifest.root.valid-shape' | 'manifest.secret-store.provider.required' | 'manifest.secret-store.provider.valid' | 'manifest.secret-store.valid-shape' | 'manifest.settings.auth-flow.removed' | 'package.ankh.capabilities.match-provider' | 'package.ankh.present.valid-shape' | 'package.ankh.provider-path.required' | 'package.ankh.required-for-provider' | 'package.cli.export.required' | 'package.cli.index.required' | 'package.cli.root-file.disallowed' | 'package.dependencies.ankh-workspace-alias.disallowed' | 'package.dependencies.ankhorage4-source.disallowed' | 'package.dependencies.changesets.required' | 'package.dependencies.devtools.required' | 'package.dependencies.paradox.required' | 'package.dependencies.types-bun.policy' | 'package.dependencies.types-bun.required' | 'package.dependencies.types-node.required' | 'package.dependencies.typescript.required' | 'package.imports.ankh-workspace-alias.disallowed' | 'package.imports.ankhorage4-source.disallowed' | 'package.json.bugs.required' | 'package.json.description.required' | 'package.json.exports.required' | 'package.json.files.required' | 'package.json.homepage.required' | 'package.json.keywords.required' | 'package.json.license.required' | 'package.json.name.required' | 'package.json.package-manager.bun' | 'package.json.package-manager.policy' | 'package.json.package-manager.required' | 'package.json.private.public-package-disallowed' | 'package.json.publish-config.public' | 'package.json.publish-config.required' | 'package.json.repository.required' | 'package.json.type.module' | 'package.json.type.required' | 'package.json.version.required' | 'package.scripts.build.required' | 'package.scripts.changeset-status.required' | 'package.scripts.changeset.required' | 'package.scripts.docs.required' | 'package.scripts.format-check.required' | 'package.scripts.format.required' | 'package.scripts.knip.required' | 'package.scripts.lint-fix.required' | 'package.scripts.lint.required' | 'package.scripts.test.required' | 'package.scripts.typecheck.required' | 'package.scripts.version-packages.required' | 'provider.commands.match-capabilities' | 'provider.commands.match-handlers' | 'provider.source.importable' | 'provider.source.required' | 'repo.changelog.required' | 'repo.changeset.required' | 'repo.license.required' | 'repo.readme.required' | 'repo.workflows.ci.bun-policy' | 'repo.workflows.release.bun-policy' | 'repo.workflows.required' | 'studio.dependencies.dnd.required' | 'studio.dependencies.runtime.required' | 'studio.imports.dnd.required' | 'studio.imports.runtime.required' | 'target.package-json.required' | 'target.path.directory' | 'target.path.exists' | 'target.profile.supported' | 'target.repo-markers.required';
|
|
5
5
|
export interface DoctorDiagnostic {
|
|
6
6
|
readonly code: DoctorDiagnosticCode;
|
|
7
7
|
readonly message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,eAAe,GACf,eAAe,GACf,uBAAuB,GACvB,2BAA2B,GAC3B,sBAAsB,GACtB,oBAAoB,GACpB,cAAc,GACd,gBAAgB,GAChB,+BAA+B,GAC/B,yBAAyB,GACzB,sBAAsB,GACtB,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,SAAS,CAAC;AAC3D,MAAM,MAAM,mBAAmB,GAC7B,cAAc,GAAG,sBAAsB,GAAG,gBAAgB,GAAG,SAAS,CAAC;AACzE,MAAM,MAAM,YAAY,GACpB,qCAAqC,GACrC,sCAAsC,GACtC,yCAAyC,GACzC,0CAA0C,GAC1C,wCAAwC,GACxC,yCAAyC,GACzC,0CAA0C,GAC1C,mCAAmC,GACnC,iCAAiC,GACjC,gCAAgC,GAChC,6CAA6C,GAC7C,gCAAgC,GAChC,0CAA0C,GAC1C,uDAAuD,GACvD,oDAAoD,GACpD,wCAAwC,GACxC,uDAAuD,GACvD,qCAAqC,GACrC,iCAAiC,GACjC,2BAA2B,GAC3B,4BAA4B,GAC5B,wBAAwB,GACxB,qBAAqB,GACrB,2BAA2B,GAC3B,yCAAyC,GACzC,sCAAsC,GACtC,mCAAmC,GACnC,qCAAqC,GACrC,0CAA0C,GAC1C,kCAAkC,GAClC,qCAAqC,GACrC,oCAAoC,GACpC,6BAA6B,GAC7B,4BAA4B,GAC5B,kCAAkC,GAClC,sDAAsD,GACtD,mDAAmD,GACnD,0CAA0C,GAC1C,wCAAwC,GACxC,uCAAuC,GACvC,yCAAyC,GACzC,0CAA0C,GAC1C,0CAA0C,GAC1C,iDAAiD,GACjD,8CAA8C,GAC9C,4BAA4B,GAC5B,mCAAmC,GACnC,+BAA+B,GAC/B,6BAA6B,GAC7B,gCAAgC,GAChC,gCAAgC,GAChC,+BAA+B,GAC/B,4BAA4B,GAC5B,kCAAkC,GAClC,uCAAuC,GACvC,gDAAgD,GAChD,oCAAoC,GACpC,sCAAsC,GACtC,kCAAkC,GAClC,0BAA0B,GAC1B,4BAA4B,GAC5B,+BAA+B,GAC/B,gCAAgC,GAChC,2CAA2C,GAC3C,oCAAoC,GACpC,+BAA+B,GAC/B,uCAAuC,GACvC,iCAAiC,GACjC,+BAA+B,GAC/B,mCAAmC,GACnC,+BAA+B,GAC/B,+BAA+B,GAC/B,oCAAoC,GACpC,2CAA2C,GAC3C,sCAAsC,GACtC,kCAAkC,GAClC,4BAA4B,GAC5B,0BAA0B,GAC1B,yBAAyB,GACzB,yBAAyB,GACzB,uBAAuB,GACvB,sBAAsB,GACtB,yBAAyB,GACzB,kCAAkC,GAClC,sCAAsC,GACtC,6BAA6B,GAC7B,iCAAiC,GACjC,8BAA8B,GAC9B,uBAAuB,GACvB,oBAAoB,GACpB,0BAA0B,GAC1B,8BAA8B,CAAC;AAEnC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,CAEtF;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,CAExF"}
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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"}
|
package/dist/diagnostics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAkIA,MAAM,UAAU,qBAAqB,CAAC,WAAwC;IAC5E,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAwC;IAC9E,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;AACtF,CAAC","sourcesContent":["export type DoctorDiagnosticCode =\n | 'field-invalid'\n | 'field-missing'\n | 'invalid-ankh-metadata'\n | 'invalid-app-manifest-json'\n | 'invalid-package-json'\n | 'missing-dependency'\n | 'missing-path'\n | 'missing-script'\n | 'provider-source-import-failed'\n | 'provider-source-missing'\n | 'target-not-directory'\n | 'target-not-found'\n | 'unsupported-target';\n\nexport type DoctorDiagnosticSeverity = 'error' | 'warning';\nexport type DoctorPolicyProfile =\n 'app-manifest' | 'integration-monorepo' | 'public-package' | 'unknown';\nexport type DoctorRuleId =\n | 'integration.package.ankh.disallowed'\n | 'integration.package.private.required'\n | 'integration.package.workspaces.required'\n | 'manifest.auth.authorization.engine.valid'\n | 'manifest.auth.authorization.kind.valid'\n | 'manifest.auth.authorization.valid-shape'\n | 'manifest.auth.flow.post-sign-in.distinct'\n | 'manifest.auth.flow.route.required'\n | 'manifest.auth.flow.route.unique'\n | 'manifest.auth.flow.route.valid'\n | 'manifest.auth.flow.unauthorized-route.valid'\n | 'manifest.auth.flow.valid-shape'\n | 'manifest.auth.oauth.callback-route.valid'\n | 'manifest.auth.oauth.callback-target.configured'\n | 'manifest.auth.oauth.provider.credentials-ref.required'\n | 'manifest.auth.oauth.provider.credentials-ref.valid'\n | 'manifest.auth.oauth.provider.duplicate'\n | 'manifest.auth.oauth.provider.inline-secret.disallowed'\n | 'manifest.auth.oauth.providers.valid'\n | 'manifest.auth.oauth.setup.supported'\n | 'manifest.auth.oauth.valid-shape'\n | 'manifest.auth.valid-shape'\n | 'manifest.deploy.targets.enabled'\n | 'manifest.deploy.targets.legacy-web'\n | 'manifest.deploy.valid-shape'\n | 'manifest.infra.valid-shape'\n | 'manifest.json.readable'\n | 'manifest.json.valid'\n | 'manifest.root.valid-shape'\n | 'manifest.secret-store.provider.required'\n | 'manifest.secret-store.provider.valid'\n | 'manifest.secret-store.valid-shape'\n | 'manifest.settings.auth-flow.removed'\n | 'package.ankh.capabilities.match-provider'\n | 'package.ankh.present.valid-shape'\n | 'package.ankh.provider-path.required'\n | 'package.ankh.required-for-provider'\n | 'package.cli.export.required'\n | 'package.cli.index.required'\n | 'package.cli.root-file.disallowed'\n | 'package.dependencies.ankh-workspace-alias.disallowed'\n | 'package.dependencies.ankhorage4-source.disallowed'\n | 'package.dependencies.changesets.required'\n | 'package.dependencies.devtools.required'\n | 'package.dependencies.paradox.required'\n | 'package.dependencies.types-bun.policy'\n | 'package.dependencies.types-bun.required'\n | 'package.dependencies.types-node.required'\n | 'package.dependencies.typescript.required'\n | 'package.imports.ankh-workspace-alias.disallowed'\n | 'package.imports.ankhorage4-source.disallowed'\n | 'package.json.bugs.required'\n | 'package.json.description.required'\n | 'package.json.exports.required'\n | 'package.json.files.required'\n | 'package.json.homepage.required'\n | 'package.json.keywords.required'\n | 'package.json.license.required'\n | 'package.json.name.required'\n | 'package.json.package-manager.bun'\n | 'package.json.package-manager.policy'\n | 'package.json.package-manager.required'\n | 'package.json.private.public-package-disallowed'\n | 'package.json.publish-config.public'\n | 'package.json.publish-config.required'\n | 'package.json.repository.required'\n | 'package.json.type.module'\n | 'package.json.type.required'\n | 'package.json.version.required'\n | 'package.scripts.build.required'\n | 'package.scripts.changeset-status.required'\n | 'package.scripts.changeset.required'\n | 'package.scripts.docs.required'\n | 'package.scripts.format-check.required'\n | 'package.scripts.format.required'\n | 'package.scripts.knip.required'\n | 'package.scripts.lint-fix.required'\n | 'package.scripts.lint.required'\n | 'package.scripts.test.required'\n | 'package.scripts.typecheck.required'\n | 'package.scripts.version-packages.required'\n | 'provider.commands.match-capabilities'\n | 'provider.commands.match-handlers'\n | 'provider.source.importable'\n | 'provider.source.required'\n | 'repo.changelog.required'\n | 'repo.changeset.required'\n | 'repo.license.required'\n | 'repo.readme.required'\n | 'repo.workflows.ci.bun-policy'\n | 'repo.workflows.release.bun-policy'\n | 'repo.workflows.required'\n | 'studio.dependencies.dnd.required'\n | 'studio.dependencies.runtime.required'\n | 'studio.imports.dnd.required'\n | 'studio.imports.runtime.required'\n | 'target.package-json.required'\n | 'target.path.directory'\n | 'target.path.exists'\n | 'target.profile.supported'\n | 'target.repo-markers.required';\n\nexport interface DoctorDiagnostic {\n readonly code: DoctorDiagnosticCode;\n readonly message: string;\n readonly path: string;\n readonly profile: DoctorPolicyProfile;\n readonly ruleId: DoctorRuleId;\n readonly severity: DoctorDiagnosticSeverity;\n}\n\nexport function countErrorDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number {\n return diagnostics.filter((diagnostic) => diagnostic.severity === 'error').length;\n}\n\nexport function countWarningDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number {\n return diagnostics.filter((diagnostic) => diagnostic.severity === 'warning').length;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type { DoctorAnalysisRequest, DoctorAnalysisResult, DoctorFixPlan, DoctorPlannedChange, DoctorPlannedChangeKind, DoctorTargetCheck, DoctorTargetMode, } from './analysis.js';
|
|
2
|
+
export { analyzeAuthReadiness, type DoctorAuthReadinessAnalysis } from './authReadinessAnalysis.js';
|
|
3
|
+
export { analyzeAuthReadinessFile } from './authReadinessFileAnalysis.js';
|
|
2
4
|
export { createDoctorRuntimeProvider, type CreateDoctorRuntimeProviderOptions, } from './cli/index.js';
|
|
3
5
|
export { runCli } from './cli/standalone.js';
|
|
4
6
|
export type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';
|
|
@@ -7,4 +9,5 @@ export { analyzeDoctorTarget, analyzeDoctorTargetWithCliLayout, } from './depend
|
|
|
7
9
|
export type { DoctorDiagnostic, DoctorDiagnosticCode, DoctorDiagnosticSeverity, DoctorPolicyProfile, DoctorRuleId, } from './diagnostics.js';
|
|
8
10
|
export { analyzeAppManifest, analyzeAppManifestFile, analyzeAppManifestTarget, } from './manifestAnalysis.js';
|
|
9
11
|
export { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY, DOCTOR_PACKAGE_METADATA, DOCTOR_PACKAGE_NAME, DOCTOR_PACKAGE_VERSION, } from './packageMetadata.js';
|
|
12
|
+
export type { DoctorReadiness, DoctorReadinessStatus } from './readiness.js';
|
|
10
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,2BAA2B,EAC3B,KAAK,kCAAkC,GACxC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,mBAAmB,EACnB,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EACL,2BAA2B,EAC3B,KAAK,kCAAkC,GACxC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,mBAAmB,EACnB,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { analyzeAuthReadiness } from './authReadinessAnalysis.js';
|
|
2
|
+
export { analyzeAuthReadinessFile } from './authReadinessFileAnalysis.js';
|
|
1
3
|
export { createDoctorRuntimeProvider, } from './cli/index.js';
|
|
2
4
|
export { runCli } from './cli/standalone.js';
|
|
3
5
|
export { createDefaultCommandContext } from './commandContext.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,mBAAmB,EACnB,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AAQvC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC","sourcesContent":["export type {\n DoctorAnalysisRequest,\n DoctorAnalysisResult,\n DoctorFixPlan,\n DoctorPlannedChange,\n DoctorPlannedChangeKind,\n DoctorTargetCheck,\n DoctorTargetMode,\n} from './analysis.js';\nexport {\n createDoctorRuntimeProvider,\n type CreateDoctorRuntimeProviderOptions,\n} from './cli/index.js';\nexport { runCli } from './cli/standalone.js';\nexport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nexport { createDefaultCommandContext } from './commandContext.js';\nexport {\n analyzeDoctorTarget,\n analyzeDoctorTargetWithCliLayout,\n} from './dependencyPolicyAnalysis.js';\nexport type {\n DoctorDiagnostic,\n DoctorDiagnosticCode,\n DoctorDiagnosticSeverity,\n DoctorPolicyProfile,\n DoctorRuleId,\n} from './diagnostics.js';\nexport {\n analyzeAppManifest,\n analyzeAppManifestFile,\n analyzeAppManifestTarget,\n} from './manifestAnalysis.js';\nexport {\n DOCTOR_CAPABILITIES,\n DOCTOR_COMMAND_CATEGORY,\n DOCTOR_PACKAGE_METADATA,\n DOCTOR_PACKAGE_NAME,\n DOCTOR_PACKAGE_VERSION,\n} from './packageMetadata.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,oBAAoB,EAAoC,MAAM,4BAA4B,CAAC;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EACL,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EACL,mBAAmB,EACnB,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AAQvC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC","sourcesContent":["export type {\n DoctorAnalysisRequest,\n DoctorAnalysisResult,\n DoctorFixPlan,\n DoctorPlannedChange,\n DoctorPlannedChangeKind,\n DoctorTargetCheck,\n DoctorTargetMode,\n} from './analysis.js';\nexport { analyzeAuthReadiness, type DoctorAuthReadinessAnalysis } from './authReadinessAnalysis.js';\nexport { analyzeAuthReadinessFile } from './authReadinessFileAnalysis.js';\nexport {\n createDoctorRuntimeProvider,\n type CreateDoctorRuntimeProviderOptions,\n} from './cli/index.js';\nexport { runCli } from './cli/standalone.js';\nexport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nexport { createDefaultCommandContext } from './commandContext.js';\nexport {\n analyzeDoctorTarget,\n analyzeDoctorTargetWithCliLayout,\n} from './dependencyPolicyAnalysis.js';\nexport type {\n DoctorDiagnostic,\n DoctorDiagnosticCode,\n DoctorDiagnosticSeverity,\n DoctorPolicyProfile,\n DoctorRuleId,\n} from './diagnostics.js';\nexport {\n analyzeAppManifest,\n analyzeAppManifestFile,\n analyzeAppManifestTarget,\n} from './manifestAnalysis.js';\nexport {\n DOCTOR_CAPABILITIES,\n DOCTOR_COMMAND_CATEGORY,\n DOCTOR_PACKAGE_METADATA,\n DOCTOR_PACKAGE_NAME,\n DOCTOR_PACKAGE_VERSION,\n} from './packageMetadata.js';\nexport type { DoctorReadiness, DoctorReadinessStatus } from './readiness.js';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestAnalysis.d.ts","sourceRoot":"","sources":["../src/manifestAnalysis.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"manifestAnalysis.d.ts","sourceRoot":"","sources":["../src/manifestAnalysis.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAGrB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;AAsB1B,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAqCtC;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgC1F;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EACjB,YAAY,SAAkB,GAC7B,gBAAgB,EAAE,CAuEpB"}
|
package/dist/manifestAnalysis.js
CHANGED
|
@@ -2,6 +2,7 @@ import { promises as fs } from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { AUTHZ_ENGINES, AUTHZ_KINDS } from '@ankhorage/contracts';
|
|
4
4
|
import { resolveAuthFlow } from '@ankhorage/contracts/auth';
|
|
5
|
+
import { analyzeAuthReadinessFile } from './authReadinessFileAnalysis.js';
|
|
5
6
|
import { analyzeSecretStoreManifest } from './secretManifestAnalysis.js';
|
|
6
7
|
const MANIFEST_PROFILE = 'app-manifest';
|
|
7
8
|
const AUTH_ACTION_ROUTE_KEYS = [
|
|
@@ -27,7 +28,8 @@ export async function analyzeAppManifestTarget(request) {
|
|
|
27
28
|
(request.mode !== 'validate' && request.mode !== 'fix')) {
|
|
28
29
|
return null;
|
|
29
30
|
}
|
|
30
|
-
const
|
|
31
|
+
const authReadiness = await analyzeAuthReadinessFile(targetPath);
|
|
32
|
+
const diagnostics = [...(await analyzeAppManifestFile(targetPath)), ...authReadiness.diagnostics];
|
|
31
33
|
const plannedChanges = [];
|
|
32
34
|
const fixPlan = request.mode === 'fix'
|
|
33
35
|
? {
|
|
@@ -44,6 +46,7 @@ export async function analyzeAppManifestTarget(request) {
|
|
|
44
46
|
hasPackageJson: false,
|
|
45
47
|
plannedChanges,
|
|
46
48
|
profile: MANIFEST_PROFILE,
|
|
49
|
+
readiness: authReadiness.readiness,
|
|
47
50
|
repoMarkers: [],
|
|
48
51
|
targetPath,
|
|
49
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestAnalysis.js","sourceRoot":"","sources":["../src/manifestAnalysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAuB,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAcjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEzE,MAAM,gBAAgB,GAAG,cAA4C,CAAC;AACtE,MAAM,sBAAsB,GAAG;IAC7B,aAAa;IACb,aAAa;IACb,cAAc;IACd,qBAAqB;IACrB,UAAU;CAC0C,CAAC;AACvD,MAAM,mBAAmB,GAAG;IAC1B,aAAa;IACb,cAAc;IACd,qBAAqB;IACrB,UAAU;IACV,mBAAmB;CACiC,CAAC;AAKvD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAA8B;IAE9B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAE3C,IACE,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,MAAM,EAAE;QACf,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO;QAClD,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC,EACvD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,cAAc,GAA0B,EAAE,CAAC;IACjD,MAAM,OAAO,GACX,OAAO,CAAC,IAAI,KAAK,KAAK;QACpB,CAAC,CAAC;YACE,OAAO,EAAE,cAAc;YACvB,WAAW;YACX,OAAO,EAAE,gBAAgB;YACzB,UAAU;SACX;QACH,CAAC,CAAC,IAAI,CAAC;IAEX,OAAO;QACL,aAAa,EAAE,CAAC,UAAU,CAAC;QAC3B,WAAW;QACX,OAAO;QACP,cAAc,EAAE,KAAK;QACrB,cAAc;QACd,OAAO,EAAE,gBAAgB;QACzB,WAAW,EAAE,EAAE;QACf,UAAU;KACX,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,QAAgB;IAC3D,IAAI,MAAc,CAAC;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,wBAAwB,CAAC;gBACvB,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,qCAAqC,cAAc,CAAC,KAAK,CAAC,EAAE;gBACrE,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,wBAAwB;aACjC,CAAC;SACH,CAAC;IACJ,CAAC;IAED,IAAI,QAAiB,CAAC;IAEtB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,wBAAwB,CAAC;gBACvB,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,yCAAyC,cAAc,CAAC,KAAK,CAAC,EAAE;gBACzE,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,qBAAqB;aAC9B,CAAC;SACH,CAAC;IACJ,CAAC;IAED,OAAO,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,QAAiB,EACjB,YAAY,GAAG,eAAe;IAE9B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,wBAAwB,CAAC;gBACvB,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,0CAA0C;gBACnD,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,2BAA2B;aACpC,CAAC;SACH,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAE9B,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;QACvD,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EACL,+HAA+H;YACjI,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,qCAAqC;SAC9C,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAC3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,oDAAoD;YAC7D,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,4BAA4B;SACrC,CAAC,CACH,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,GAAG,0BAA0B,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;IAErE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,yDAAyD;YAClE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,2BAA2B;SACpC,CAAC,CACH,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACjE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,6BAA6B,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAED,qBAAqB,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAErE,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,aAAa,CACpB,KAAc,EACd,YAAoB,EACpB,WAA+B;IAE/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,8DAA8D;YACvE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,gCAAgC;SACzC,CAAC,CACH,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACvF,MAAM,eAAe,GAAG,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC/F,MAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAE5E,IAAI,WAAW,KAAK,IAAI,IAAI,eAAe,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,eAAe,CAAC;QACrB,WAAW;QACX,eAAe;QACf,GAAG,cAAc;KAClB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CACxB,IAA6B,EAC7B,GAAsC,EACtC,YAAoB,EACpB,WAA+B;IAE/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IAExB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe;YAC7D,OAAO,EAAE,4BAA4B,GAAG,8BAA8B;YACtE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,mCAAmC;SAC5C,CAAC,CACH,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CACzB,IAA6B,EAC7B,YAAoB,EACpB,WAA+B;IAE/B,MAAM,MAAM,GAAoD,EAAE,CAAC;IACnE,IAAI,KAAK,GAAG,IAAI,CAAC;IAEjB,KAAK,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrD,KAAK,GAAG,KAAK,CAAC;YACd,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;gBACvB,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,4BAA4B,GAAG,2CAA2C;gBACnF,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,gCAAgC;aACzC,CAAC,CACH,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED,SAAS,6BAA6B,CACpC,IAAoB,EACpB,YAAoB,EACpB,WAA+B;IAE/B,MAAM,YAAY,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,CAAC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAAgC,CAAC;IAE7D,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,YAAY,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,SAAS;QACX,CAAC;QAED,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,sCAAsC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,KAAK,IAAI;YAC3F,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,iCAAiC;SAC1C,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAAG,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7D,MAAM,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC;IACtF,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,iFAAiF,eAAe,CAAC,GAAG,GAAG;YAChH,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,0CAA0C;SACnD,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO;IACT,CAAC;IAED,MAAM,iBAAiB,GAAG,cAAc,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAErD,IAAI,iBAAiB,KAAK,eAAe,EAAE,CAAC;QAC1C,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,wDAAwD;YACjE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,6CAA6C;SACtD,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,iBAAiB,KAAK,WAAW,EAAE,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,oBAAoB,GAAG,YAAY,CAAC,IAAI,CAC5C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,aAAa,IAAI,KAAK,CAAC,KAAK,KAAK,iBAAiB,CAC5E,CAAC;IACF,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACvC,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,yEAAyE,oBAAoB,CAAC,GAAG,GAAG;YAC7G,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,6CAA6C;SACtD,CAAC,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc,EACd,YAAoB,EACpB,WAA+B;IAE/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,WAAW,CAAC,IAAI,CACd,wBAAwB,CAAC;YACvB,IAAI,EAAE,eAAe;YACrB,OAAO,EACL,qFAAqF;YACvF,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,yCAAyC;SAClD,CAAC,CACH,CAAC;QACF,OAAO;IACT,CAAC;IAED,0BAA0B,CAAC;QACzB,OAAO,EAAE,WAAW;QACpB,WAAW;QACX,SAAS,EAAE,MAAM;QACjB,YAAY;QACZ,KAAK,EAAE,KAAK,CAAC,IAAI;QACjB,MAAM,EAAE,wCAAwC;KACjD,CAAC,CAAC;IACH,0BAA0B,CAAC;QACzB,OAAO,EAAE,aAAa;QACtB,WAAW;QACX,SAAS,EAAE,QAAQ;QACnB,YAAY;QACZ,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,MAAM,EAAE,0CAA0C;KACnD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,0BAA0B,CAAC,OAOnC;IACC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,WAAW,CAAC,IAAI,CACtB,wBAAwB,CAAC;QACvB,IAAI,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe;QACrE,OAAO,EAAE,0BAA0B,OAAO,CAAC,SAAS,oBAAoB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACrG,IAAI,EAAE,OAAO,CAAC,YAAY;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,OAKjC;IACC,OAAO;QACL,GAAG,OAAO;QACV,OAAO,EAAE,gBAAgB;QACzB,QAAQ,EAAE,OAAO;KAClB,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxE,OAAO,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;AAClD,CAAC;AAED,SAAS,MAAM,CAAC,MAA+B,EAAE,GAAW;IAC1D,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport { AUTHZ_ENGINES, AUTHZ_KINDS } from '@ankhorage/contracts';\nimport { type AuthFlowConfig, resolveAuthFlow } from '@ankhorage/contracts/auth';\n\nimport type {\n DoctorAnalysisRequest,\n DoctorAnalysisResult,\n DoctorFixPlan,\n DoctorPlannedChange,\n} from './analysis.js';\nimport type {\n DoctorDiagnostic,\n DoctorDiagnosticCode,\n DoctorPolicyProfile,\n DoctorRuleId,\n} from './diagnostics.js';\nimport { analyzeSecretStoreManifest } from './secretManifestAnalysis.js';\n\nconst MANIFEST_PROFILE = 'app-manifest' satisfies DoctorPolicyProfile;\nconst AUTH_ACTION_ROUTE_KEYS = [\n 'signInRoute',\n 'signUpRoute',\n 'signOutRoute',\n 'forgotPasswordRoute',\n 'otpRoute',\n] as const satisfies readonly (keyof AuthFlowConfig)[];\nconst OPTIONAL_ROUTE_KEYS = [\n 'signUpRoute',\n 'signOutRoute',\n 'forgotPasswordRoute',\n 'otpRoute',\n 'unauthorizedRoute',\n] as const satisfies readonly (keyof AuthFlowConfig)[];\n\ntype AuthActionRouteKey = (typeof AUTH_ACTION_ROUTE_KEYS)[number];\ntype OptionalRouteKey = (typeof OPTIONAL_ROUTE_KEYS)[number];\n\nexport async function analyzeAppManifestTarget(\n request: DoctorAnalysisRequest,\n): Promise<DoctorAnalysisResult | null> {\n const targetPath = path.resolve(request.cwd, request.inputPath ?? '.');\n const stats = await statOrNull(targetPath);\n\n if (\n stats === null ||\n !stats.isFile() ||\n path.extname(targetPath).toLowerCase() !== '.json' ||\n (request.mode !== 'validate' && request.mode !== 'fix')\n ) {\n return null;\n }\n\n const diagnostics = await analyzeAppManifestFile(targetPath);\n const plannedChanges: DoctorPlannedChange[] = [];\n const fixPlan: DoctorFixPlan | null =\n request.mode === 'fix'\n ? {\n changes: plannedChanges,\n diagnostics,\n profile: MANIFEST_PROFILE,\n targetPath,\n }\n : null;\n\n return {\n appliedChecks: ['manifest'],\n diagnostics,\n fixPlan,\n hasPackageJson: false,\n plannedChanges,\n profile: MANIFEST_PROFILE,\n repoMarkers: [],\n targetPath,\n };\n}\n\nexport async function analyzeAppManifestFile(filePath: string): Promise<DoctorDiagnostic[]> {\n let source: string;\n\n try {\n source = await fs.readFile(filePath, 'utf8');\n } catch (error) {\n return [\n createManifestDiagnostic({\n code: 'invalid-app-manifest-json',\n message: `Could not read app manifest JSON: ${toErrorMessage(error)}`,\n path: filePath,\n ruleId: 'manifest.json.readable',\n }),\n ];\n }\n\n let manifest: unknown;\n\n try {\n manifest = JSON.parse(source) as unknown;\n } catch (error) {\n return [\n createManifestDiagnostic({\n code: 'invalid-app-manifest-json',\n message: `App manifest must contain valid JSON: ${toErrorMessage(error)}`,\n path: filePath,\n ruleId: 'manifest.json.valid',\n }),\n ];\n }\n\n return analyzeAppManifest(manifest, filePath);\n}\n\nexport function analyzeAppManifest(\n manifest: unknown,\n manifestPath = 'manifest.json',\n): DoctorDiagnostic[] {\n if (!isRecord(manifest)) {\n return [\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'App manifest root must be a JSON object.',\n path: manifestPath,\n ruleId: 'manifest.root.valid-shape',\n }),\n ];\n }\n\n const diagnostics: DoctorDiagnostic[] = [];\n const { settings } = manifest;\n\n if (isRecord(settings) && hasOwn(settings, 'authFlow')) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message:\n 'settings.authFlow was removed. Move this configuration manually to infra.auth.flow; Doctor will not migrate it automatically.',\n path: manifestPath,\n ruleId: 'manifest.settings.auth-flow.removed',\n }),\n );\n }\n\n const { infra } = manifest;\n if (infra === undefined) {\n return diagnostics;\n }\n\n if (!isRecord(infra)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'manifest.infra must be a JSON object when present.',\n path: manifestPath,\n ruleId: 'manifest.infra.valid-shape',\n }),\n );\n return diagnostics;\n }\n\n diagnostics.push(...analyzeSecretStoreManifest(infra, manifestPath));\n\n const { auth } = infra;\n if (auth === undefined) {\n return diagnostics;\n }\n\n if (!isRecord(auth)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'manifest.infra.auth must be a JSON object when present.',\n path: manifestPath,\n ruleId: 'manifest.auth.valid-shape',\n }),\n );\n return diagnostics;\n }\n\n const flow = parseAuthFlow(auth.flow, manifestPath, diagnostics);\n if (flow !== null) {\n validateAuthFlowRelationships(flow, manifestPath, diagnostics);\n }\n\n validateAuthorization(auth.authorization, manifestPath, diagnostics);\n\n return diagnostics;\n}\n\nfunction parseAuthFlow(\n value: unknown,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): AuthFlowConfig | null {\n if (value === undefined) {\n return resolveAuthFlow();\n }\n\n if (!isRecord(value)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'manifest.infra.auth.flow must be a JSON object when present.',\n path: manifestPath,\n ruleId: 'manifest.auth.flow.valid-shape',\n }),\n );\n return null;\n }\n\n const signInRoute = readRequiredRoute(value, 'signInRoute', manifestPath, diagnostics);\n const postSignInRoute = readRequiredRoute(value, 'postSignInRoute', manifestPath, diagnostics);\n const optionalRoutes = readOptionalRoutes(value, manifestPath, diagnostics);\n\n if (signInRoute === null || postSignInRoute === null || optionalRoutes === null) {\n return null;\n }\n\n return resolveAuthFlow({\n signInRoute,\n postSignInRoute,\n ...optionalRoutes,\n });\n}\n\nfunction readRequiredRoute(\n flow: Record<string, unknown>,\n key: 'postSignInRoute' | 'signInRoute',\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): string | null {\n const value = flow[key];\n\n if (typeof value !== 'string' || value.trim() === '') {\n diagnostics.push(\n createManifestDiagnostic({\n code: value === undefined ? 'field-missing' : 'field-invalid',\n message: `manifest.infra.auth.flow.${key} must be a non-empty string.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.route.required',\n }),\n );\n return null;\n }\n\n return value;\n}\n\nfunction readOptionalRoutes(\n flow: Record<string, unknown>,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): Pick<AuthFlowConfig, OptionalRouteKey> | null {\n const routes: Partial<Pick<AuthFlowConfig, OptionalRouteKey>> = {};\n let valid = true;\n\n for (const key of OPTIONAL_ROUTE_KEYS) {\n const value = flow[key];\n if (value === undefined) {\n continue;\n }\n\n if (typeof value !== 'string' || value.trim() === '') {\n valid = false;\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `manifest.infra.auth.flow.${key} must be a non-empty string when present.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.route.valid',\n }),\n );\n continue;\n }\n\n routes[key] = value;\n }\n\n return valid ? routes : null;\n}\n\nfunction validateAuthFlowRelationships(\n flow: AuthFlowConfig,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): void {\n const actionRoutes = AUTH_ACTION_ROUTE_KEYS.flatMap((key) => {\n const value = flow[key];\n return typeof value === 'string' ? [{ key, route: normalizeRoute(value) }] : [];\n });\n const routesByName = new Map<string, AuthActionRouteKey[]>();\n\n for (const entry of actionRoutes) {\n const keys = routesByName.get(entry.route) ?? [];\n keys.push(entry.key);\n routesByName.set(entry.route, keys);\n }\n\n for (const [route, keys] of routesByName) {\n if (keys.length < 2) {\n continue;\n }\n\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `Auth action routes must be unique; ${keys.join(', ')} all resolve to \"${route}\".`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.route.unique',\n }),\n );\n }\n\n const postSignInRoute = normalizeRoute(flow.postSignInRoute);\n const collidingAction = actionRoutes.find((entry) => entry.route === postSignInRoute);\n if (collidingAction !== undefined) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `postSignInRoute must resolve outside the auth action routes; it collides with ${collidingAction.key}.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.post-sign-in.distinct',\n }),\n );\n }\n\n if (flow.unauthorizedRoute === undefined) {\n return;\n }\n\n const unauthorizedRoute = normalizeRoute(flow.unauthorizedRoute);\n const signInRoute = normalizeRoute(flow.signInRoute);\n\n if (unauthorizedRoute === postSignInRoute) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'unauthorizedRoute must not resolve to postSignInRoute.',\n path: manifestPath,\n ruleId: 'manifest.auth.flow.unauthorized-route.valid',\n }),\n );\n }\n\n if (unauthorizedRoute === signInRoute) {\n return;\n }\n\n const collidingActionRoute = actionRoutes.find(\n (entry) => entry.key !== 'signInRoute' && entry.route === unauthorizedRoute,\n );\n if (collidingActionRoute !== undefined) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `unauthorizedRoute may alias signInRoute, but it must not collide with ${collidingActionRoute.key}.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.unauthorized-route.valid',\n }),\n );\n }\n}\n\nfunction validateAuthorization(\n value: unknown,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): void {\n if (value === undefined) {\n return;\n }\n\n if (!isRecord(value)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message:\n 'manifest.infra.auth.authorization must be a JSON object when explicitly configured.',\n path: manifestPath,\n ruleId: 'manifest.auth.authorization.valid-shape',\n }),\n );\n return;\n }\n\n validateAuthorizationField({\n allowed: AUTHZ_KINDS,\n diagnostics,\n fieldName: 'kind',\n manifestPath,\n value: value.kind,\n ruleId: 'manifest.auth.authorization.kind.valid',\n });\n validateAuthorizationField({\n allowed: AUTHZ_ENGINES,\n diagnostics,\n fieldName: 'engine',\n manifestPath,\n value: value.engine,\n ruleId: 'manifest.auth.authorization.engine.valid',\n });\n}\n\nfunction validateAuthorizationField(request: {\n readonly allowed: readonly string[];\n readonly diagnostics: DoctorDiagnostic[];\n readonly fieldName: 'engine' | 'kind';\n readonly manifestPath: string;\n readonly ruleId: DoctorRuleId;\n readonly value: unknown;\n}): void {\n if (typeof request.value === 'string' && request.allowed.includes(request.value)) {\n return;\n }\n\n request.diagnostics.push(\n createManifestDiagnostic({\n code: request.value === undefined ? 'field-missing' : 'field-invalid',\n message: `Explicit authorization.${request.fieldName} must be one of: ${request.allowed.join(', ')}.`,\n path: request.manifestPath,\n ruleId: request.ruleId,\n }),\n );\n}\n\nfunction createManifestDiagnostic(request: {\n readonly code: DoctorDiagnosticCode;\n readonly message: string;\n readonly path: string;\n readonly ruleId: DoctorRuleId;\n}): DoctorDiagnostic {\n return {\n ...request,\n profile: MANIFEST_PROFILE,\n severity: 'error',\n };\n}\n\nfunction normalizeRoute(route: string): string {\n const normalized = route.trim().replace(/^\\/+/, '').replace(/\\/+$/, '');\n return normalized === '' ? 'index' : normalized;\n}\n\nfunction hasOwn(record: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nasync function statOrNull(filePath: string) {\n try {\n return await fs.stat(filePath);\n } catch {\n return null;\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"manifestAnalysis.js","sourceRoot":"","sources":["../src/manifestAnalysis.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport { AUTHZ_ENGINES, AUTHZ_KINDS } from '@ankhorage/contracts';\nimport { type AuthFlowConfig, resolveAuthFlow } from '@ankhorage/contracts/auth';\n\nimport type {\n DoctorAnalysisRequest,\n DoctorAnalysisResult,\n DoctorFixPlan,\n DoctorPlannedChange,\n} from './analysis.js';\nimport { analyzeAuthReadinessFile } from './authReadinessFileAnalysis.js';\nimport type {\n DoctorDiagnostic,\n DoctorDiagnosticCode,\n DoctorPolicyProfile,\n DoctorRuleId,\n} from './diagnostics.js';\nimport { analyzeSecretStoreManifest } from './secretManifestAnalysis.js';\n\nconst MANIFEST_PROFILE = 'app-manifest' satisfies DoctorPolicyProfile;\nconst AUTH_ACTION_ROUTE_KEYS = [\n 'signInRoute',\n 'signUpRoute',\n 'signOutRoute',\n 'forgotPasswordRoute',\n 'otpRoute',\n] as const satisfies readonly (keyof AuthFlowConfig)[];\nconst OPTIONAL_ROUTE_KEYS = [\n 'signUpRoute',\n 'signOutRoute',\n 'forgotPasswordRoute',\n 'otpRoute',\n 'unauthorizedRoute',\n] as const satisfies readonly (keyof AuthFlowConfig)[];\n\ntype AuthActionRouteKey = (typeof AUTH_ACTION_ROUTE_KEYS)[number];\ntype OptionalRouteKey = (typeof OPTIONAL_ROUTE_KEYS)[number];\n\nexport async function analyzeAppManifestTarget(\n request: DoctorAnalysisRequest,\n): Promise<DoctorAnalysisResult | null> {\n const targetPath = path.resolve(request.cwd, request.inputPath ?? '.');\n const stats = await statOrNull(targetPath);\n\n if (\n stats === null ||\n !stats.isFile() ||\n path.extname(targetPath).toLowerCase() !== '.json' ||\n (request.mode !== 'validate' && request.mode !== 'fix')\n ) {\n return null;\n }\n\n const authReadiness = await analyzeAuthReadinessFile(targetPath);\n const diagnostics = [...(await analyzeAppManifestFile(targetPath)), ...authReadiness.diagnostics];\n const plannedChanges: DoctorPlannedChange[] = [];\n const fixPlan: DoctorFixPlan | null =\n request.mode === 'fix'\n ? {\n changes: plannedChanges,\n diagnostics,\n profile: MANIFEST_PROFILE,\n targetPath,\n }\n : null;\n\n return {\n appliedChecks: ['manifest'],\n diagnostics,\n fixPlan,\n hasPackageJson: false,\n plannedChanges,\n profile: MANIFEST_PROFILE,\n readiness: authReadiness.readiness,\n repoMarkers: [],\n targetPath,\n };\n}\n\nexport async function analyzeAppManifestFile(filePath: string): Promise<DoctorDiagnostic[]> {\n let source: string;\n\n try {\n source = await fs.readFile(filePath, 'utf8');\n } catch (error) {\n return [\n createManifestDiagnostic({\n code: 'invalid-app-manifest-json',\n message: `Could not read app manifest JSON: ${toErrorMessage(error)}`,\n path: filePath,\n ruleId: 'manifest.json.readable',\n }),\n ];\n }\n\n let manifest: unknown;\n\n try {\n manifest = JSON.parse(source) as unknown;\n } catch (error) {\n return [\n createManifestDiagnostic({\n code: 'invalid-app-manifest-json',\n message: `App manifest must contain valid JSON: ${toErrorMessage(error)}`,\n path: filePath,\n ruleId: 'manifest.json.valid',\n }),\n ];\n }\n\n return analyzeAppManifest(manifest, filePath);\n}\n\nexport function analyzeAppManifest(\n manifest: unknown,\n manifestPath = 'manifest.json',\n): DoctorDiagnostic[] {\n if (!isRecord(manifest)) {\n return [\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'App manifest root must be a JSON object.',\n path: manifestPath,\n ruleId: 'manifest.root.valid-shape',\n }),\n ];\n }\n\n const diagnostics: DoctorDiagnostic[] = [];\n const { settings } = manifest;\n\n if (isRecord(settings) && hasOwn(settings, 'authFlow')) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message:\n 'settings.authFlow was removed. Move this configuration manually to infra.auth.flow; Doctor will not migrate it automatically.',\n path: manifestPath,\n ruleId: 'manifest.settings.auth-flow.removed',\n }),\n );\n }\n\n const { infra } = manifest;\n if (infra === undefined) {\n return diagnostics;\n }\n\n if (!isRecord(infra)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'manifest.infra must be a JSON object when present.',\n path: manifestPath,\n ruleId: 'manifest.infra.valid-shape',\n }),\n );\n return diagnostics;\n }\n\n diagnostics.push(...analyzeSecretStoreManifest(infra, manifestPath));\n\n const { auth } = infra;\n if (auth === undefined) {\n return diagnostics;\n }\n\n if (!isRecord(auth)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'manifest.infra.auth must be a JSON object when present.',\n path: manifestPath,\n ruleId: 'manifest.auth.valid-shape',\n }),\n );\n return diagnostics;\n }\n\n const flow = parseAuthFlow(auth.flow, manifestPath, diagnostics);\n if (flow !== null) {\n validateAuthFlowRelationships(flow, manifestPath, diagnostics);\n }\n\n validateAuthorization(auth.authorization, manifestPath, diagnostics);\n\n return diagnostics;\n}\n\nfunction parseAuthFlow(\n value: unknown,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): AuthFlowConfig | null {\n if (value === undefined) {\n return resolveAuthFlow();\n }\n\n if (!isRecord(value)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'manifest.infra.auth.flow must be a JSON object when present.',\n path: manifestPath,\n ruleId: 'manifest.auth.flow.valid-shape',\n }),\n );\n return null;\n }\n\n const signInRoute = readRequiredRoute(value, 'signInRoute', manifestPath, diagnostics);\n const postSignInRoute = readRequiredRoute(value, 'postSignInRoute', manifestPath, diagnostics);\n const optionalRoutes = readOptionalRoutes(value, manifestPath, diagnostics);\n\n if (signInRoute === null || postSignInRoute === null || optionalRoutes === null) {\n return null;\n }\n\n return resolveAuthFlow({\n signInRoute,\n postSignInRoute,\n ...optionalRoutes,\n });\n}\n\nfunction readRequiredRoute(\n flow: Record<string, unknown>,\n key: 'postSignInRoute' | 'signInRoute',\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): string | null {\n const value = flow[key];\n\n if (typeof value !== 'string' || value.trim() === '') {\n diagnostics.push(\n createManifestDiagnostic({\n code: value === undefined ? 'field-missing' : 'field-invalid',\n message: `manifest.infra.auth.flow.${key} must be a non-empty string.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.route.required',\n }),\n );\n return null;\n }\n\n return value;\n}\n\nfunction readOptionalRoutes(\n flow: Record<string, unknown>,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): Pick<AuthFlowConfig, OptionalRouteKey> | null {\n const routes: Partial<Pick<AuthFlowConfig, OptionalRouteKey>> = {};\n let valid = true;\n\n for (const key of OPTIONAL_ROUTE_KEYS) {\n const value = flow[key];\n if (value === undefined) {\n continue;\n }\n\n if (typeof value !== 'string' || value.trim() === '') {\n valid = false;\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `manifest.infra.auth.flow.${key} must be a non-empty string when present.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.route.valid',\n }),\n );\n continue;\n }\n\n routes[key] = value;\n }\n\n return valid ? routes : null;\n}\n\nfunction validateAuthFlowRelationships(\n flow: AuthFlowConfig,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): void {\n const actionRoutes = AUTH_ACTION_ROUTE_KEYS.flatMap((key) => {\n const value = flow[key];\n return typeof value === 'string' ? [{ key, route: normalizeRoute(value) }] : [];\n });\n const routesByName = new Map<string, AuthActionRouteKey[]>();\n\n for (const entry of actionRoutes) {\n const keys = routesByName.get(entry.route) ?? [];\n keys.push(entry.key);\n routesByName.set(entry.route, keys);\n }\n\n for (const [route, keys] of routesByName) {\n if (keys.length < 2) {\n continue;\n }\n\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `Auth action routes must be unique; ${keys.join(', ')} all resolve to \"${route}\".`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.route.unique',\n }),\n );\n }\n\n const postSignInRoute = normalizeRoute(flow.postSignInRoute);\n const collidingAction = actionRoutes.find((entry) => entry.route === postSignInRoute);\n if (collidingAction !== undefined) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `postSignInRoute must resolve outside the auth action routes; it collides with ${collidingAction.key}.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.post-sign-in.distinct',\n }),\n );\n }\n\n if (flow.unauthorizedRoute === undefined) {\n return;\n }\n\n const unauthorizedRoute = normalizeRoute(flow.unauthorizedRoute);\n const signInRoute = normalizeRoute(flow.signInRoute);\n\n if (unauthorizedRoute === postSignInRoute) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: 'unauthorizedRoute must not resolve to postSignInRoute.',\n path: manifestPath,\n ruleId: 'manifest.auth.flow.unauthorized-route.valid',\n }),\n );\n }\n\n if (unauthorizedRoute === signInRoute) {\n return;\n }\n\n const collidingActionRoute = actionRoutes.find(\n (entry) => entry.key !== 'signInRoute' && entry.route === unauthorizedRoute,\n );\n if (collidingActionRoute !== undefined) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message: `unauthorizedRoute may alias signInRoute, but it must not collide with ${collidingActionRoute.key}.`,\n path: manifestPath,\n ruleId: 'manifest.auth.flow.unauthorized-route.valid',\n }),\n );\n }\n}\n\nfunction validateAuthorization(\n value: unknown,\n manifestPath: string,\n diagnostics: DoctorDiagnostic[],\n): void {\n if (value === undefined) {\n return;\n }\n\n if (!isRecord(value)) {\n diagnostics.push(\n createManifestDiagnostic({\n code: 'field-invalid',\n message:\n 'manifest.infra.auth.authorization must be a JSON object when explicitly configured.',\n path: manifestPath,\n ruleId: 'manifest.auth.authorization.valid-shape',\n }),\n );\n return;\n }\n\n validateAuthorizationField({\n allowed: AUTHZ_KINDS,\n diagnostics,\n fieldName: 'kind',\n manifestPath,\n value: value.kind,\n ruleId: 'manifest.auth.authorization.kind.valid',\n });\n validateAuthorizationField({\n allowed: AUTHZ_ENGINES,\n diagnostics,\n fieldName: 'engine',\n manifestPath,\n value: value.engine,\n ruleId: 'manifest.auth.authorization.engine.valid',\n });\n}\n\nfunction validateAuthorizationField(request: {\n readonly allowed: readonly string[];\n readonly diagnostics: DoctorDiagnostic[];\n readonly fieldName: 'engine' | 'kind';\n readonly manifestPath: string;\n readonly ruleId: DoctorRuleId;\n readonly value: unknown;\n}): void {\n if (typeof request.value === 'string' && request.allowed.includes(request.value)) {\n return;\n }\n\n request.diagnostics.push(\n createManifestDiagnostic({\n code: request.value === undefined ? 'field-missing' : 'field-invalid',\n message: `Explicit authorization.${request.fieldName} must be one of: ${request.allowed.join(', ')}.`,\n path: request.manifestPath,\n ruleId: request.ruleId,\n }),\n );\n}\n\nfunction createManifestDiagnostic(request: {\n readonly code: DoctorDiagnosticCode;\n readonly message: string;\n readonly path: string;\n readonly ruleId: DoctorRuleId;\n}): DoctorDiagnostic {\n return {\n ...request,\n profile: MANIFEST_PROFILE,\n severity: 'error',\n };\n}\n\nfunction normalizeRoute(route: string): string {\n const normalized = route.trim().replace(/^\\/+/, '').replace(/\\/+$/, '');\n return normalized === '' ? 'index' : normalized;\n}\n\nfunction hasOwn(record: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nasync function statOrNull(filePath: string) {\n try {\n return await fs.stat(filePath);\n } catch {\n return null;\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AuthOAuthProviderId, AuthOAuthTransportId } from '@ankhorage/contracts/auth';
|
|
2
|
+
import type { AppDeployEnvironmentId, AppDeployTargetId } from '@ankhorage/contracts/deploy';
|
|
3
|
+
export type DoctorReadinessStatus = 'missing' | 'ready' | 'unsupported';
|
|
4
|
+
export interface DoctorReadiness {
|
|
5
|
+
readonly category: 'auth-oauth';
|
|
6
|
+
readonly environment: AppDeployEnvironmentId;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
readonly provider: AuthOAuthProviderId;
|
|
9
|
+
readonly status: DoctorReadinessStatus;
|
|
10
|
+
readonly target: AppDeployTargetId;
|
|
11
|
+
readonly transport: AuthOAuthTransportId;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=readiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7F,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAExE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.js","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"","sourcesContent":["import type { AuthOAuthProviderId, AuthOAuthTransportId } from '@ankhorage/contracts/auth';\nimport type { AppDeployEnvironmentId, AppDeployTargetId } from '@ankhorage/contracts/deploy';\n\nexport type DoctorReadinessStatus = 'missing' | 'ready' | 'unsupported';\n\nexport interface DoctorReadiness {\n readonly category: 'auth-oauth';\n readonly environment: AppDeployEnvironmentId;\n readonly message: string;\n readonly provider: AuthOAuthProviderId;\n readonly status: DoctorReadinessStatus;\n readonly target: AppDeployTargetId;\n readonly transport: AuthOAuthTransportId;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/doctor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Executable Ankh provider and standalone CLI for lightweight repo and package compliance diagnostics.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -77,7 +77,8 @@
|
|
|
77
77
|
"version-packages": "changeset version"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@ankhorage/contracts": "^
|
|
80
|
+
"@ankhorage/contracts": "^7.8.0",
|
|
81
|
+
"@ankhorage/supabase-auth": "^1.2.0"
|
|
81
82
|
},
|
|
82
83
|
"devDependencies": {
|
|
83
84
|
"@ankhorage/ankh": "^0.4.0",
|
package/src/analysis.ts
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
|
|
5
5
|
import type { DoctorDiagnostic, DoctorPolicyProfile, DoctorRuleId } from './diagnostics.js';
|
|
6
|
+
import type { DoctorReadiness } from './readiness.js';
|
|
6
7
|
|
|
7
8
|
export type DoctorTargetCheck = 'manifest' | 'package' | 'repo';
|
|
8
9
|
export type DoctorTargetMode = 'fix' | 'package' | 'repo' | 'validate';
|
|
@@ -37,6 +38,7 @@ export interface DoctorAnalysisResult {
|
|
|
37
38
|
readonly hasPackageJson: boolean;
|
|
38
39
|
readonly plannedChanges: readonly DoctorPlannedChange[];
|
|
39
40
|
readonly profile: DoctorPolicyProfile;
|
|
41
|
+
readonly readiness?: readonly DoctorReadiness[];
|
|
40
42
|
readonly repoMarkers: readonly string[];
|
|
41
43
|
readonly targetPath: string;
|
|
42
44
|
}
|