@openpkg-ts/spec 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +52 -4
- package/dist/index.js +418 -8
- package/package.json +1 -1
- package/schemas/v0.2.0/openpkg.schema.json +10 -1
package/dist/index.d.ts
CHANGED
|
@@ -123,6 +123,21 @@ type OpenPkg = {
|
|
|
123
123
|
extensions?: SpecExtension;
|
|
124
124
|
};
|
|
125
125
|
declare function dereference(spec: OpenPkg): OpenPkg;
|
|
126
|
+
type BreakingSeverity = "high" | "medium" | "low";
|
|
127
|
+
interface CategorizedBreaking {
|
|
128
|
+
id: string;
|
|
129
|
+
name: string;
|
|
130
|
+
kind: SpecExportKind;
|
|
131
|
+
severity: BreakingSeverity;
|
|
132
|
+
reason: string;
|
|
133
|
+
}
|
|
134
|
+
/** Minimal member change info for categorization (avoids circular dep with SDK) */
|
|
135
|
+
interface MemberChangeInfo {
|
|
136
|
+
className: string;
|
|
137
|
+
memberName: string;
|
|
138
|
+
memberKind: "method" | "property" | "accessor" | "constructor";
|
|
139
|
+
changeType: "added" | "removed" | "signature-changed";
|
|
140
|
+
}
|
|
126
141
|
type SpecDiff = {
|
|
127
142
|
breaking: string[];
|
|
128
143
|
nonBreaking: string[];
|
|
@@ -137,18 +152,51 @@ type SpecDiff = {
|
|
|
137
152
|
driftResolved: number;
|
|
138
153
|
};
|
|
139
154
|
declare function diffSpec(oldSpec: OpenPkg, newSpec: OpenPkg): SpecDiff;
|
|
155
|
+
/**
|
|
156
|
+
* Categorize breaking changes by severity
|
|
157
|
+
*
|
|
158
|
+
* @param breaking - Array of breaking change IDs
|
|
159
|
+
* @param oldSpec - Previous spec version
|
|
160
|
+
* @param newSpec - Current spec version
|
|
161
|
+
* @param memberChanges - Optional member-level changes for classes
|
|
162
|
+
* @returns Categorized breaking changes sorted by severity (high first)
|
|
163
|
+
*/
|
|
164
|
+
declare function categorizeBreakingChanges(breaking: string[], oldSpec: OpenPkg, newSpec: OpenPkg, memberChanges?: MemberChangeInfo[]): CategorizedBreaking[];
|
|
140
165
|
declare function normalize(spec: OpenPkg): OpenPkg;
|
|
166
|
+
/** Supported schema versions */
|
|
167
|
+
type SchemaVersion = "0.1.0" | "0.2.0" | "latest";
|
|
141
168
|
type SpecError = {
|
|
142
169
|
instancePath: string;
|
|
143
170
|
message: string;
|
|
144
171
|
keyword: string;
|
|
145
172
|
};
|
|
146
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Validate a spec against a specific schema version.
|
|
175
|
+
*
|
|
176
|
+
* @param spec - The spec object to validate
|
|
177
|
+
* @param version - Schema version to validate against (default: 'latest')
|
|
178
|
+
* @returns Validation result
|
|
179
|
+
*/
|
|
180
|
+
declare function validateSpec(spec: unknown, version?: SchemaVersion): {
|
|
147
181
|
ok: true;
|
|
148
182
|
} | {
|
|
149
183
|
ok: false;
|
|
150
184
|
errors: SpecError[];
|
|
151
185
|
};
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
186
|
+
/**
|
|
187
|
+
* Assert that a value is a valid OpenPkg spec.
|
|
188
|
+
* Throws an error with details if validation fails.
|
|
189
|
+
*
|
|
190
|
+
* @param spec - The value to validate
|
|
191
|
+
* @param version - Schema version to validate against (default: 'latest')
|
|
192
|
+
*/
|
|
193
|
+
declare function assertSpec(spec: unknown, version?: SchemaVersion): asserts spec is OpenPkg;
|
|
194
|
+
/**
|
|
195
|
+
* Get validation errors for a spec.
|
|
196
|
+
*
|
|
197
|
+
* @param spec - The spec to validate
|
|
198
|
+
* @param version - Schema version to validate against (default: 'latest')
|
|
199
|
+
* @returns Array of validation errors (empty if valid)
|
|
200
|
+
*/
|
|
201
|
+
declare function getValidationErrors(spec: unknown, version?: SchemaVersion): SpecError[];
|
|
202
|
+
export { validateSpec, normalize, getValidationErrors, diffSpec, dereference, categorizeBreakingChanges, assertSpec, SpecVisibility, SpecTypeParameter, SpecTypeKind, SpecType, SpecTag, SpecSource, SpecSignatureReturn, SpecSignatureParameter, SpecSignature, SpecSchema, SpecMember, SpecExtension, SpecExportKind, SpecExport, SpecExample, SpecDocsMetadata, SpecDocSignal, SpecDocDrift, SpecDiff, SCHEMA_VERSION, SCHEMA_URL, OpenPkgMeta, OpenPkg, MemberChangeInfo, JSON_SCHEMA_DRAFT, CategorizedBreaking, BreakingSeverity };
|
package/dist/index.js
CHANGED
|
@@ -159,7 +159,21 @@ function toMap(items) {
|
|
|
159
159
|
}
|
|
160
160
|
return map;
|
|
161
161
|
}
|
|
162
|
-
var DOC_KEYS = new Set([
|
|
162
|
+
var DOC_KEYS = new Set([
|
|
163
|
+
"description",
|
|
164
|
+
"examples",
|
|
165
|
+
"tags",
|
|
166
|
+
"rawComments",
|
|
167
|
+
"source",
|
|
168
|
+
"docs",
|
|
169
|
+
"displayName",
|
|
170
|
+
"slug",
|
|
171
|
+
"importPath",
|
|
172
|
+
"category",
|
|
173
|
+
"coverageScore",
|
|
174
|
+
"missing",
|
|
175
|
+
"drift"
|
|
176
|
+
]);
|
|
163
177
|
function isDocOnlyChange(a, b) {
|
|
164
178
|
const structuralA = normalizeForComparison(removeDocFields(a));
|
|
165
179
|
const structuralB = normalizeForComparison(removeDocFields(b));
|
|
@@ -204,6 +218,70 @@ function sortKeys(value) {
|
|
|
204
218
|
}
|
|
205
219
|
return result;
|
|
206
220
|
}
|
|
221
|
+
function categorizeBreakingChanges(breaking, oldSpec, newSpec, memberChanges) {
|
|
222
|
+
const oldExportMap = toExportMap(oldSpec.exports);
|
|
223
|
+
const newExportMap = toExportMap(newSpec.exports);
|
|
224
|
+
const categorized = [];
|
|
225
|
+
for (const id of breaking) {
|
|
226
|
+
const oldExport = oldExportMap.get(id);
|
|
227
|
+
const newExport = newExportMap.get(id);
|
|
228
|
+
if (!newExport) {
|
|
229
|
+
const kind = oldExport?.kind ?? "variable";
|
|
230
|
+
categorized.push({
|
|
231
|
+
id,
|
|
232
|
+
name: oldExport?.name ?? id,
|
|
233
|
+
kind,
|
|
234
|
+
severity: kind === "function" || kind === "class" ? "high" : "medium",
|
|
235
|
+
reason: "removed"
|
|
236
|
+
});
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (oldExport?.kind === "class" && memberChanges?.length) {
|
|
240
|
+
const classChanges = memberChanges.filter((mc) => mc.className === id);
|
|
241
|
+
if (classChanges.length > 0) {
|
|
242
|
+
const hasConstructorChange = classChanges.some((mc) => mc.memberKind === "constructor");
|
|
243
|
+
const hasMethodRemoval = classChanges.some((mc) => mc.changeType === "removed" && mc.memberKind === "method");
|
|
244
|
+
categorized.push({
|
|
245
|
+
id,
|
|
246
|
+
name: oldExport.name,
|
|
247
|
+
kind: "class",
|
|
248
|
+
severity: hasConstructorChange || hasMethodRemoval ? "high" : "medium",
|
|
249
|
+
reason: hasConstructorChange ? "constructor changed" : hasMethodRemoval ? "methods removed" : "methods changed"
|
|
250
|
+
});
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (oldExport?.kind === "interface" || oldExport?.kind === "type") {
|
|
255
|
+
categorized.push({
|
|
256
|
+
id,
|
|
257
|
+
name: oldExport.name,
|
|
258
|
+
kind: oldExport.kind,
|
|
259
|
+
severity: "medium",
|
|
260
|
+
reason: "type definition changed"
|
|
261
|
+
});
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (oldExport?.kind === "function") {
|
|
265
|
+
categorized.push({
|
|
266
|
+
id,
|
|
267
|
+
name: oldExport.name,
|
|
268
|
+
kind: "function",
|
|
269
|
+
severity: "high",
|
|
270
|
+
reason: "signature changed"
|
|
271
|
+
});
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
categorized.push({
|
|
275
|
+
id,
|
|
276
|
+
name: oldExport?.name ?? id,
|
|
277
|
+
kind: oldExport?.kind ?? "variable",
|
|
278
|
+
severity: "low",
|
|
279
|
+
reason: "changed"
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const severityOrder = { high: 0, medium: 1, low: 2 };
|
|
283
|
+
return categorized.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
284
|
+
}
|
|
207
285
|
// src/normalize.ts
|
|
208
286
|
var DEFAULT_ECOSYSTEM = "js/ts";
|
|
209
287
|
var arrayFieldsByExport = ["signatures", "members", "examples", "tags"];
|
|
@@ -419,7 +497,16 @@ var openpkg_schema_default = {
|
|
|
419
497
|
kind: {
|
|
420
498
|
type: "string",
|
|
421
499
|
description: "Kind of export",
|
|
422
|
-
enum: [
|
|
500
|
+
enum: [
|
|
501
|
+
"function",
|
|
502
|
+
"class",
|
|
503
|
+
"variable",
|
|
504
|
+
"interface",
|
|
505
|
+
"type",
|
|
506
|
+
"enum",
|
|
507
|
+
"namespace",
|
|
508
|
+
"external"
|
|
509
|
+
]
|
|
423
510
|
},
|
|
424
511
|
description: {
|
|
425
512
|
type: "string",
|
|
@@ -660,8 +747,315 @@ var openpkg_schema_default = {
|
|
|
660
747
|
}
|
|
661
748
|
}
|
|
662
749
|
};
|
|
750
|
+
// schemas/v0.1.0/openpkg.schema.json
|
|
751
|
+
var openpkg_schema_default2 = {
|
|
752
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
753
|
+
$id: "https://unpkg.com/@openpkg-ts/spec/schemas/v0.1.0/openpkg.schema.json",
|
|
754
|
+
title: "OpenPkg Specification",
|
|
755
|
+
description: "Schema for OpenPkg specification files",
|
|
756
|
+
type: "object",
|
|
757
|
+
required: ["openpkg", "meta", "exports"],
|
|
758
|
+
properties: {
|
|
759
|
+
$schema: {
|
|
760
|
+
type: "string",
|
|
761
|
+
description: "Reference to the OpenPkg schema version",
|
|
762
|
+
pattern: "^(https://raw\\.githubusercontent\\.com/ryanwaits/openpkg/main/schemas/v[0-9]+\\.[0-9]+\\.[0-9]+/openpkg\\.schema\\.json|https://unpkg\\.com/@openpkg-ts/spec/schemas/v[0-9]+\\.[0-9]+\\.[0-9]+/openpkg\\.schema\\.json)$"
|
|
763
|
+
},
|
|
764
|
+
openpkg: {
|
|
765
|
+
type: "string",
|
|
766
|
+
description: "OpenPkg specification version",
|
|
767
|
+
pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
768
|
+
const: "0.1.0"
|
|
769
|
+
},
|
|
770
|
+
meta: {
|
|
771
|
+
type: "object",
|
|
772
|
+
description: "Package metadata",
|
|
773
|
+
required: ["name"],
|
|
774
|
+
properties: {
|
|
775
|
+
name: {
|
|
776
|
+
type: "string",
|
|
777
|
+
description: "Package name"
|
|
778
|
+
},
|
|
779
|
+
version: {
|
|
780
|
+
type: "string",
|
|
781
|
+
description: "Package version"
|
|
782
|
+
},
|
|
783
|
+
description: {
|
|
784
|
+
type: "string",
|
|
785
|
+
description: "Package description"
|
|
786
|
+
},
|
|
787
|
+
license: {
|
|
788
|
+
type: "string",
|
|
789
|
+
description: "Package license"
|
|
790
|
+
},
|
|
791
|
+
repository: {
|
|
792
|
+
type: "string",
|
|
793
|
+
description: "Repository URL"
|
|
794
|
+
},
|
|
795
|
+
ecosystem: {
|
|
796
|
+
type: "string",
|
|
797
|
+
description: "Package ecosystem"
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
exports: {
|
|
802
|
+
type: "array",
|
|
803
|
+
description: "List of exported items",
|
|
804
|
+
items: {
|
|
805
|
+
$ref: "#/$defs/export"
|
|
806
|
+
}
|
|
807
|
+
},
|
|
808
|
+
types: {
|
|
809
|
+
type: "array",
|
|
810
|
+
description: "List of type definitions",
|
|
811
|
+
items: {
|
|
812
|
+
$ref: "#/$defs/typeDef"
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
},
|
|
816
|
+
$defs: {
|
|
817
|
+
export: {
|
|
818
|
+
type: "object",
|
|
819
|
+
required: ["id", "name", "kind"],
|
|
820
|
+
properties: {
|
|
821
|
+
id: {
|
|
822
|
+
type: "string",
|
|
823
|
+
description: "Unique identifier for the export"
|
|
824
|
+
},
|
|
825
|
+
name: {
|
|
826
|
+
type: "string",
|
|
827
|
+
description: "Export name"
|
|
828
|
+
},
|
|
829
|
+
slug: {
|
|
830
|
+
type: "string",
|
|
831
|
+
description: "Stable slug for linking"
|
|
832
|
+
},
|
|
833
|
+
displayName: {
|
|
834
|
+
type: "string",
|
|
835
|
+
description: "UI-friendly label"
|
|
836
|
+
},
|
|
837
|
+
category: {
|
|
838
|
+
type: "string",
|
|
839
|
+
description: "Grouping hint for navigation"
|
|
840
|
+
},
|
|
841
|
+
importPath: {
|
|
842
|
+
type: "string",
|
|
843
|
+
description: "Recommended import path"
|
|
844
|
+
},
|
|
845
|
+
kind: {
|
|
846
|
+
type: "string",
|
|
847
|
+
description: "Kind of export",
|
|
848
|
+
enum: ["function", "class", "variable", "interface", "type", "enum"]
|
|
849
|
+
},
|
|
850
|
+
description: {
|
|
851
|
+
type: "string",
|
|
852
|
+
description: "JSDoc/TSDoc description"
|
|
853
|
+
},
|
|
854
|
+
examples: {
|
|
855
|
+
type: "array",
|
|
856
|
+
description: "Usage examples from documentation",
|
|
857
|
+
items: {
|
|
858
|
+
type: "string"
|
|
859
|
+
}
|
|
860
|
+
},
|
|
861
|
+
signatures: {
|
|
862
|
+
type: "array",
|
|
863
|
+
description: "Function/method signatures",
|
|
864
|
+
items: {
|
|
865
|
+
$ref: "#/$defs/signature"
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
type: {
|
|
869
|
+
description: "Type reference or inline schema for variables",
|
|
870
|
+
oneOf: [{ type: "string" }, { $ref: "#/$defs/schema" }]
|
|
871
|
+
},
|
|
872
|
+
members: {
|
|
873
|
+
type: "array",
|
|
874
|
+
description: "Class/interface/enum members",
|
|
875
|
+
items: { type: "object" }
|
|
876
|
+
},
|
|
877
|
+
tags: {
|
|
878
|
+
type: "array",
|
|
879
|
+
description: "JSDoc/TSDoc tags",
|
|
880
|
+
items: {
|
|
881
|
+
type: "object",
|
|
882
|
+
required: ["name", "text"],
|
|
883
|
+
properties: {
|
|
884
|
+
name: { type: "string" },
|
|
885
|
+
text: { type: "string" }
|
|
886
|
+
},
|
|
887
|
+
additionalProperties: false
|
|
888
|
+
}
|
|
889
|
+
},
|
|
890
|
+
source: {
|
|
891
|
+
$ref: "#/$defs/sourceLocation"
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
},
|
|
895
|
+
typeDef: {
|
|
896
|
+
type: "object",
|
|
897
|
+
required: ["id", "name", "kind"],
|
|
898
|
+
properties: {
|
|
899
|
+
id: {
|
|
900
|
+
type: "string",
|
|
901
|
+
description: "Unique identifier for the type"
|
|
902
|
+
},
|
|
903
|
+
name: {
|
|
904
|
+
type: "string",
|
|
905
|
+
description: "Type name"
|
|
906
|
+
},
|
|
907
|
+
slug: {
|
|
908
|
+
type: "string",
|
|
909
|
+
description: "Stable slug for linking"
|
|
910
|
+
},
|
|
911
|
+
displayName: {
|
|
912
|
+
type: "string",
|
|
913
|
+
description: "UI-friendly label"
|
|
914
|
+
},
|
|
915
|
+
category: {
|
|
916
|
+
type: "string",
|
|
917
|
+
description: "Grouping hint for navigation"
|
|
918
|
+
},
|
|
919
|
+
importPath: {
|
|
920
|
+
type: "string",
|
|
921
|
+
description: "Recommended import path"
|
|
922
|
+
},
|
|
923
|
+
kind: {
|
|
924
|
+
type: "string",
|
|
925
|
+
description: "Kind of type definition",
|
|
926
|
+
enum: ["interface", "type", "enum", "class"]
|
|
927
|
+
},
|
|
928
|
+
description: {
|
|
929
|
+
type: "string",
|
|
930
|
+
description: "JSDoc/TSDoc description"
|
|
931
|
+
},
|
|
932
|
+
schema: {
|
|
933
|
+
$ref: "#/$defs/schema"
|
|
934
|
+
},
|
|
935
|
+
type: {
|
|
936
|
+
type: "string",
|
|
937
|
+
description: "Type expression for type aliases"
|
|
938
|
+
},
|
|
939
|
+
members: {
|
|
940
|
+
type: "array",
|
|
941
|
+
description: "Members for classes/interfaces/enums",
|
|
942
|
+
items: { type: "object" }
|
|
943
|
+
},
|
|
944
|
+
tags: {
|
|
945
|
+
type: "array",
|
|
946
|
+
description: "JSDoc/TSDoc tags",
|
|
947
|
+
items: {
|
|
948
|
+
type: "object",
|
|
949
|
+
required: ["name", "text"],
|
|
950
|
+
properties: {
|
|
951
|
+
name: { type: "string" },
|
|
952
|
+
text: { type: "string" }
|
|
953
|
+
},
|
|
954
|
+
additionalProperties: false
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
source: {
|
|
958
|
+
$ref: "#/$defs/sourceLocation"
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
},
|
|
962
|
+
signature: {
|
|
963
|
+
type: "object",
|
|
964
|
+
properties: {
|
|
965
|
+
parameters: {
|
|
966
|
+
type: "array",
|
|
967
|
+
items: {
|
|
968
|
+
$ref: "#/$defs/parameter"
|
|
969
|
+
}
|
|
970
|
+
},
|
|
971
|
+
returns: {
|
|
972
|
+
$ref: "#/$defs/returns"
|
|
973
|
+
},
|
|
974
|
+
description: {
|
|
975
|
+
type: "string",
|
|
976
|
+
description: "Signature-level description"
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
parameter: {
|
|
981
|
+
type: "object",
|
|
982
|
+
required: ["name", "required"],
|
|
983
|
+
properties: {
|
|
984
|
+
name: {
|
|
985
|
+
type: "string",
|
|
986
|
+
description: "Parameter name"
|
|
987
|
+
},
|
|
988
|
+
required: {
|
|
989
|
+
type: "boolean",
|
|
990
|
+
description: "Whether the parameter is required"
|
|
991
|
+
},
|
|
992
|
+
schema: {
|
|
993
|
+
$ref: "#/$defs/schema"
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
},
|
|
997
|
+
returns: {
|
|
998
|
+
type: "object",
|
|
999
|
+
properties: {
|
|
1000
|
+
schema: {
|
|
1001
|
+
$ref: "#/$defs/schema"
|
|
1002
|
+
},
|
|
1003
|
+
description: {
|
|
1004
|
+
type: "string",
|
|
1005
|
+
description: "Return value description"
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
},
|
|
1009
|
+
schema: {
|
|
1010
|
+
anyOf: [
|
|
1011
|
+
{
|
|
1012
|
+
type: "boolean"
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
type: "object",
|
|
1016
|
+
properties: {
|
|
1017
|
+
$ref: {
|
|
1018
|
+
type: "string",
|
|
1019
|
+
description: "Reference to another type",
|
|
1020
|
+
pattern: "^#/types/[A-Za-z0-9_.-]+$"
|
|
1021
|
+
}
|
|
1022
|
+
},
|
|
1023
|
+
required: ["$ref"],
|
|
1024
|
+
additionalProperties: false
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
type: "object",
|
|
1028
|
+
not: {
|
|
1029
|
+
required: ["$ref"]
|
|
1030
|
+
},
|
|
1031
|
+
additionalProperties: true
|
|
1032
|
+
}
|
|
1033
|
+
]
|
|
1034
|
+
},
|
|
1035
|
+
sourceLocation: {
|
|
1036
|
+
type: "object",
|
|
1037
|
+
required: ["file", "line"],
|
|
1038
|
+
properties: {
|
|
1039
|
+
file: {
|
|
1040
|
+
type: "string",
|
|
1041
|
+
description: "Source file path"
|
|
1042
|
+
},
|
|
1043
|
+
line: {
|
|
1044
|
+
type: "integer",
|
|
1045
|
+
description: "Line number in source file",
|
|
1046
|
+
minimum: 1
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
663
1052
|
|
|
664
1053
|
// src/validate.ts
|
|
1054
|
+
var LATEST_VERSION = "0.2.0";
|
|
1055
|
+
var schemas = {
|
|
1056
|
+
"0.1.0": openpkg_schema_default2,
|
|
1057
|
+
"0.2.0": openpkg_schema_default
|
|
1058
|
+
};
|
|
665
1059
|
var ajv = new Ajv({
|
|
666
1060
|
strict: false,
|
|
667
1061
|
allErrors: true,
|
|
@@ -669,8 +1063,23 @@ var ajv = new Ajv({
|
|
|
669
1063
|
$data: true
|
|
670
1064
|
});
|
|
671
1065
|
addFormats(ajv);
|
|
672
|
-
var
|
|
673
|
-
function
|
|
1066
|
+
var validatorCache = new Map;
|
|
1067
|
+
function getValidator(version = "latest") {
|
|
1068
|
+
const resolvedVersion = version === "latest" ? LATEST_VERSION : version;
|
|
1069
|
+
let validator = validatorCache.get(resolvedVersion);
|
|
1070
|
+
if (validator) {
|
|
1071
|
+
return validator;
|
|
1072
|
+
}
|
|
1073
|
+
const schema = schemas[resolvedVersion];
|
|
1074
|
+
if (!schema) {
|
|
1075
|
+
throw new Error(`Unknown schema version: ${resolvedVersion}. Available: ${Object.keys(schemas).join(", ")}`);
|
|
1076
|
+
}
|
|
1077
|
+
validator = ajv.compile(schema);
|
|
1078
|
+
validatorCache.set(resolvedVersion, validator);
|
|
1079
|
+
return validator;
|
|
1080
|
+
}
|
|
1081
|
+
function validateSpec(spec, version = "latest") {
|
|
1082
|
+
const validate = getValidator(version);
|
|
674
1083
|
const ok = validate(spec);
|
|
675
1084
|
if (ok) {
|
|
676
1085
|
return { ok: true };
|
|
@@ -685,8 +1094,8 @@ function validateSpec(spec) {
|
|
|
685
1094
|
errors
|
|
686
1095
|
};
|
|
687
1096
|
}
|
|
688
|
-
function assertSpec(spec) {
|
|
689
|
-
const result = validateSpec(spec);
|
|
1097
|
+
function assertSpec(spec, version = "latest") {
|
|
1098
|
+
const result = validateSpec(spec, version);
|
|
690
1099
|
if (!result.ok) {
|
|
691
1100
|
const details = result.errors.map((error) => `- ${error.instancePath || "/"} ${error.message}`).join(`
|
|
692
1101
|
`);
|
|
@@ -694,8 +1103,8 @@ function assertSpec(spec) {
|
|
|
694
1103
|
${details}`);
|
|
695
1104
|
}
|
|
696
1105
|
}
|
|
697
|
-
function getValidationErrors(spec) {
|
|
698
|
-
const result = validateSpec(spec);
|
|
1106
|
+
function getValidationErrors(spec, version = "latest") {
|
|
1107
|
+
const result = validateSpec(spec, version);
|
|
699
1108
|
return result.ok ? [] : result.errors;
|
|
700
1109
|
}
|
|
701
1110
|
export {
|
|
@@ -704,6 +1113,7 @@ export {
|
|
|
704
1113
|
getValidationErrors,
|
|
705
1114
|
diffSpec,
|
|
706
1115
|
dereference,
|
|
1116
|
+
categorizeBreakingChanges,
|
|
707
1117
|
assertSpec,
|
|
708
1118
|
SCHEMA_VERSION,
|
|
709
1119
|
SCHEMA_URL,
|
package/package.json
CHANGED
|
@@ -173,7 +173,16 @@
|
|
|
173
173
|
"kind": {
|
|
174
174
|
"type": "string",
|
|
175
175
|
"description": "Kind of export",
|
|
176
|
-
"enum": [
|
|
176
|
+
"enum": [
|
|
177
|
+
"function",
|
|
178
|
+
"class",
|
|
179
|
+
"variable",
|
|
180
|
+
"interface",
|
|
181
|
+
"type",
|
|
182
|
+
"enum",
|
|
183
|
+
"namespace",
|
|
184
|
+
"external"
|
|
185
|
+
]
|
|
177
186
|
},
|
|
178
187
|
"description": {
|
|
179
188
|
"type": "string",
|