ts-openapi-codegen 2.1.0-beta.8 → 2.1.0-beta.9

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 (133) hide show
  1. package/README.md +4 -0
  2. package/README.rus.md +4 -0
  3. package/dist/cli/analyzeDiff/__tests__/analyzeDiff.cli.test.js +31 -24
  4. package/dist/cli/analyzeDiff/__tests__/analyzeDiffLomMiracles.test.d.ts +2 -0
  5. package/dist/cli/analyzeDiff/__tests__/analyzeDiffLomMiracles.test.d.ts.map +1 -0
  6. package/dist/cli/analyzeDiff/__tests__/analyzeDiffLomMiracles.test.js +47 -0
  7. package/dist/cli/analyzeDiff/__tests__/analyzeDiffRenameAndInvalidRegex.test.js +8 -7
  8. package/dist/cli/analyzeDiff/__tests__/analyzeDiffTypeCoercion.test.js +8 -7
  9. package/dist/cli/analyzeDiff/analyzeDiff.d.ts +14 -2
  10. package/dist/cli/analyzeDiff/analyzeDiff.d.ts.map +1 -1
  11. package/dist/cli/analyzeDiff/analyzeDiff.js +56 -13
  12. package/dist/cli/analyzeDiff/ciSummary.d.ts +6 -3
  13. package/dist/cli/analyzeDiff/ciSummary.d.ts.map +1 -1
  14. package/dist/cli/analyzeDiff/ciSummary.js +10 -6
  15. package/dist/cli/analyzeDiff/report.d.ts +0 -1
  16. package/dist/cli/analyzeDiff/report.d.ts.map +1 -1
  17. package/dist/cli/analyzeDiff/report.js +1 -3
  18. package/dist/cli/analyzeDiff/writeLegacyReport.d.ts +2 -0
  19. package/dist/cli/analyzeDiff/writeLegacyReport.d.ts.map +1 -1
  20. package/dist/cli/analyzeDiff/writeLegacyReport.js +2 -0
  21. package/dist/cli/analyzeUsage/core/Scanner.d.ts +8 -0
  22. package/dist/cli/analyzeUsage/core/Scanner.d.ts.map +1 -1
  23. package/dist/cli/analyzeUsage/core/Scanner.js +10 -0
  24. package/dist/cli/analyzeUsage/rules/ClientRule.d.ts +8 -0
  25. package/dist/cli/analyzeUsage/rules/ClientRule.d.ts.map +1 -1
  26. package/dist/cli/analyzeUsage/rules/ClientRule.js +10 -0
  27. package/dist/cli/analyzeUsage/rules/ServiceRule.d.ts +8 -0
  28. package/dist/cli/analyzeUsage/rules/ServiceRule.d.ts.map +1 -1
  29. package/dist/cli/analyzeUsage/rules/ServiceRule.js +10 -0
  30. package/dist/common/LoggerMessages.d.ts +5 -0
  31. package/dist/common/LoggerMessages.d.ts.map +1 -1
  32. package/dist/common/LoggerMessages.js +4 -0
  33. package/dist/core/OpenApiClient.d.ts +8 -0
  34. package/dist/core/OpenApiClient.d.ts.map +1 -1
  35. package/dist/core/OpenApiClient.js +16 -2
  36. package/dist/core/WriteClient.d.ts +52 -15
  37. package/dist/core/WriteClient.d.ts.map +1 -1
  38. package/dist/core/WriteClient.js +36 -4
  39. package/dist/core/semanticDiff/__tests__/analyzeOpenApiDiff.test.js +72 -0
  40. package/dist/core/semanticDiff/__tests__/semanticDiffReportSchema.test.js +20 -1
  41. package/dist/core/semanticDiff/analyzeOpenApiDiff.d.ts +58 -6
  42. package/dist/core/semanticDiff/analyzeOpenApiDiff.d.ts.map +1 -1
  43. package/dist/core/semanticDiff/analyzeOpenApiDiff.js +47 -19
  44. package/dist/core/semanticDiff/semanticDiffReportSchema.d.ts +11 -1
  45. package/dist/core/semanticDiff/semanticDiffReportSchema.d.ts.map +1 -1
  46. package/dist/core/semanticDiff/semanticDiffReportSchema.js +140 -50
  47. package/dist/core/types/DiffReport.model.d.ts +101 -0
  48. package/dist/core/types/DiffReport.model.d.ts.map +1 -0
  49. package/dist/core/types/DiffReport.model.js +5 -0
  50. package/dist/core/types/shared/Model.model.d.ts +36 -0
  51. package/dist/core/types/shared/Model.model.d.ts.map +1 -1
  52. package/dist/core/utils/__tests__/applyDiffReportToClient.test.js +182 -0
  53. package/dist/core/utils/__tests__/buildMiraclesFromSemanticChanges.test.d.ts +2 -0
  54. package/dist/core/utils/__tests__/buildMiraclesFromSemanticChanges.test.d.ts.map +1 -0
  55. package/dist/core/utils/__tests__/buildMiraclesFromSemanticChanges.test.js +77 -0
  56. package/dist/core/utils/__tests__/expandOpenApiRefsForSemanticDiff.test.d.ts +2 -0
  57. package/dist/core/utils/__tests__/expandOpenApiRefsForSemanticDiff.test.d.ts.map +1 -0
  58. package/dist/core/utils/__tests__/expandOpenApiRefsForSemanticDiff.test.js +159 -0
  59. package/dist/core/utils/__tests__/loadDiffReport.test.js +131 -0
  60. package/dist/core/utils/__tests__/modelHelpers.test.js +27 -9
  61. package/dist/core/utils/__tests__/prepareDtoModels.test.js +74 -2
  62. package/dist/core/utils/__tests__/resolveClassesModeTypes.test.d.ts +2 -0
  63. package/dist/core/utils/__tests__/resolveClassesModeTypes.test.d.ts.map +1 -0
  64. package/dist/core/utils/__tests__/resolveClassesModeTypes.test.js +111 -0
  65. package/dist/core/utils/__tests__/semanticChangesToDiffEntries.test.d.ts +2 -0
  66. package/dist/core/utils/__tests__/semanticChangesToDiffEntries.test.d.ts.map +1 -0
  67. package/dist/core/utils/__tests__/semanticChangesToDiffEntries.test.js +68 -0
  68. package/dist/core/utils/__tests__/serviceHelpers.test.js +10 -11
  69. package/dist/core/utils/__tests__/templateRendering.test.js +71 -0
  70. package/dist/core/utils/adapters/__tests__/semanticToStructural.test.d.ts +2 -0
  71. package/dist/core/utils/adapters/__tests__/semanticToStructural.test.d.ts.map +1 -0
  72. package/dist/core/utils/adapters/__tests__/semanticToStructural.test.js +63 -0
  73. package/dist/core/utils/adapters/extractMiraclesFromSemantic.d.ts +10 -0
  74. package/dist/core/utils/adapters/extractMiraclesFromSemantic.d.ts.map +1 -0
  75. package/dist/core/utils/adapters/extractMiraclesFromSemantic.js +13 -0
  76. package/dist/core/utils/adapters/index.d.ts +4 -0
  77. package/dist/core/utils/adapters/index.d.ts.map +1 -0
  78. package/dist/core/utils/adapters/index.js +8 -0
  79. package/dist/core/utils/adapters/semanticToStructural.d.ts +12 -0
  80. package/dist/core/utils/adapters/semanticToStructural.d.ts.map +1 -0
  81. package/dist/core/utils/adapters/semanticToStructural.js +36 -0
  82. package/dist/core/utils/applyDiffReportToClient.d.ts +13 -1
  83. package/dist/core/utils/applyDiffReportToClient.d.ts.map +1 -1
  84. package/dist/core/utils/applyDiffReportToClient.js +187 -107
  85. package/dist/core/utils/buildMiraclesFromSemanticChanges.d.ts +25 -0
  86. package/dist/core/utils/buildMiraclesFromSemanticChanges.d.ts.map +1 -0
  87. package/dist/core/utils/buildMiraclesFromSemanticChanges.js +146 -0
  88. package/dist/core/utils/expandOpenApiRefsForSemanticDiff.d.ts +23 -0
  89. package/dist/core/utils/expandOpenApiRefsForSemanticDiff.d.ts.map +1 -0
  90. package/dist/core/utils/expandOpenApiRefsForSemanticDiff.js +163 -0
  91. package/dist/core/utils/getOpenApiSpec.d.ts +18 -0
  92. package/dist/core/utils/getOpenApiSpec.d.ts.map +1 -1
  93. package/dist/core/utils/getOpenApiSpec.js +35 -0
  94. package/dist/core/utils/loadDiffReport.d.ts +11 -30
  95. package/dist/core/utils/loadDiffReport.d.ts.map +1 -1
  96. package/dist/core/utils/loadDiffReport.js +69 -3
  97. package/dist/core/utils/loadSemanticOpenApiSpec.d.ts +15 -0
  98. package/dist/core/utils/loadSemanticOpenApiSpec.d.ts.map +1 -0
  99. package/dist/core/utils/loadSemanticOpenApiSpec.js +61 -0
  100. package/dist/core/utils/modelHelpers.d.ts +13 -5
  101. package/dist/core/utils/modelHelpers.d.ts.map +1 -1
  102. package/dist/core/utils/modelHelpers.js +28 -23
  103. package/dist/core/utils/prepareDtoModels.d.ts +5 -0
  104. package/dist/core/utils/prepareDtoModels.d.ts.map +1 -1
  105. package/dist/core/utils/prepareDtoModels.js +55 -12
  106. package/dist/core/utils/resolveClassesModeTypes.d.ts +8 -0
  107. package/dist/core/utils/resolveClassesModeTypes.d.ts.map +1 -0
  108. package/dist/core/utils/resolveClassesModeTypes.js +77 -0
  109. package/dist/core/utils/semanticChangesToDiffEntries.d.ts +37 -0
  110. package/dist/core/utils/semanticChangesToDiffEntries.d.ts.map +1 -0
  111. package/dist/core/utils/semanticChangesToDiffEntries.js +99 -0
  112. package/dist/core/utils/semanticPointerToJsonPath.d.ts +7 -0
  113. package/dist/core/utils/semanticPointerToJsonPath.d.ts.map +1 -0
  114. package/dist/core/utils/semanticPointerToJsonPath.js +67 -0
  115. package/dist/core/utils/serviceHelpers.d.ts +6 -7
  116. package/dist/core/utils/serviceHelpers.d.ts.map +1 -1
  117. package/dist/core/utils/serviceHelpers.js +8 -25
  118. package/dist/core/utils/writeClientServices.d.ts +14 -14
  119. package/dist/core/utils/writeClientServices.d.ts.map +1 -1
  120. package/dist/core/utils/writeClientServices.js +4 -8
  121. package/dist/templatesCompiled/client/exportModels.d.ts +17 -11
  122. package/dist/templatesCompiled/client/exportModels.d.ts.map +1 -1
  123. package/dist/templatesCompiled/client/exportModels.js +96 -49
  124. package/dist/templatesCompiled/client/exportService.d.ts +13 -10
  125. package/dist/templatesCompiled/client/exportService.d.ts.map +1 -1
  126. package/dist/templatesCompiled/client/exportService.js +95 -67
  127. package/package.json +1 -3
  128. package/dist/cli/analyzeDiff/buildLegacyReport.d.ts +0 -17
  129. package/dist/cli/analyzeDiff/buildLegacyReport.d.ts.map +0 -1
  130. package/dist/cli/analyzeDiff/buildLegacyReport.js +0 -54
  131. package/dist/cli/analyzeDiff/diffEngine.d.ts +0 -54
  132. package/dist/cli/analyzeDiff/diffEngine.d.ts.map +0 -1
  133. package/dist/cli/analyzeDiff/diffEngine.js +0 -209
