@ankhorage/doctor 0.8.0 → 0.10.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/analysis.d.ts +2 -0
  3. package/dist/analysis.d.ts.map +1 -1
  4. package/dist/analysis.js.map +1 -1
  5. package/dist/authReadinessAnalysis.d.ts +8 -0
  6. package/dist/authReadinessAnalysis.d.ts.map +1 -0
  7. package/dist/authReadinessAnalysis.js +38 -0
  8. package/dist/authReadinessAnalysis.js.map +1 -0
  9. package/dist/authReadinessDiagnostic.d.ts +9 -0
  10. package/dist/authReadinessDiagnostic.d.ts.map +1 -0
  11. package/dist/authReadinessDiagnostic.js +11 -0
  12. package/dist/authReadinessDiagnostic.js.map +1 -0
  13. package/dist/authReadinessEnvironment.d.ts +16 -0
  14. package/dist/authReadinessEnvironment.d.ts.map +1 -0
  15. package/dist/authReadinessEnvironment.js +34 -0
  16. package/dist/authReadinessEnvironment.js.map +1 -0
  17. package/dist/authReadinessFileAnalysis.d.ts +3 -0
  18. package/dist/authReadinessFileAnalysis.d.ts.map +1 -0
  19. package/dist/authReadinessFileAnalysis.js +12 -0
  20. package/dist/authReadinessFileAnalysis.js.map +1 -0
  21. package/dist/authReadinessNativeContext.d.ts +13 -0
  22. package/dist/authReadinessNativeContext.d.ts.map +1 -0
  23. package/dist/authReadinessNativeContext.js +19 -0
  24. package/dist/authReadinessNativeContext.js.map +1 -0
  25. package/dist/authReadinessNativeDiagnostic.d.ts +4 -0
  26. package/dist/authReadinessNativeDiagnostic.d.ts.map +1 -0
  27. package/dist/authReadinessNativeDiagnostic.js +11 -0
  28. package/dist/authReadinessNativeDiagnostic.js.map +1 -0
  29. package/dist/authReadinessProvider.d.ts +15 -0
  30. package/dist/authReadinessProvider.d.ts.map +1 -0
  31. package/dist/authReadinessProvider.js +44 -0
  32. package/dist/authReadinessProvider.js.map +1 -0
  33. package/dist/authReadinessProviderEnvironment.d.ts +15 -0
  34. package/dist/authReadinessProviderEnvironment.d.ts.map +1 -0
  35. package/dist/authReadinessProviderEnvironment.js +35 -0
  36. package/dist/authReadinessProviderEnvironment.js.map +1 -0
  37. package/dist/authReadinessRequirements.d.ts +10 -0
  38. package/dist/authReadinessRequirements.d.ts.map +1 -0
  39. package/dist/authReadinessRequirements.js +34 -0
  40. package/dist/authReadinessRequirements.js.map +1 -0
  41. package/dist/authReadinessTargetFallback.d.ts +3 -0
  42. package/dist/authReadinessTargetFallback.d.ts.map +1 -0
  43. package/dist/authReadinessTargetFallback.js +32 -0
  44. package/dist/authReadinessTargetFallback.js.map +1 -0
  45. package/dist/authReadinessTargetResolution.d.ts +8 -0
  46. package/dist/authReadinessTargetResolution.d.ts.map +1 -0
  47. package/dist/authReadinessTargetResolution.js +2 -0
  48. package/dist/authReadinessTargetResolution.js.map +1 -0
  49. package/dist/authReadinessTargets.d.ts +3 -0
  50. package/dist/authReadinessTargets.d.ts.map +1 -0
  51. package/dist/authReadinessTargets.js +26 -0
  52. package/dist/authReadinessTargets.js.map +1 -0
  53. package/dist/authReadinessUnsupported.d.ts +13 -0
  54. package/dist/authReadinessUnsupported.d.ts.map +1 -0
  55. package/dist/authReadinessUnsupported.js +22 -0
  56. package/dist/authReadinessUnsupported.js.map +1 -0
  57. package/dist/authReadinessUnsupportedBackend.d.ts +12 -0
  58. package/dist/authReadinessUnsupportedBackend.d.ts.map +1 -0
  59. package/dist/authReadinessUnsupportedBackend.js +18 -0
  60. package/dist/authReadinessUnsupportedBackend.js.map +1 -0
  61. package/dist/commands.d.ts.map +1 -1
  62. package/dist/commands.js +14 -0
  63. package/dist/commands.js.map +1 -1
  64. package/dist/diagnostics.d.ts +1 -1
  65. package/dist/diagnostics.d.ts.map +1 -1
  66. package/dist/diagnostics.js.map +1 -1
  67. package/dist/index.d.ts +3 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +2 -0
  70. package/dist/index.js.map +1 -1
  71. package/dist/manifestAnalysis.d.ts.map +1 -1
  72. package/dist/manifestAnalysis.js +4 -1
  73. package/dist/manifestAnalysis.js.map +1 -1
  74. package/dist/readiness.d.ts +15 -0
  75. package/dist/readiness.d.ts.map +1 -0
  76. package/dist/readiness.js +2 -0
  77. package/dist/readiness.js.map +1 -0
  78. package/package.json +3 -2
  79. package/src/analysis.ts +2 -0
  80. package/src/authReadinessAnalysis.ts +50 -0
  81. package/src/authReadinessDiagnostic.ts +18 -0
  82. package/src/authReadinessEnvironment.ts +58 -0
  83. package/src/authReadinessFileAnalysis.ts +14 -0
  84. package/src/authReadinessNativeContext.ts +37 -0
  85. package/src/authReadinessNativeDiagnostic.ts +17 -0
  86. package/src/authReadinessProvider.ts +61 -0
  87. package/src/authReadinessProviderEnvironment.ts +54 -0
  88. package/src/authReadinessRequirements.ts +50 -0
  89. package/src/authReadinessTargetFallback.ts +38 -0
  90. package/src/authReadinessTargetResolution.ts +9 -0
  91. package/src/authReadinessTargets.ts +35 -0
  92. package/src/authReadinessUnsupported.ts +34 -0
  93. package/src/authReadinessUnsupportedBackend.ts +34 -0
  94. package/src/commands.ts +16 -0
  95. package/src/diagnostics.ts +5 -0
  96. package/src/index.ts +3 -0
  97. package/src/manifestAnalysis.ts +4 -1
  98. package/src/readiness.ts +16 -0
@@ -0,0 +1,19 @@
1
+ export function resolveNativeAuthReadinessContext(input) {
2
+ if (input.target === 'web')
3
+ return {};
4
+ const callbackScheme = input.targets[input.target]?.scheme;
5
+ return {
6
+ ...(callbackScheme === undefined ? {} : { callbackScheme }),
7
+ hostRequirement: 'development-or-standalone-build',
8
+ };
9
+ }
10
+ export function createAuthReadinessMessage(input) {
11
+ const base = input.missing.length === 0
12
+ ? 'Manifest and adapter setup requirements are satisfiable; concrete callback URLs remain Infra/runtime-owned.'
13
+ : `Missing ${input.missing.join(' and ')}.`;
14
+ if (input.target === 'web')
15
+ return base;
16
+ const scheme = input.callbackScheme === undefined ? '' : ` Callback scheme: ${input.callbackScheme}.`;
17
+ return `${base}${scheme} Native OAuth requires a development or standalone app build; runtime host compatibility remains runtime-owned.`;
18
+ }
19
+ //# sourceMappingURL=authReadinessNativeContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessNativeContext.js","sourceRoot":"","sources":["../src/authReadinessNativeContext.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,iCAAiC,CAAC,KAGjD;IACC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAC3D,OAAO;QACL,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC;QAC3D,eAAe,EAAE,iCAAiC;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAI1C;IACC,MAAM,IAAI,GACR,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QACxB,CAAC,CAAC,6GAA6G;QAC/G,CAAC,CAAC,WAAW,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAExC,MAAM,MAAM,GACV,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,KAAK,CAAC,cAAc,GAAG,CAAC;IACzF,OAAO,GAAG,IAAI,GAAG,MAAM,iHAAiH,CAAC;AAC3I,CAAC","sourcesContent":["import type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';\n\nimport type { DoctorReadiness } from './readiness.js';\n\nexport type NativeAuthReadinessContext = Pick<\n DoctorReadiness,\n 'callbackScheme' | 'hostRequirement'\n>;\n\nexport function resolveNativeAuthReadinessContext(input: {\n readonly target: AppDeployTargetId;\n readonly targets: AppDeployTargets;\n}): NativeAuthReadinessContext {\n if (input.target === 'web') return {};\n\n const callbackScheme = input.targets[input.target]?.scheme;\n return {\n ...(callbackScheme === undefined ? {} : { callbackScheme }),\n hostRequirement: 'development-or-standalone-build',\n };\n}\n\nexport function createAuthReadinessMessage(input: {\n readonly callbackScheme?: string;\n readonly missing: readonly string[];\n readonly target: AppDeployTargetId;\n}): string {\n const base =\n input.missing.length === 0\n ? 'Manifest and adapter setup requirements are satisfiable; concrete callback URLs remain Infra/runtime-owned.'\n : `Missing ${input.missing.join(' and ')}.`;\n if (input.target === 'web') return base;\n\n const scheme =\n input.callbackScheme === undefined ? '' : ` Callback scheme: ${input.callbackScheme}.`;\n return `${base}${scheme} Native OAuth requires a development or standalone app build; runtime host compatibility remains runtime-owned.`;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { AppDeployTargetId } from '@ankhorage/contracts/deploy';
2
+ import type { DoctorDiagnostic } from './diagnostics.js';
3
+ export declare function createNativeAuthCallbackDiagnostic(target: AppDeployTargetId, path: string): DoctorDiagnostic;
4
+ //# sourceMappingURL=authReadinessNativeDiagnostic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessNativeDiagnostic.d.ts","sourceRoot":"","sources":["../src/authReadinessNativeDiagnostic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,MAAM,GACX,gBAAgB,CAQlB"}
@@ -0,0 +1,11 @@
1
+ import { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';
2
+ export function createNativeAuthCallbackDiagnostic(target, path) {
3
+ return createAuthReadinessDiagnostic({
4
+ code: 'field-missing',
5
+ message: `Enabled ${target} brokered OAuth requires deploy.targets.${target}.scheme for the app callback.`,
6
+ path,
7
+ ruleId: 'manifest.auth.oauth.callback-target.configured',
8
+ severity: 'error',
9
+ });
10
+ }
11
+ //# sourceMappingURL=authReadinessNativeDiagnostic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessNativeDiagnostic.js","sourceRoot":"","sources":["../src/authReadinessNativeDiagnostic.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAG7E,MAAM,UAAU,kCAAkC,CAChD,MAAyB,EACzB,IAAY;IAEZ,OAAO,6BAA6B,CAAC;QACnC,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,WAAW,MAAM,2CAA2C,MAAM,+BAA+B;QAC1G,IAAI;QACJ,MAAM,EAAE,gDAAgD;QACxD,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { AppDeployTargetId } from '@ankhorage/contracts/deploy';\n\nimport { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';\nimport type { DoctorDiagnostic } from './diagnostics.js';\n\nexport function createNativeAuthCallbackDiagnostic(\n target: AppDeployTargetId,\n path: string,\n): DoctorDiagnostic {\n return createAuthReadinessDiagnostic({\n code: 'field-missing',\n message: `Enabled ${target} brokered OAuth requires deploy.targets.${target}.scheme for the app callback.`,\n path,\n ruleId: 'manifest.auth.oauth.callback-target.configured',\n severity: 'error',\n });\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';
2
+ import type { DoctorDiagnostic } from './diagnostics.js';
3
+ import type { DoctorReadiness } from './readiness.js';
4
+ export declare function analyzeAuthProviderReadiness(input: {
5
+ readonly authProvider: unknown;
6
+ readonly callbackRoute: unknown;
7
+ readonly enabledTargets: readonly AppDeployTargetId[];
8
+ readonly manifestPath: string;
9
+ readonly provider: Record<string, unknown>;
10
+ readonly targets: AppDeployTargets;
11
+ }): {
12
+ readonly diagnostics: DoctorDiagnostic[];
13
+ readonly readiness: DoctorReadiness[];
14
+ };
15
+ //# sourceMappingURL=authReadinessProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessProvider.d.ts","sourceRoot":"","sources":["../src/authReadinessProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAOvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACpC,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,EAAE,CAAA;CAAE,CA2CtF"}
@@ -0,0 +1,44 @@
1
+ import { APP_DEPLOY_ENVIRONMENT_IDS } from '@ankhorage/contracts/deploy';
2
+ import { createNativeAuthCallbackDiagnostic } from './authReadinessNativeDiagnostic.js';
3
+ import { analyzeAuthProviderEnvironment } from './authReadinessProviderEnvironment.js';
4
+ import { createUnsupportedAuthDiagnostic } from './authReadinessUnsupported.js';
5
+ import { analyzeUnsupportedAuthBackend } from './authReadinessUnsupportedBackend.js';
6
+ export function analyzeAuthProviderReadiness(input) {
7
+ const providerId = typeof input.provider.id === 'string' ? input.provider.id : '';
8
+ if (providerId === '')
9
+ return { diagnostics: [], readiness: [] };
10
+ if (input.authProvider !== 'supabase') {
11
+ const result = analyzeUnsupportedAuthBackend({
12
+ enabledTargets: input.enabledTargets,
13
+ manifestPath: input.manifestPath,
14
+ provider: providerId,
15
+ });
16
+ return { diagnostics: [...result.diagnostics], readiness: [...result.readiness] };
17
+ }
18
+ const diagnostics = [];
19
+ const readiness = [];
20
+ const missingNativeTargets = new Set();
21
+ let unsupported = false;
22
+ for (const environment of APP_DEPLOY_ENVIRONMENT_IDS) {
23
+ const result = analyzeAuthProviderEnvironment({
24
+ callbackRoute: input.callbackRoute,
25
+ credentialsRef: input.provider.credentialsRef,
26
+ enabledTargets: input.enabledTargets,
27
+ environment,
28
+ provider: providerId,
29
+ targets: input.targets,
30
+ });
31
+ readiness.push(...result.readiness);
32
+ unsupported ||= result.unsupported;
33
+ result.missingNativeTargets.forEach((target) => missingNativeTargets.add(target));
34
+ }
35
+ if (unsupported) {
36
+ diagnostics.push(createUnsupportedAuthDiagnostic({
37
+ message: `OAuth provider "${providerId}" is not supported by the Supabase brokeredRedirect setup resolver.`,
38
+ path: input.manifestPath,
39
+ }));
40
+ }
41
+ missingNativeTargets.forEach((target) => diagnostics.push(createNativeAuthCallbackDiagnostic(target, input.manifestPath)));
42
+ return { diagnostics, readiness };
43
+ }
44
+ //# sourceMappingURL=authReadinessProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessProvider.js","sourceRoot":"","sources":["../src/authReadinessProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEzE,OAAO,EAAE,kCAAkC,EAAE,MAAM,oCAAoC,CAAC;AACxF,OAAO,EAAE,8BAA8B,EAAE,MAAM,uCAAuC,CAAC;AACvF,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAIrF,MAAM,UAAU,4BAA4B,CAAC,KAO5C;IACC,MAAM,UAAU,GAAG,OAAO,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,IAAI,UAAU,KAAK,EAAE;QAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACjE,IAAI,KAAK,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,6BAA6B,CAAC;YAC3C,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,QAAQ,EAAE,UAAU;SACrB,CAAC,CAAC;QACH,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;IACpF,CAAC;IAED,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAsB,EAAE,CAAC;IACxC,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1D,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,KAAK,MAAM,WAAW,IAAI,0BAA0B,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,8BAA8B,CAAC;YAC5C,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc;YAC7C,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,WAAW;YACX,QAAQ,EAAE,UAAU;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QACpC,WAAW,KAAK,MAAM,CAAC,WAAW,CAAC;QACnC,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,CACd,+BAA+B,CAAC;YAC9B,OAAO,EAAE,mBAAmB,UAAU,qEAAqE;YAC3G,IAAI,EAAE,KAAK,CAAC,YAAY;SACzB,CAAC,CACH,CAAC;IACJ,CAAC;IACD,oBAAoB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACtC,WAAW,CAAC,IAAI,CAAC,kCAAkC,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CACjF,CAAC;IACF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AACpC,CAAC","sourcesContent":["import type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';\nimport { APP_DEPLOY_ENVIRONMENT_IDS } from '@ankhorage/contracts/deploy';\n\nimport { createNativeAuthCallbackDiagnostic } from './authReadinessNativeDiagnostic.js';\nimport { analyzeAuthProviderEnvironment } from './authReadinessProviderEnvironment.js';\nimport { createUnsupportedAuthDiagnostic } from './authReadinessUnsupported.js';\nimport { analyzeUnsupportedAuthBackend } from './authReadinessUnsupportedBackend.js';\nimport type { DoctorDiagnostic } from './diagnostics.js';\nimport type { DoctorReadiness } from './readiness.js';\n\nexport function analyzeAuthProviderReadiness(input: {\n readonly authProvider: unknown;\n readonly callbackRoute: unknown;\n readonly enabledTargets: readonly AppDeployTargetId[];\n readonly manifestPath: string;\n readonly provider: Record<string, unknown>;\n readonly targets: AppDeployTargets;\n}): { readonly diagnostics: DoctorDiagnostic[]; readonly readiness: DoctorReadiness[] } {\n const providerId = typeof input.provider.id === 'string' ? input.provider.id : '';\n if (providerId === '') return { diagnostics: [], readiness: [] };\n if (input.authProvider !== 'supabase') {\n const result = analyzeUnsupportedAuthBackend({\n enabledTargets: input.enabledTargets,\n manifestPath: input.manifestPath,\n provider: providerId,\n });\n return { diagnostics: [...result.diagnostics], readiness: [...result.readiness] };\n }\n\n const diagnostics: DoctorDiagnostic[] = [];\n const readiness: DoctorReadiness[] = [];\n const missingNativeTargets = new Set<AppDeployTargetId>();\n let unsupported = false;\n\n for (const environment of APP_DEPLOY_ENVIRONMENT_IDS) {\n const result = analyzeAuthProviderEnvironment({\n callbackRoute: input.callbackRoute,\n credentialsRef: input.provider.credentialsRef,\n enabledTargets: input.enabledTargets,\n environment,\n provider: providerId,\n targets: input.targets,\n });\n readiness.push(...result.readiness);\n unsupported ||= result.unsupported;\n result.missingNativeTargets.forEach((target) => missingNativeTargets.add(target));\n }\n\n if (unsupported) {\n diagnostics.push(\n createUnsupportedAuthDiagnostic({\n message: `OAuth provider \"${providerId}\" is not supported by the Supabase brokeredRedirect setup resolver.`,\n path: input.manifestPath,\n }),\n );\n }\n missingNativeTargets.forEach((target) =>\n diagnostics.push(createNativeAuthCallbackDiagnostic(target, input.manifestPath)),\n );\n return { diagnostics, readiness };\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { AppDeployEnvironmentId, AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';
2
+ import type { DoctorReadiness } from './readiness.js';
3
+ export declare function analyzeAuthProviderEnvironment(input: {
4
+ readonly callbackRoute: unknown;
5
+ readonly credentialsRef: unknown;
6
+ readonly enabledTargets: readonly AppDeployTargetId[];
7
+ readonly environment: AppDeployEnvironmentId;
8
+ readonly provider: string;
9
+ readonly targets: AppDeployTargets;
10
+ }): {
11
+ readonly missingNativeTargets: readonly AppDeployTargetId[];
12
+ readonly readiness: readonly DoctorReadiness[];
13
+ readonly unsupported: boolean;
14
+ };
15
+ //# sourceMappingURL=authReadinessProviderEnvironment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessProviderEnvironment.d.ts","sourceRoot":"","sources":["../src/authReadinessProviderEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,6BAA6B,CAAC;AAKrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE;IACpD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtD,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACpC,GAAG;IACF,QAAQ,CAAC,oBAAoB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B,CA+BA"}
@@ -0,0 +1,35 @@
1
+ import { resolveSupabaseOAuthSetupPlan } from '@ankhorage/supabase-auth';
2
+ import { analyzeAuthReadinessEnvironment } from './authReadinessEnvironment.js';
3
+ import { createUnsupportedAuthReadiness } from './authReadinessUnsupported.js';
4
+ export function analyzeAuthProviderEnvironment(input) {
5
+ const plan = resolveSupabaseOAuthSetupPlan({
6
+ provider: input.provider,
7
+ transport: 'brokeredRedirect',
8
+ environment: input.environment,
9
+ targets: input.enabledTargets,
10
+ });
11
+ if (plan === null) {
12
+ return {
13
+ missingNativeTargets: [],
14
+ readiness: createUnsupportedAuthReadiness({
15
+ environment: input.environment,
16
+ provider: input.provider,
17
+ targets: input.enabledTargets,
18
+ }),
19
+ unsupported: true,
20
+ };
21
+ }
22
+ return {
23
+ ...analyzeAuthReadinessEnvironment({
24
+ callbackRoute: input.callbackRoute,
25
+ credentialsRef: input.credentialsRef,
26
+ enabledTargets: input.enabledTargets,
27
+ environment: input.environment,
28
+ plan,
29
+ provider: input.provider,
30
+ targets: input.targets,
31
+ }),
32
+ unsupported: false,
33
+ };
34
+ }
35
+ //# sourceMappingURL=authReadinessProviderEnvironment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessProviderEnvironment.js","sourceRoot":"","sources":["../src/authReadinessProviderEnvironment.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAEzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAG/E,MAAM,UAAU,8BAA8B,CAAC,KAO9C;IAKC,MAAM,IAAI,GAAG,6BAA6B,CAAC;QACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,kBAAkB;QAC7B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,KAAK,CAAC,cAAc;KAC9B,CAAC,CAAC;IACH,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO;YACL,oBAAoB,EAAE,EAAE;YACxB,SAAS,EAAE,8BAA8B,CAAC;gBACxC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,OAAO,EAAE,KAAK,CAAC,cAAc;aAC9B,CAAC;YACF,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,GAAG,+BAA+B,CAAC;YACjC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,IAAI;YACJ,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;QACF,WAAW,EAAE,KAAK;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import type {\n AppDeployEnvironmentId,\n AppDeployTargetId,\n AppDeployTargets,\n} from '@ankhorage/contracts/deploy';\nimport { resolveSupabaseOAuthSetupPlan } from '@ankhorage/supabase-auth';\n\nimport { analyzeAuthReadinessEnvironment } from './authReadinessEnvironment.js';\nimport { createUnsupportedAuthReadiness } from './authReadinessUnsupported.js';\nimport type { DoctorReadiness } from './readiness.js';\n\nexport function analyzeAuthProviderEnvironment(input: {\n readonly callbackRoute: unknown;\n readonly credentialsRef: unknown;\n readonly enabledTargets: readonly AppDeployTargetId[];\n readonly environment: AppDeployEnvironmentId;\n readonly provider: string;\n readonly targets: AppDeployTargets;\n}): {\n readonly missingNativeTargets: readonly AppDeployTargetId[];\n readonly readiness: readonly DoctorReadiness[];\n readonly unsupported: boolean;\n} {\n const plan = resolveSupabaseOAuthSetupPlan({\n provider: input.provider,\n transport: 'brokeredRedirect',\n environment: input.environment,\n targets: input.enabledTargets,\n });\n if (plan === null) {\n return {\n missingNativeTargets: [],\n readiness: createUnsupportedAuthReadiness({\n environment: input.environment,\n provider: input.provider,\n targets: input.enabledTargets,\n }),\n unsupported: true,\n };\n }\n\n return {\n ...analyzeAuthReadinessEnvironment({\n callbackRoute: input.callbackRoute,\n credentialsRef: input.credentialsRef,\n enabledTargets: input.enabledTargets,\n environment: input.environment,\n plan,\n provider: input.provider,\n targets: input.targets,\n }),\n unsupported: false,\n };\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { AuthOAuthSetupPlan } from '@ankhorage/contracts/auth';
2
+ import type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';
3
+ export declare function collectMissingAuthReadinessRequirements(input: {
4
+ readonly callbackRoute: unknown;
5
+ readonly credentialsRef: unknown;
6
+ readonly plan: AuthOAuthSetupPlan;
7
+ readonly target: AppDeployTargetId;
8
+ readonly targets: AppDeployTargets;
9
+ }): readonly string[];
10
+ //# sourceMappingURL=authReadinessRequirements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessRequirements.d.ts","sourceRoot":"","sources":["../src/authReadinessRequirements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGvF,wBAAgB,uCAAuC,CAAC,KAAK,EAAE;IAC7D,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACpC,GAAG,SAAS,MAAM,EAAE,CAoBpB"}
@@ -0,0 +1,34 @@
1
+ import { normalizeSecretRef } from '@ankhorage/contracts/secrets';
2
+ export function collectMissingAuthReadinessRequirements(input) {
3
+ const missing = [];
4
+ if (requiresTrustedCredential(input.plan) && !hasCanonicalCredentialRef(input.credentialsRef)) {
5
+ missing.push('credential reference');
6
+ }
7
+ const callbackRequired = input.plan.requirements.some((requirement) => requirement.kind === 'callback' &&
8
+ requirement.role === 'app' &&
9
+ requirement.required &&
10
+ requirement.target === input.target);
11
+ if (!callbackRequired)
12
+ return missing;
13
+ if (!isAbsoluteRoute(input.callbackRoute))
14
+ missing.push('callback route');
15
+ if (input.target !== 'web' && input.targets[input.target]?.scheme === undefined) {
16
+ missing.push(`${input.target} deep-link scheme`);
17
+ }
18
+ return missing;
19
+ }
20
+ function requiresTrustedCredential(plan) {
21
+ return plan.requirements.some((requirement) => requirement.kind === 'field' &&
22
+ requirement.required &&
23
+ requirement.persistence === 'trustedCredential');
24
+ }
25
+ function hasCanonicalCredentialRef(value) {
26
+ if (typeof value !== 'string')
27
+ return false;
28
+ const result = normalizeSecretRef(value);
29
+ return result.ok && result.data === value;
30
+ }
31
+ function isAbsoluteRoute(value) {
32
+ return typeof value === 'string' && value.trim().startsWith('/') && value.trim().length > 0;
33
+ }
34
+ //# sourceMappingURL=authReadinessRequirements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessRequirements.js","sourceRoot":"","sources":["../src/authReadinessRequirements.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,UAAU,uCAAuC,CAAC,KAMvD;IACC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,yBAAyB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;QAC9F,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CACnD,CAAC,WAAW,EAAE,EAAE,CACd,WAAW,CAAC,IAAI,KAAK,UAAU;QAC/B,WAAW,CAAC,IAAI,KAAK,KAAK;QAC1B,WAAW,CAAC,QAAQ;QACpB,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CACtC,CAAC;IACF,IAAI,CAAC,gBAAgB;QAAE,OAAO,OAAO,CAAC;IAEtC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,mBAAmB,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAwB;IACzD,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAC3B,CAAC,WAAW,EAAE,EAAE,CACd,WAAW,CAAC,IAAI,KAAK,OAAO;QAC5B,WAAW,CAAC,QAAQ;QACpB,WAAW,CAAC,WAAW,KAAK,mBAAmB,CAClD,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAc;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;AAC5C,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9F,CAAC","sourcesContent":["import type { AuthOAuthSetupPlan } from '@ankhorage/contracts/auth';\nimport type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';\nimport { normalizeSecretRef } from '@ankhorage/contracts/secrets';\n\nexport function collectMissingAuthReadinessRequirements(input: {\n readonly callbackRoute: unknown;\n readonly credentialsRef: unknown;\n readonly plan: AuthOAuthSetupPlan;\n readonly target: AppDeployTargetId;\n readonly targets: AppDeployTargets;\n}): readonly string[] {\n const missing: string[] = [];\n if (requiresTrustedCredential(input.plan) && !hasCanonicalCredentialRef(input.credentialsRef)) {\n missing.push('credential reference');\n }\n\n const callbackRequired = input.plan.requirements.some(\n (requirement) =>\n requirement.kind === 'callback' &&\n requirement.role === 'app' &&\n requirement.required &&\n requirement.target === input.target,\n );\n if (!callbackRequired) return missing;\n\n if (!isAbsoluteRoute(input.callbackRoute)) missing.push('callback route');\n if (input.target !== 'web' && input.targets[input.target]?.scheme === undefined) {\n missing.push(`${input.target} deep-link scheme`);\n }\n return missing;\n}\n\nfunction requiresTrustedCredential(plan: AuthOAuthSetupPlan): boolean {\n return plan.requirements.some(\n (requirement) =>\n requirement.kind === 'field' &&\n requirement.required &&\n requirement.persistence === 'trustedCredential',\n );\n}\n\nfunction hasCanonicalCredentialRef(value: unknown): boolean {\n if (typeof value !== 'string') return false;\n const result = normalizeSecretRef(value);\n return result.ok && result.data === value;\n}\n\nfunction isAbsoluteRoute(value: unknown): boolean {\n return typeof value === 'string' && value.trim().startsWith('/') && value.trim().length > 0;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { AuthReadinessTargetResolution } from './authReadinessTargetResolution.js';
2
+ export declare function resolveAuthReadinessTargetFallback(deploy: unknown, manifestPath: string): AuthReadinessTargetResolution;
3
+ //# sourceMappingURL=authReadinessTargetFallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessTargetFallback.d.ts","sourceRoot":"","sources":["../src/authReadinessTargetFallback.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAExF,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,MAAM,GACnB,6BAA6B,CA+B/B"}
@@ -0,0 +1,32 @@
1
+ import { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';
2
+ export function resolveAuthReadinessTargetFallback(deploy, manifestPath) {
3
+ if (deploy === undefined) {
4
+ return {
5
+ diagnostics: [
6
+ createAuthReadinessDiagnostic({
7
+ code: 'field-missing',
8
+ message: 'deploy.targets is missing; Doctor evaluates legacy Web-only readiness until canonical targets are persisted.',
9
+ path: manifestPath,
10
+ ruleId: 'manifest.deploy.targets.legacy-web',
11
+ severity: 'warning',
12
+ }),
13
+ ],
14
+ enabledTargets: ['web'],
15
+ targets: { web: { enabled: true } },
16
+ };
17
+ }
18
+ return {
19
+ diagnostics: [
20
+ createAuthReadinessDiagnostic({
21
+ code: 'field-invalid',
22
+ message: 'manifest.deploy must match the canonical Contracts deploy target model.',
23
+ path: manifestPath,
24
+ ruleId: 'manifest.deploy.valid-shape',
25
+ severity: 'error',
26
+ }),
27
+ ],
28
+ enabledTargets: [],
29
+ targets: null,
30
+ };
31
+ }
32
+ //# sourceMappingURL=authReadinessTargetFallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessTargetFallback.js","sourceRoot":"","sources":["../src/authReadinessTargetFallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAG7E,MAAM,UAAU,kCAAkC,CAChD,MAAe,EACf,YAAoB;IAEpB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;YACL,WAAW,EAAE;gBACX,6BAA6B,CAAC;oBAC5B,IAAI,EAAE,eAAe;oBACrB,OAAO,EACL,8GAA8G;oBAChH,IAAI,EAAE,YAAY;oBAClB,MAAM,EAAE,oCAAoC;oBAC5C,QAAQ,EAAE,SAAS;iBACpB,CAAC;aACH;YACD,cAAc,EAAE,CAAC,KAAK,CAAC;YACvB,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;SACpC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,WAAW,EAAE;YACX,6BAA6B,CAAC;gBAC5B,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,yEAAyE;gBAClF,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,6BAA6B;gBACrC,QAAQ,EAAE,OAAO;aAClB,CAAC;SACH;QACD,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC","sourcesContent":["import { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';\nimport type { AuthReadinessTargetResolution } from './authReadinessTargetResolution.js';\n\nexport function resolveAuthReadinessTargetFallback(\n deploy: unknown,\n manifestPath: string,\n): AuthReadinessTargetResolution {\n if (deploy === undefined) {\n return {\n diagnostics: [\n createAuthReadinessDiagnostic({\n code: 'field-missing',\n message:\n 'deploy.targets is missing; Doctor evaluates legacy Web-only readiness until canonical targets are persisted.',\n path: manifestPath,\n ruleId: 'manifest.deploy.targets.legacy-web',\n severity: 'warning',\n }),\n ],\n enabledTargets: ['web'],\n targets: { web: { enabled: true } },\n };\n }\n\n return {\n diagnostics: [\n createAuthReadinessDiagnostic({\n code: 'field-invalid',\n message: 'manifest.deploy must match the canonical Contracts deploy target model.',\n path: manifestPath,\n ruleId: 'manifest.deploy.valid-shape',\n severity: 'error',\n }),\n ],\n enabledTargets: [],\n targets: null,\n };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';
2
+ import type { DoctorDiagnostic } from './diagnostics.js';
3
+ export interface AuthReadinessTargetResolution {
4
+ readonly diagnostics: readonly DoctorDiagnostic[];
5
+ readonly enabledTargets: readonly AppDeployTargetId[];
6
+ readonly targets: AppDeployTargets | null;
7
+ }
8
+ //# sourceMappingURL=authReadinessTargetResolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessTargetResolution.d.ts","sourceRoot":"","sources":["../src/authReadinessTargetResolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAClD,QAAQ,CAAC,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtD,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC3C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=authReadinessTargetResolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessTargetResolution.js","sourceRoot":"","sources":["../src/authReadinessTargetResolution.ts"],"names":[],"mappings":"","sourcesContent":["import type { AppDeployTargetId, AppDeployTargets } from '@ankhorage/contracts/deploy';\n\nimport type { DoctorDiagnostic } from './diagnostics.js';\n\nexport interface AuthReadinessTargetResolution {\n readonly diagnostics: readonly DoctorDiagnostic[];\n readonly enabledTargets: readonly AppDeployTargetId[];\n readonly targets: AppDeployTargets | null;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { AuthReadinessTargetResolution } from './authReadinessTargetResolution.js';
2
+ export declare function resolveAuthReadinessTargets(deploy: unknown, manifestPath: string): AuthReadinessTargetResolution;
3
+ //# sourceMappingURL=authReadinessTargets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessTargets.d.ts","sourceRoot":"","sources":["../src/authReadinessTargets.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAExF,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,MAAM,GACnB,6BAA6B,CAyB/B"}
@@ -0,0 +1,26 @@
1
+ import { APP_DEPLOY_TARGET_IDS, isAppDeployManifest } from '@ankhorage/contracts/deploy';
2
+ import { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';
3
+ import { resolveAuthReadinessTargetFallback } from './authReadinessTargetFallback.js';
4
+ export function resolveAuthReadinessTargets(deploy, manifestPath) {
5
+ if (!isAppDeployManifest(deploy)) {
6
+ return resolveAuthReadinessTargetFallback(deploy, manifestPath);
7
+ }
8
+ const enabledTargets = APP_DEPLOY_TARGET_IDS.filter((target) => deploy.targets[target]?.enabled === true);
9
+ if (enabledTargets.length > 0) {
10
+ return { diagnostics: [], enabledTargets, targets: deploy.targets };
11
+ }
12
+ return {
13
+ diagnostics: [
14
+ createAuthReadinessDiagnostic({
15
+ code: 'field-missing',
16
+ message: 'manifest.deploy.targets must enable at least one application target.',
17
+ path: manifestPath,
18
+ ruleId: 'manifest.deploy.targets.enabled',
19
+ severity: 'error',
20
+ }),
21
+ ],
22
+ enabledTargets,
23
+ targets: deploy.targets,
24
+ };
25
+ }
26
+ //# sourceMappingURL=authReadinessTargets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessTargets.js","sourceRoot":"","sources":["../src/authReadinessTargets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEzF,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAC;AAGtF,MAAM,UAAU,2BAA2B,CACzC,MAAe,EACf,YAAoB;IAEpB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,OAAO,kCAAkC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,cAAc,GAAG,qBAAqB,CAAC,MAAM,CACjD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CACrD,CAAC;IACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACtE,CAAC;IAED,OAAO;QACL,WAAW,EAAE;YACX,6BAA6B,CAAC;gBAC5B,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,sEAAsE;gBAC/E,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,iCAAiC;gBACzC,QAAQ,EAAE,OAAO;aAClB,CAAC;SACH;QACD,cAAc;QACd,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;AACJ,CAAC","sourcesContent":["import { APP_DEPLOY_TARGET_IDS, isAppDeployManifest } from '@ankhorage/contracts/deploy';\n\nimport { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';\nimport { resolveAuthReadinessTargetFallback } from './authReadinessTargetFallback.js';\nimport type { AuthReadinessTargetResolution } from './authReadinessTargetResolution.js';\n\nexport function resolveAuthReadinessTargets(\n deploy: unknown,\n manifestPath: string,\n): AuthReadinessTargetResolution {\n if (!isAppDeployManifest(deploy)) {\n return resolveAuthReadinessTargetFallback(deploy, manifestPath);\n }\n\n const enabledTargets = APP_DEPLOY_TARGET_IDS.filter(\n (target) => deploy.targets[target]?.enabled === true,\n );\n if (enabledTargets.length > 0) {\n return { diagnostics: [], enabledTargets, targets: deploy.targets };\n }\n\n return {\n diagnostics: [\n createAuthReadinessDiagnostic({\n code: 'field-missing',\n message: 'manifest.deploy.targets must enable at least one application target.',\n path: manifestPath,\n ruleId: 'manifest.deploy.targets.enabled',\n severity: 'error',\n }),\n ],\n enabledTargets,\n targets: deploy.targets,\n };\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { AppDeployEnvironmentId, AppDeployTargetId } from '@ankhorage/contracts/deploy';
2
+ import type { DoctorDiagnostic } from './diagnostics.js';
3
+ import type { DoctorReadiness } from './readiness.js';
4
+ export declare function createUnsupportedAuthReadiness(input: {
5
+ readonly environment: AppDeployEnvironmentId;
6
+ readonly provider: string;
7
+ readonly targets: readonly AppDeployTargetId[];
8
+ }): DoctorReadiness[];
9
+ export declare function createUnsupportedAuthDiagnostic(input: {
10
+ readonly message: string;
11
+ readonly path: string;
12
+ }): DoctorDiagnostic;
13
+ //# sourceMappingURL=authReadinessUnsupported.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessUnsupported.d.ts","sourceRoot":"","sources":["../src/authReadinessUnsupported.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAG7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE;IACpD,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAChD,GAAG,eAAe,EAAE,CAUpB;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GAAG,gBAAgB,CAQnB"}
@@ -0,0 +1,22 @@
1
+ import { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';
2
+ export function createUnsupportedAuthReadiness(input) {
3
+ return input.targets.map((target) => ({
4
+ category: 'auth-oauth',
5
+ environment: input.environment,
6
+ message: 'The selected backend/provider/transport combination has no setup capability.',
7
+ provider: input.provider,
8
+ status: 'unsupported',
9
+ target,
10
+ transport: 'brokeredRedirect',
11
+ }));
12
+ }
13
+ export function createUnsupportedAuthDiagnostic(input) {
14
+ return createAuthReadinessDiagnostic({
15
+ code: 'field-invalid',
16
+ message: input.message,
17
+ path: input.path,
18
+ ruleId: 'manifest.auth.oauth.setup.supported',
19
+ severity: 'error',
20
+ });
21
+ }
22
+ //# sourceMappingURL=authReadinessUnsupported.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessUnsupported.js","sourceRoot":"","sources":["../src/authReadinessUnsupported.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAI7E,MAAM,UAAU,8BAA8B,CAAC,KAI9C;IACC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpC,QAAQ,EAAE,YAAY;QACtB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,8EAA8E;QACvF,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,aAAa;QACrB,MAAM;QACN,SAAS,EAAE,kBAAkB;KAC9B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAG/C;IACC,OAAO,6BAA6B,CAAC;QACnC,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,qCAAqC;QAC7C,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { AppDeployEnvironmentId, AppDeployTargetId } from '@ankhorage/contracts/deploy';\n\nimport { createAuthReadinessDiagnostic } from './authReadinessDiagnostic.js';\nimport type { DoctorDiagnostic } from './diagnostics.js';\nimport type { DoctorReadiness } from './readiness.js';\n\nexport function createUnsupportedAuthReadiness(input: {\n readonly environment: AppDeployEnvironmentId;\n readonly provider: string;\n readonly targets: readonly AppDeployTargetId[];\n}): DoctorReadiness[] {\n return input.targets.map((target) => ({\n category: 'auth-oauth',\n environment: input.environment,\n message: 'The selected backend/provider/transport combination has no setup capability.',\n provider: input.provider,\n status: 'unsupported',\n target,\n transport: 'brokeredRedirect',\n }));\n}\n\nexport function createUnsupportedAuthDiagnostic(input: {\n readonly message: string;\n readonly path: string;\n}): DoctorDiagnostic {\n return createAuthReadinessDiagnostic({\n code: 'field-invalid',\n message: input.message,\n path: input.path,\n ruleId: 'manifest.auth.oauth.setup.supported',\n severity: 'error',\n });\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import type { AppDeployTargetId } from '@ankhorage/contracts/deploy';
2
+ import type { DoctorDiagnostic } from './diagnostics.js';
3
+ import type { DoctorReadiness } from './readiness.js';
4
+ export declare function analyzeUnsupportedAuthBackend(input: {
5
+ readonly enabledTargets: readonly AppDeployTargetId[];
6
+ readonly manifestPath: string;
7
+ readonly provider: string;
8
+ }): {
9
+ readonly diagnostics: readonly DoctorDiagnostic[];
10
+ readonly readiness: readonly DoctorReadiness[];
11
+ };
12
+ //# sourceMappingURL=authReadinessUnsupportedBackend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessUnsupportedBackend.d.ts","sourceRoot":"","sources":["../src/authReadinessUnsupportedBackend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAOrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,QAAQ,CAAC,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,GAAG;IACF,QAAQ,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;CAChD,CAgBA"}
@@ -0,0 +1,18 @@
1
+ import { APP_DEPLOY_ENVIRONMENT_IDS } from '@ankhorage/contracts/deploy';
2
+ import { createUnsupportedAuthDiagnostic, createUnsupportedAuthReadiness, } from './authReadinessUnsupported.js';
3
+ export function analyzeUnsupportedAuthBackend(input) {
4
+ return {
5
+ diagnostics: [
6
+ createUnsupportedAuthDiagnostic({
7
+ message: 'Configured OAuth backend has no Doctor setup resolver.',
8
+ path: input.manifestPath,
9
+ }),
10
+ ],
11
+ readiness: APP_DEPLOY_ENVIRONMENT_IDS.flatMap((environment) => createUnsupportedAuthReadiness({
12
+ environment,
13
+ provider: input.provider,
14
+ targets: input.enabledTargets,
15
+ })),
16
+ };
17
+ }
18
+ //# sourceMappingURL=authReadinessUnsupportedBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authReadinessUnsupportedBackend.js","sourceRoot":"","sources":["../src/authReadinessUnsupportedBackend.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEzE,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,+BAA+B,CAAC;AAIvC,MAAM,UAAU,6BAA6B,CAAC,KAI7C;IAIC,OAAO;QACL,WAAW,EAAE;YACX,+BAA+B,CAAC;gBAC9B,OAAO,EAAE,wDAAwD;gBACjE,IAAI,EAAE,KAAK,CAAC,YAAY;aACzB,CAAC;SACH;QACD,SAAS,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAC5D,8BAA8B,CAAC;YAC7B,WAAW;YACX,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,KAAK,CAAC,cAAc;SAC9B,CAAC,CACH;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { AppDeployTargetId } from '@ankhorage/contracts/deploy';\nimport { APP_DEPLOY_ENVIRONMENT_IDS } from '@ankhorage/contracts/deploy';\n\nimport {\n createUnsupportedAuthDiagnostic,\n createUnsupportedAuthReadiness,\n} from './authReadinessUnsupported.js';\nimport type { DoctorDiagnostic } from './diagnostics.js';\nimport type { DoctorReadiness } from './readiness.js';\n\nexport function analyzeUnsupportedAuthBackend(input: {\n readonly enabledTargets: readonly AppDeployTargetId[];\n readonly manifestPath: string;\n readonly provider: string;\n}): {\n readonly diagnostics: readonly DoctorDiagnostic[];\n readonly readiness: readonly DoctorReadiness[];\n} {\n return {\n diagnostics: [\n createUnsupportedAuthDiagnostic({\n message: 'Configured OAuth backend has no Doctor setup resolver.',\n path: input.manifestPath,\n }),\n ],\n readiness: APP_DEPLOY_ENVIRONMENT_IDS.flatMap((environment) =>\n createUnsupportedAuthReadiness({\n environment,\n provider: input.provider,\n targets: input.enabledTargets,\n }),\n ),\n };\n}\n"]}
@@ -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;AAQxF,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"}
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
  }
@@ -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"]}