@@ -0,0 +1,101 @@
1
+ import type { GovernanceReport } from '../governance/evaluateGovernanceRules';
2
+ import type { SemanticDiffChange, SemanticDiffRecommendation, SemanticDiffSummary } from '../semanticDiff/analyzeOpenApiDiff';
3
+ import type { DiffInfo } from './shared/DiffInfo.model';
4
+ import type { MiracleEntry } from './shared/Miracle.model';
5
+ /** Версия схемы унифицированного diff-отчёта. */
6
+ export declare const UNIFIED_DIFF_REPORT_SCHEMA_VERSION = "2.0.0";
7
+ /** Запись структурного diff с обязательным действием изменения. */
8
+ export interface DiffReportEntry extends DiffInfo {
9
+ action: DiffInfo['action'];
10
+ }
11
+ /**
12
+ * Метаданные diff-отчёта.
13
+ * @property [base] источник базовой спецификации
14
+ * @property [target] источник целевой спецификации
15
+ * @property [baseHash] хеш базовой спецификации
16
+ * @property [targetHash] хеш целевой спецификации
17
+ */
18
+ export interface DiffReportMetadata {
19
+ base?: string;
20
+ target?: string;
21
+ baseHash?: string;
22
+ targetHash?: string;
23
+ }
24
+ /**
25
+ * Статистика изменений в diff-отчёте.
26
+ * @property [totalChanges] общее количество изменений
27
+ * @property [added] количество добавлений
28
+ * @property [removed] количество удалений
29
+ * @property [changed] количество изменений
30
+ * @property [ignored] количество проигнорированных изменений
31
+ * @property [stabilityScore] оценка стабильности API в процентах
32
+ */
33
+ export interface DiffReportStats {
34
+ totalChanges?: number;
35
+ added?: number;
36
+ removed?: number;
37
+ changed?: number;
38
+ ignored?: number;
39
+ stabilityScore?: number;
40
+ }
41
+ /**
42
+ * Структурная часть diff-отчёта для генерации клиента.
43
+ * @property diff группы изменений по уровню серьёзности
44
+ * @property miracles кандидаты на переименование и приведение типов
45
+ * @property stats агрегированная статистика изменений
46
+ */
47
+ export interface StructuralDiffPart {
48
+ diff: {
49
+ breaking: DiffReportEntry[];
50
+ warnings: DiffReportEntry[];
51
+ info: DiffReportEntry[];
52
+ all: DiffReportEntry[];
53
+ };
54
+ miracles: MiracleEntry[];
55
+ stats: DiffReportStats;
56
+ }
57
+ /**
58
+ * Legacy diff-отчёт для обратной совместимости.
59
+ * @property [version] версия схемы отчёта
60
+ * @property [timestamp] время формирования отчёта
61
+ * @property [metadata] метаданные сравниваемых спецификаций
62
+ * @property [stats] статистика изменений
63
+ * @property [diff] группы изменений по уровню серьёзности
64
+ * @property [miracles] кандидаты на переименование и приведение типов
65
+ */
66
+ export interface DiffReport {
67
+ version?: string;
68
+ timestamp?: string;
69
+ metadata?: DiffReportMetadata;
70
+ stats?: DiffReportStats;
71
+ diff?: {
72
+ breaking?: DiffReportEntry[];
73
+ warnings?: DiffReportEntry[];
74
+ info?: DiffReportEntry[];
75
+ all?: DiffReportEntry[];
76
+ };
77
+ miracles?: MiracleEntry[];
78
+ }
79
+ /**
80
+ * Унифицированный diff-отчёт с семантической и структурной частями.
81
+ * @property schemaVersion версия схемы отчёта
82
+ * @property timestamp время формирования отчёта
83
+ * @property metadata метаданные сравниваемых спецификаций
84
+ * @property semantic семантический анализ изменений
85
+ * @property structural структурная часть для генерации клиента
86
+ */
87
+ export interface UnifiedDiffReport {
88
+ schemaVersion: typeof UNIFIED_DIFF_REPORT_SCHEMA_VERSION;
89
+ timestamp: string;
90
+ metadata: DiffReportMetadata;
91
+ semantic: {
92
+ changes: SemanticDiffChange[];
93
+ governance: GovernanceReport;
94
+ recommendation: SemanticDiffRecommendation;
95
+ summary: SemanticDiffSummary;
96
+ };
97
+ structural: StructuralDiffPart;
98
+ }
99
+ /** Реэкспорт типов структурного diff и miracles. */
100
+ export type { DiffInfo, MiracleEntry };
101
+ //# sourceMappingURL=DiffReport.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffReport.model.d.ts","sourceRoot":"","sources":["../../../src/core/types/DiffReport.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9H,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,iDAAiD;AACjD,eAAO,MAAM,kCAAkC,UAAU,CAAC;AAE1D,mEAAmE;AACnE,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC7C,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE;QACF,QAAQ,EAAE,eAAe,EAAE,CAAC;QAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;QAC5B,IAAI,EAAE,eAAe,EAAE,CAAC;QACxB,GAAG,EAAE,eAAe,EAAE,CAAC;KAC1B,CAAC;IACF,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,IAAI,CAAC,EAAE;QACH,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7B,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC;QACzB,GAAG,CAAC,EAAE,eAAe,EAAE,CAAC;KAC3B,CAAC;IACF,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAC9B,aAAa,EAAE,OAAO,kCAAkC,CAAC;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,QAAQ,EAAE;QACN,OAAO,EAAE,kBAAkB,EAAE,CAAC;QAC9B,UAAU,EAAE,gBAAgB,CAAC;QAC7B,cAAc,EAAE,0BAA0B,CAAC;QAC3C,OAAO,EAAE,mBAAmB,CAAC;KAChC,CAAC;IACF,UAAU,EAAE,kBAAkB,CAAC;CAClC;AAED,oDAAoD;AACpD,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UNIFIED_DIFF_REPORT_SCHEMA_VERSION = void 0;
4
+ /** Версия схемы унифицированного diff-отчёта. */
5
+ exports.UNIFIED_DIFF_REPORT_SCHEMA_VERSION = '2.0.0';
@@ -2,6 +2,41 @@ import type { DiffInfo } from './DiffInfo.model';
2
2
  import type { Enum } from './Enum.model';
3
3
  import { Import } from './Import.model';
4
4
  import type { Schema } from './Schema.model';
5
+ /**
6
+ * Модель OpenAPI-схемы для генерации TypeScript-типов и DTO.
7
+ * @property name имя модели
8
+ * @property alias алиас для экспорта
9
+ * @property path путь к схеме в спецификации
10
+ * @property export способ экспорта модели
11
+ * @property type строковое представление типа
12
+ * @property base базовый тип
13
+ * @property template шаблон generic-типа
14
+ * @property link связанная модель
15
+ * @property description описание схемы
16
+ * @property [default] значение по умолчанию
17
+ * @property imports импорты модели
18
+ * @property enum значения enum
19
+ * @property enums вложенные enum-модели
20
+ * @property properties свойства модели
21
+ * @property [ghostProperties] свойства, удалённые в новой версии API
22
+ * @property [diff] основное diff-изменение свойства
23
+ * @property [structuralDiff] список структурных diff-изменений
24
+ * @property [isGhost] признак ghost-свойства
25
+ * @property [rawName] имя raw-типа в режиме classes
26
+ * @property [dtoName] имя DTO-типа в режиме classes
27
+ * @property [exportName] имя для экспорта в режиме classes
28
+ * @property [rawType] строковое представление raw-типа
29
+ * @property [dtoType] строковое представление DTO-типа
30
+ * @property [dtoInit] инициализатор DTO
31
+ * @property [dtoToJSON] метод сериализации DTO
32
+ * @property [dtoTarget] целевой тип DTO
33
+ * @property [dtoKind] вид DTO: class или alias
34
+ * @property [dtoGetters] геттеры для переименованных свойств
35
+ * @property [needsCoercion] требуется приведение типа
36
+ * @property [coercionFrom] исходный тип приведения
37
+ * @property [coercionTo] целевой тип приведения
38
+ * @property [hasCoercion] признак наличия приведения типа
39
+ */
5
40
  export interface Model extends Schema {
6
41
  name: string;
7
42
  alias: string;
@@ -23,6 +58,7 @@ export interface Model extends Schema {
23
58
  isGhost?: boolean;
24
59
  rawName?: string;
25
60
  dtoName?: string;
61
+ exportName?: string;
26
62
  rawType?: string;
27
63
  dtoType?: string;
28
64
  dtoInit?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Model.model.d.ts","sourceRoot":"","sources":["../../../../src/core/types/shared/Model.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,KAAM,SAAQ,MAAM;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACjH,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,UAAU,EAAE,KAAK,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,KAAK,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;IACJ,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB"}
1
+ {"version":3,"file":"Model.model.d.ts","sourceRoot":"","sources":["../../../../src/core/types/shared/Model.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,WAAW,KAAM,SAAQ,MAAM;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACjH,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,KAAK,EAAE,KAAK,EAAE,CAAC;IACf,UAAU,EAAE,KAAK,EAAE,CAAC;IACpB,eAAe,CAAC,EAAE,KAAK,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;IACJ,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB"}
@@ -105,4 +105,186 @@ const createObjectModel = (name, properties) => ({
105
105
  node_assert_1.default.strictEqual(property?.coercionTo, 'number');
106
106
  node_assert_1.default.ok(updatedModel.hasCoercion, 'Expected model.hasCoercion to be true');
107
107
  });
108
+ (0, node_test_1.test)('marks needsCoercion for $ref alias schema via Context resolver', () => {
109
+ const userBodyDef = {
110
+ type: 'object',
111
+ properties: {
112
+ age: { type: 'number' },
113
+ },
114
+ };
115
+ const mockContext = {
116
+ get: (ref) => {
117
+ if (ref === '#/components/schemas/User') {
118
+ return userBodyDef;
119
+ }
120
+ return undefined;
121
+ },
122
+ };
123
+ const userModel = createObjectModel('IUser', [createPropertyModel('age', 'number')]);
124
+ const client = {
125
+ version: '1.0.0',
126
+ server: 'http://localhost',
127
+ models: [userModel],
128
+ services: [],
129
+ };
130
+ const openApi = {
131
+ openapi: '3.0.0',
132
+ info: { title: 'Test', version: '1.0.0' },
133
+ paths: {},
134
+ components: {
135
+ schemas: {
136
+ User: { $ref: '#/components/schemas/UserBody' },
137
+ UserBody: userBodyDef,
138
+ },
139
+ },
140
+ };
141
+ const report = {
142
+ diff: {
143
+ all: [
144
+ {
145
+ action: 'changed',
146
+ path: '$.components.schemas.User.properties.age.type',
147
+ severity: 'warning',
148
+ from: 'string',
149
+ to: 'number',
150
+ },
151
+ ],
152
+ },
153
+ miracles: [
154
+ {
155
+ oldPath: '$.components.schemas.User.properties.age',
156
+ newPath: '$.components.schemas.User.properties.age',
157
+ type: 'TYPE_COERCION',
158
+ confidence: 1,
159
+ status: 'auto-generated',
160
+ },
161
+ ],
162
+ };
163
+ const result = (0, applyDiffReportToClient_1.applyDiffReportToClient)({
164
+ client,
165
+ openApi,
166
+ openApiVersion: getOpenApiVersion_1.OpenApiVersion.V3,
167
+ diffReport: report,
168
+ prefix: { interface: 'I', enum: 'E', type: 'T' },
169
+ context: mockContext,
170
+ });
171
+ const updatedModel = result.models[0];
172
+ const property = updatedModel.properties.find(prop => prop.name === 'age');
173
+ node_assert_1.default.ok(property?.needsCoercion, 'Expected needsCoercion to be true for $ref schema');
174
+ node_assert_1.default.strictEqual(property?.coercionFrom, 'string');
175
+ node_assert_1.default.strictEqual(property?.coercionTo, 'number');
176
+ node_assert_1.default.ok(updatedModel.hasCoercion, 'Expected model.hasCoercion to be true');
177
+ });
178
+ (0, node_test_1.test)('marks needsCoercion on property via applyModelDiffs with $ref schema', () => {
179
+ const userBodyDef = {
180
+ type: 'object',
181
+ properties: {
182
+ age: { type: 'number' },
183
+ },
184
+ };
185
+ const mockContext = {
186
+ get: (ref) => {
187
+ if (ref === '#/components/schemas/User') {
188
+ return userBodyDef;
189
+ }
190
+ return undefined;
191
+ },
192
+ };
193
+ const userModel = createObjectModel('IUser', [createPropertyModel('age', 'number')]);
194
+ const client = {
195
+ version: '1.0.0',
196
+ server: 'http://localhost',
197
+ models: [userModel],
198
+ services: [],
199
+ };
200
+ const openApi = {
201
+ openapi: '3.0.0',
202
+ info: { title: 'Test', version: '1.0.0' },
203
+ paths: {},
204
+ components: {
205
+ schemas: {
206
+ User: { $ref: '#/components/schemas/UserBody' },
207
+ UserBody: userBodyDef,
208
+ },
209
+ },
210
+ };
211
+ const report = {
212
+ diff: {
213
+ all: [
214
+ {
215
+ action: 'changed',
216
+ path: '$.components.schemas.User.properties.age.type',
217
+ severity: 'warning',
218
+ from: 'string',
219
+ to: 'number',
220
+ },
221
+ ],
222
+ },
223
+ };
224
+ const result = (0, applyDiffReportToClient_1.applyDiffReportToClient)({
225
+ client,
226
+ openApi,
227
+ openApiVersion: getOpenApiVersion_1.OpenApiVersion.V3,
228
+ diffReport: report,
229
+ prefix: { interface: 'I', enum: 'E', type: 'T' },
230
+ context: mockContext,
231
+ });
232
+ const updatedModel = result.models[0];
233
+ const property = updatedModel.properties.find(prop => prop.name === 'age');
234
+ node_assert_1.default.ok(property?.needsCoercion, 'Expected needsCoercion from applyModelDiffs');
235
+ node_assert_1.default.strictEqual(property?.coercionFrom, 'string');
236
+ node_assert_1.default.strictEqual(property?.coercionTo, 'number');
237
+ node_assert_1.default.ok(updatedModel.hasCoercion, 'Expected model.hasCoercion to be true');
238
+ });
239
+ (0, node_test_1.test)('applies model diffs to all models with the same schema name', () => {
240
+ const sequence1 = createObjectModel('ISequence', [createPropertyModel('pathway_id', 'string')]);
241
+ const sequence2 = createObjectModel('ISequence', [createPropertyModel('pathwayId', 'string')]);
242
+ sequence2.alias = 'ISequence$2';
243
+ const client = {
244
+ version: '1.0.0',
245
+ server: 'http://localhost',
246
+ models: [sequence1, sequence2],
247
+ services: [],
248
+ };
249
+ const openApi = {
250
+ openapi: '3.0.0',
251
+ info: { title: 'Test', version: '1.0.0' },
252
+ paths: {},
253
+ components: {
254
+ schemas: {
255
+ Sequence: {
256
+ type: 'object',
257
+ properties: {
258
+ pathway_id: { type: 'string' },
259
+ pathwayId: { type: 'string' },
260
+ },
261
+ },
262
+ },
263
+ },
264
+ };
265
+ const report = {
266
+ diff: {
267
+ all: [
268
+ {
269
+ action: 'removed',
270
+ path: '$.components.schemas.Sequence.properties.legacyField',
271
+ severity: 'warning',
272
+ },
273
+ ],
274
+ },
275
+ };
276
+ const result = (0, applyDiffReportToClient_1.applyDiffReportToClient)({
277
+ client,
278
+ openApi,
279
+ openApiVersion: getOpenApiVersion_1.OpenApiVersion.V3,
280
+ diffReport: report,
281
+ prefix: { interface: 'I', enum: 'E', type: 'T' },
282
+ });
283
+ const updated1 = result.models.find(model => model.name === 'ISequence' && !model.alias);
284
+ const updated2 = result.models.find(model => model.alias === 'ISequence$2');
285
+ node_assert_1.default.strictEqual(updated1?.ghostProperties?.length, 1);
286
+ node_assert_1.default.strictEqual(updated1?.ghostProperties?.[0].name, 'legacyField');
287
+ node_assert_1.default.strictEqual(updated2?.ghostProperties?.length, 1);
288
+ node_assert_1.default.strictEqual(updated2?.ghostProperties?.[0].name, 'legacyField');
289
+ });
108
290
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=buildMiraclesFromSemanticChanges.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildMiraclesFromSemanticChanges.test.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/__tests__/buildMiraclesFromSemanticChanges.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const node_test_1 = require("node:test");
8
+ const buildMiraclesFromSemanticChanges_1 = require("../buildMiraclesFromSemanticChanges");
9
+ (0, node_test_1.describe)('@unit: buildMiraclesFromSemanticChanges', () => {
10
+ (0, node_test_1.test)('parses schema property pointer', () => {
11
+ const parsed = (0, buildMiraclesFromSemanticChanges_1.parseSchemaPropertyPointer)('#/components/schemas/User/properties/first_name');
12
+ node_assert_1.default.ok(parsed);
13
+ node_assert_1.default.strictEqual(parsed.schemaName, 'User');
14
+ node_assert_1.default.strictEqual(parsed.propertyName, 'first_name');
15
+ node_assert_1.default.strictEqual(parsed.jsonPath, '$.components.schemas.User.properties.first_name');
16
+ });
17
+ (0, node_test_1.test)('creates RENAME miracle between removed and added property', () => {
18
+ const changes = [
19
+ {
20
+ type: 'model.property.removed',
21
+ severity: 'breaking',
22
+ path: '#/components/schemas/User/properties/first_name',
23
+ message: 'removed',
24
+ from: { type: 'string' },
25
+ },
26
+ {
27
+ type: 'model.property.added',
28
+ severity: 'non-breaking',
29
+ path: '#/components/schemas/User/properties/firstName',
30
+ message: 'added',
31
+ to: { type: 'string' },
32
+ },
33
+ ];
34
+ const miracles = (0, buildMiraclesFromSemanticChanges_1.buildMiraclesFromSemanticChanges)(changes);
35
+ node_assert_1.default.strictEqual(miracles.length, 1);
36
+ node_assert_1.default.strictEqual(miracles[0].type, 'RENAME');
37
+ node_assert_1.default.strictEqual(miracles[0].oldPath, '$.components.schemas.User.properties.first_name');
38
+ node_assert_1.default.strictEqual(miracles[0].newPath, '$.components.schemas.User.properties.firstName');
39
+ node_assert_1.default.ok(miracles[0].confidence >= 0.8);
40
+ });
41
+ (0, node_test_1.test)('creates TYPE_COERCION miracle for scalar type changes', () => {
42
+ const changes = [
43
+ {
44
+ type: 'model.property.type.changed',
45
+ severity: 'breaking',
46
+ path: '#/components/schemas/User/properties/age',
47
+ message: 'type changed',
48
+ from: 'string',
49
+ to: 'integer',
50
+ },
51
+ ];
52
+ const miracles = (0, buildMiraclesFromSemanticChanges_1.buildMiraclesFromSemanticChanges)(changes);
53
+ node_assert_1.default.strictEqual(miracles.length, 1);
54
+ node_assert_1.default.strictEqual(miracles[0].type, 'TYPE_COERCION');
55
+ node_assert_1.default.strictEqual(miracles[0].oldPath, '$.components.schemas.User.properties.age');
56
+ });
57
+ (0, node_test_1.test)('returns empty list when rename candidates do not match', () => {
58
+ const changes = [
59
+ {
60
+ type: 'model.property.removed',
61
+ severity: 'breaking',
62
+ path: '#/components/schemas/User/properties/id',
63
+ message: 'removed',
64
+ from: { type: 'string' },
65
+ },
66
+ {
67
+ type: 'model.property.added',
68
+ severity: 'non-breaking',
69
+ path: '#/components/schemas/Account/properties/accountId',
70
+ message: 'added',
71
+ to: { type: 'string' },
72
+ },
73
+ ];
74
+ const miracles = (0, buildMiraclesFromSemanticChanges_1.buildMiraclesFromSemanticChanges)(changes);
75
+ node_assert_1.default.deepStrictEqual(miracles, []);
76
+ });
77
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=expandOpenApiRefsForSemanticDiff.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expandOpenApiRefsForSemanticDiff.test.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/__tests__/expandOpenApiRefsForSemanticDiff.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const node_test_1 = require("node:test");
8
+ const expandOpenApiRefsForSemanticDiff_1 = require("../expandOpenApiRefsForSemanticDiff");
9
+ const sourceFile = '/tmp/openapi/api.yaml';
10
+ function createResolver(entries) {
11
+ return {
12
+ exists: ref => Object.prototype.hasOwnProperty.call(entries, ref),
13
+ get: ref => entries[ref],
14
+ };
15
+ }
16
+ (0, node_test_1.describe)('@unit: expandOpenApiRefsForSemanticDiff', () => {
17
+ (0, node_test_1.test)('expands local refs without mutating the original document', () => {
18
+ const spec = {
19
+ openapi: '3.0.0',
20
+ info: { title: 'Test', version: '1.0.0' },
21
+ paths: {},
22
+ components: {
23
+ schemas: {
24
+ User: {
25
+ type: 'object',
26
+ properties: {
27
+ id: { $ref: '#/components/schemas/UserId' },
28
+ },
29
+ },
30
+ UserId: { type: 'string', format: 'uuid' },
31
+ },
32
+ },
33
+ };
34
+ const expanded = (0, expandOpenApiRefsForSemanticDiff_1.expandOpenApiRefsForSemanticDiff)(spec, { sourceFile });
35
+ node_assert_1.default.deepStrictEqual(expanded.components.schemas.User.properties.id, { type: 'string', format: 'uuid' });
36
+ node_assert_1.default.deepStrictEqual(spec.components.schemas.User.properties.id, { $ref: '#/components/schemas/UserId' });
37
+ });
38
+ (0, node_test_1.test)('expands external file refs through the resolver', () => {
39
+ const spec = {
40
+ openapi: '3.0.0',
41
+ info: { title: 'Test', version: '1.0.0' },
42
+ paths: {},
43
+ components: {
44
+ schemas: {
45
+ User: { $ref: './schemas/User.yaml' },
46
+ },
47
+ },
48
+ };
49
+ const resolver = createResolver({
50
+ '/tmp/openapi/schemas/User.yaml': {
51
+ type: 'object',
52
+ properties: {
53
+ name: { type: 'string' },
54
+ },
55
+ },
56
+ });
57
+ const expanded = (0, expandOpenApiRefsForSemanticDiff_1.expandOpenApiRefsForSemanticDiff)(spec, { refs: resolver, sourceFile });
58
+ node_assert_1.default.deepStrictEqual(expanded.components.schemas.User, {
59
+ type: 'object',
60
+ properties: {
61
+ name: { type: 'string' },
62
+ },
63
+ });
64
+ });
65
+ (0, node_test_1.test)('expands external file fragment refs through the resolver', () => {
66
+ const spec = {
67
+ openapi: '3.0.0',
68
+ info: { title: 'Test', version: '1.0.0' },
69
+ paths: {},
70
+ components: {
71
+ schemas: {
72
+ User: { $ref: './schemas/common.yaml#/components/schemas/User' },
73
+ },
74
+ },
75
+ };
76
+ const resolver = createResolver({
77
+ '/tmp/openapi/schemas/common.yaml#/components/schemas/User': {
78
+ type: 'object',
79
+ required: ['id'],
80
+ properties: {
81
+ id: { type: 'string' },
82
+ },
83
+ },
84
+ });
85
+ const expanded = (0, expandOpenApiRefsForSemanticDiff_1.expandOpenApiRefsForSemanticDiff)(spec, { refs: resolver, sourceFile });
86
+ node_assert_1.default.deepStrictEqual(expanded.components.schemas.User, {
87
+ type: 'object',
88
+ required: ['id'],
89
+ properties: {
90
+ id: { type: 'string' },
91
+ },
92
+ });
93
+ });
94
+ (0, node_test_1.test)('expands path item refs', () => {
95
+ const spec = {
96
+ openapi: '3.0.0',
97
+ info: { title: 'Test', version: '1.0.0' },
98
+ paths: {
99
+ '/users': { $ref: '#/components/pathItems/Users' },
100
+ },
101
+ components: {
102
+ pathItems: {
103
+ Users: {
104
+ get: {
105
+ operationId: 'listUsers',
106
+ responses: {
107
+ '200': { description: 'ok' },
108
+ },
109
+ },
110
+ },
111
+ },
112
+ },
113
+ };
114
+ const expanded = (0, expandOpenApiRefsForSemanticDiff_1.expandOpenApiRefsForSemanticDiff)(spec, { sourceFile });
115
+ node_assert_1.default.deepStrictEqual(expanded.paths['/users'], {
116
+ get: {
117
+ operationId: 'listUsers',
118
+ responses: {
119
+ '200': { description: 'ok' },
120
+ },
121
+ },
122
+ });
123
+ });
124
+ (0, node_test_1.test)('keeps unresolved refs stable', () => {
125
+ const spec = {
126
+ openapi: '3.0.0',
127
+ info: { title: 'Test', version: '1.0.0' },
128
+ paths: {},
129
+ components: {
130
+ schemas: {
131
+ Missing: { $ref: './missing.yaml#/Missing' },
132
+ },
133
+ },
134
+ };
135
+ const expanded = (0, expandOpenApiRefsForSemanticDiff_1.expandOpenApiRefsForSemanticDiff)(spec, { sourceFile });
136
+ node_assert_1.default.deepStrictEqual(expanded.components.schemas.Missing, { $ref: './missing.yaml#/Missing' });
137
+ });
138
+ (0, node_test_1.test)('keeps circular refs stringify-safe', () => {
139
+ const spec = {
140
+ openapi: '3.0.0',
141
+ info: { title: 'Test', version: '1.0.0' },
142
+ paths: {},
143
+ components: {
144
+ schemas: {
145
+ Node: {
146
+ type: 'object',
147
+ properties: {
148
+ child: { $ref: '#/components/schemas/Node' },
149
+ },
150
+ },
151
+ },
152
+ },
153
+ };
154
+ const expanded = (0, expandOpenApiRefsForSemanticDiff_1.expandOpenApiRefsForSemanticDiff)(spec, { sourceFile });
155
+ const child = expanded.components.schemas.Node.properties.child;
156
+ node_assert_1.default.deepStrictEqual(child.properties.child, { $ref: '#/components/schemas/Node' });
157
+ node_assert_1.default.doesNotThrow(() => JSON.stringify(expanded));
158
+ });
159
+ });