@conduit-client/model 3.7.1 → 3.8.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 (57) hide show
  1. package/dist/types/v1/index.d.ts +2 -1
  2. package/dist/types/v1/parser/__tests__/test-utils.d.ts +433 -0
  3. package/dist/types/v1/{amf → parser/amf}/AMFAPI.d.ts +3 -5
  4. package/dist/types/v1/{amf → parser/amf}/amf-api-service.d.ts +1 -8
  5. package/dist/types/v1/{amf → parser/amf}/amf-utils.d.ts +1 -1
  6. package/dist/types/v1/{amf → parser/amf}/endpoints/amf-endpoint.d.ts +2 -2
  7. package/dist/types/v1/{amf → parser/amf}/endpoints/amf-operation.d.ts +314 -314
  8. package/dist/types/v1/{amf → parser/amf}/index.d.ts +0 -1
  9. package/dist/types/v1/{amf → parser/amf}/types/AMFAllOfType.d.ts +2 -2
  10. package/dist/types/v1/{amf → parser/amf}/types/AMFAnyType.d.ts +1 -1
  11. package/dist/types/v1/{amf → parser/amf}/types/AMFArrayType.d.ts +1 -1
  12. package/dist/types/v1/{amf → parser/amf}/types/AMFBaseType.d.ts +2 -2
  13. package/dist/types/v1/{amf → parser/amf}/types/AMFDiscriminatedObjectType.d.ts +2 -2
  14. package/dist/types/v1/{amf → parser/amf}/types/AMFEnumType.d.ts +3 -3
  15. package/dist/types/v1/{amf → parser/amf}/types/AMFNilType.d.ts +1 -1
  16. package/dist/types/v1/{amf → parser/amf}/types/AMFNotType.d.ts +3 -3
  17. package/dist/types/v1/{amf → parser/amf}/types/AMFObjectType.d.ts +1 -1
  18. package/dist/types/v1/{amf → parser/amf}/types/AMFOneOfType.d.ts +1 -1
  19. package/dist/types/v1/{amf → parser/amf}/types/AMFRefType.d.ts +1 -1
  20. package/dist/types/v1/{amf → parser/amf}/types/AMFScalarTypes.d.ts +3 -3
  21. package/dist/types/v1/parser/amf/types/__tests__/AMFOneOfType.spec.d.ts +1 -0
  22. package/dist/types/v1/parser/amf/types/__tests__/AMFScalarType.spec.d.ts +1 -0
  23. package/dist/types/v1/{amf → parser/amf}/types/factory.d.ts +2 -2
  24. package/dist/types/v1/{amf → parser/amf}/types/index.d.ts +1 -2
  25. package/dist/types/v1/parser/parser-utils.d.ts +10 -0
  26. package/dist/types/v1/parser/zod-schemas.d.ts +445 -0
  27. package/dist/v1/index.js +1833 -1834
  28. package/dist/v1/index.js.map +1 -1
  29. package/package.json +3 -3
  30. package/dist/types/v1/amf/__tests__/test-utils.d.ts +0 -212
  31. package/dist/types/v1/amf/types/annotations-schemas.d.ts +0 -172
  32. /package/dist/types/v1/{amf/types → parser}/__tests__/annotations-schemas.spec.d.ts +0 -0
  33. /package/dist/types/v1/{amf/__tests__/AMFAPI.spec.d.ts → parser/__tests__/parser-api.spec.d.ts} +0 -0
  34. /package/dist/types/v1/{amf/__tests__/amf-api-service.spec.d.ts → parser/__tests__/parser-utils.spec.d.ts} +0 -0
  35. /package/dist/types/v1/{amf/__tests__/amf-extensions-services.spec.d.ts → parser/__tests__/type-factory.spec.d.ts} +0 -0
  36. /package/dist/types/v1/{amf/__tests__/amf-extensions.spec.d.ts → parser/amf/__tests__/AMFAPI.spec.d.ts} +0 -0
  37. /package/dist/types/v1/{amf/__tests__/amf-utils.spec.d.ts → parser/amf/__tests__/amf-api-service.spec.d.ts} +0 -0
  38. /package/dist/types/v1/{amf/__tests__/parser.spec.d.ts → parser/amf/__tests__/amf-extensions-services.spec.d.ts} +0 -0
  39. /package/dist/types/v1/{amf/__tests__/validation.spec.d.ts → parser/amf/__tests__/amf-extensions.spec.d.ts} +0 -0
  40. /package/dist/types/v1/{amf/__tests__/version.spec.d.ts → parser/amf/__tests__/amf-utils.spec.d.ts} +0 -0
  41. /package/dist/types/v1/{amf/endpoints/__tests__/amf-endpoint.spec.d.ts → parser/amf/__tests__/parser.spec.d.ts} +0 -0
  42. /package/dist/types/v1/{amf/endpoints/__tests__/amf-operation.spec.d.ts → parser/amf/__tests__/validation.spec.d.ts} +0 -0
  43. /package/dist/types/v1/{amf/types/__tests__/AMFAnyType.spec.d.ts → parser/amf/__tests__/version.spec.d.ts} +0 -0
  44. /package/dist/types/v1/{amf → parser/amf}/amf-extensions.d.ts +0 -0
  45. /package/dist/types/v1/{amf/types/__tests__/AMFArrayType.spec.d.ts → parser/amf/endpoints/__tests__/amf-endpoint.spec.d.ts} +0 -0
  46. /package/dist/types/v1/{amf/types/__tests__/AMFBaseType.spec.d.ts → parser/amf/endpoints/__tests__/amf-operation.spec.d.ts} +0 -0
  47. /package/dist/types/v1/{amf → parser/amf}/parser.d.ts +0 -0
  48. /package/dist/types/v1/{amf/types/__tests__/AMFDiscriminatedObjectType.spec.d.ts → parser/amf/types/__tests__/AMFAnyType.spec.d.ts} +0 -0
  49. /package/dist/types/v1/{amf/types/__tests__/AMFEnumType.spec.d.ts → parser/amf/types/__tests__/AMFArrayType.spec.d.ts} +0 -0
  50. /package/dist/types/v1/{amf/types/__tests__/AMFNilType.spec.d.ts → parser/amf/types/__tests__/AMFBaseType.spec.d.ts} +0 -0
  51. /package/dist/types/v1/{amf/types/__tests__/AMFNotType.spec.d.ts → parser/amf/types/__tests__/AMFDiscriminatedObjectType.spec.d.ts} +0 -0
  52. /package/dist/types/v1/{amf/types/__tests__/AMFObjectType.spec.d.ts → parser/amf/types/__tests__/AMFEnumType.spec.d.ts} +0 -0
  53. /package/dist/types/v1/{amf/types/__tests__/AMFOneOfType.spec.d.ts → parser/amf/types/__tests__/AMFNilType.spec.d.ts} +0 -0
  54. /package/dist/types/v1/{amf/types/__tests__/AMFScalarType.spec.d.ts → parser/amf/types/__tests__/AMFNotType.spec.d.ts} +0 -0
  55. /package/dist/types/v1/{amf/types/__tests__/factory.spec.d.ts → parser/amf/types/__tests__/AMFObjectType.spec.d.ts} +0 -0
  56. /package/dist/types/v1/{amf → parser/amf}/validation.d.ts +0 -0
  57. /package/dist/types/v1/{amf → parser/amf}/version.d.ts +0 -0
package/dist/v1/index.js CHANGED
@@ -3,9 +3,9 @@
3
3
  * All rights reserved.
4
4
  * For full license text, see the LICENSE.txt file
5
5
  */
6
- import path from "path";
7
- import amf from "amf-client-js";
8
6
  import * as url from "url";
7
+ import amf from "amf-client-js";
8
+ import path from "path";
9
9
  const BindingTypesEnum = ["wire", "imperative", "imperative-legacy", "mutation"];
10
10
  class BaseTypeRegistry extends Map {
11
11
  nameOf(t) {
@@ -969,77 +969,341 @@ class InvalidationValidator {
969
969
  return null;
970
970
  }
971
971
  }
972
- var util;
973
- (function(util2) {
974
- util2.assertEqual = (val) => val;
975
- function assertIs(_arg) {
976
- }
977
- util2.assertIs = assertIs;
978
- function assertNever(_x) {
979
- throw new Error();
980
- }
981
- util2.assertNever = assertNever;
982
- util2.arrayToEnum = (items) => {
983
- const obj = {};
984
- for (const item of items) {
985
- obj[item] = item;
986
- }
987
- return obj;
972
+ const V1_VERSION = "1.0.0";
973
+ const ANONYMOUS_TYPE_NAME = "<anonymous>";
974
+ function asAPIService(api) {
975
+ const p = Promise.resolve(api);
976
+ return {
977
+ build: () => p,
978
+ api
988
979
  };
989
- util2.getValidEnumValues = (obj) => {
990
- const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
991
- const filtered = {};
992
- for (const k of validKeys) {
993
- filtered[k] = obj[k];
980
+ }
981
+ class NoNormalizedTypesValidator {
982
+ constructor(types) {
983
+ this.types = types;
984
+ }
985
+ validate(operation) {
986
+ if (isNormalizedOperation(operation)) {
987
+ return ok([]);
994
988
  }
995
- return util2.objectValues(filtered);
996
- };
997
- util2.objectValues = (obj) => {
998
- return util2.objectKeys(obj).map(function(e) {
999
- return obj[e];
989
+ const identifiableTypes = /* @__PURE__ */ new Set();
990
+ operation.responses.forEach((response) => {
991
+ return response.payloads.forEach((payload) => {
992
+ this.findNestedIdentifiableTypes(payload.data).forEach(
993
+ (type) => identifiableTypes.add(type)
994
+ );
995
+ });
1000
996
  });
1001
- };
1002
- util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
1003
- const keys = [];
1004
- for (const key in object) {
1005
- if (Object.prototype.hasOwnProperty.call(object, key)) {
1006
- keys.push(key);
1007
- }
997
+ const messages = [];
998
+ if (identifiableTypes.size > 0) {
999
+ identifiableTypes.forEach((type) => {
1000
+ const typeName = this.types.nameOf(type) || ANONYMOUS_TYPE_NAME;
1001
+ messages.push(
1002
+ getFormattedMessage(
1003
+ operation,
1004
+ `Operation ${operation.operationId ? `${operation.operationId} ` : ``}is not normalized but references the normalized type ${typeName} in its response`
1005
+ )
1006
+ );
1007
+ });
1008
+ return messages.length === 0 ? ok([]) : err(messages);
1008
1009
  }
1009
- return keys;
1010
- };
1011
- util2.find = (arr, checker) => {
1012
- for (const item of arr) {
1013
- if (checker(item))
1014
- return item;
1010
+ return ok([]);
1011
+ }
1012
+ /**
1013
+ * Completes a breadth-first search of a Type to locate any nested types that are identifiable.
1014
+ *
1015
+ * @returns a Set of all nested types that are identifiable.
1016
+ * @param start
1017
+ * @protected
1018
+ */
1019
+ findNestedIdentifiableTypes(start) {
1020
+ return bfs(
1021
+ [start],
1022
+ (type) => {
1023
+ var _a;
1024
+ return ((_a = type.extensions) == null ? void 0 : _a.type) === "identifiable";
1025
+ },
1026
+ (type) => {
1027
+ const typing = type.type;
1028
+ switch (typing) {
1029
+ case "allOf":
1030
+ return type.allOf;
1031
+ case "array":
1032
+ return [type.items];
1033
+ case "object":
1034
+ return [
1035
+ ...Object.values(type.properties).map((property) => property.type),
1036
+ type.additionalProperties
1037
+ ];
1038
+ case "oneOf":
1039
+ return type.oneOf;
1040
+ case "ref":
1041
+ return [type.$ref];
1042
+ case "discriminatedObject":
1043
+ return [...Object.values(type.mapping), type.baseType];
1044
+ case "any":
1045
+ case "enum":
1046
+ case "boolean":
1047
+ case "double":
1048
+ case "integer":
1049
+ case "number":
1050
+ case "string":
1051
+ case "date":
1052
+ case "datetime":
1053
+ case "datetime-only":
1054
+ case "nil":
1055
+ case "not":
1056
+ case "time":
1057
+ return [];
1058
+ default:
1059
+ throw new Error(
1060
+ `${typing} has not been accounted for when searching for nested identifiable types`
1061
+ );
1062
+ }
1063
+ }
1064
+ );
1065
+ }
1066
+ }
1067
+ class KeyMatchValidator {
1068
+ constructor(types) {
1069
+ this.types = types;
1070
+ }
1071
+ validate(operation) {
1072
+ if (!isNormalizedOperation(operation)) {
1073
+ return ok([]);
1015
1074
  }
1016
- return void 0;
1017
- };
1018
- util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
1019
- function joinValues(array, separator = " | ") {
1020
- return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
1075
+ const operationHasKey = !!operation.cacheStrategy.key;
1076
+ let valid = true;
1077
+ const messages = [];
1078
+ operation.responses.forEach((response) => {
1079
+ response.payloads.forEach((payload) => {
1080
+ var _a, _b;
1081
+ if (((_a = payload.data.extensions) == null ? void 0 : _a.type) === "identifiable") {
1082
+ const typeName = this.types.nameOf(payload.data) || ANONYMOUS_TYPE_NAME;
1083
+ if (!operationHasKey) {
1084
+ valid = false;
1085
+ messages.push(
1086
+ getFormattedMessage(
1087
+ operation,
1088
+ `Operation ${operation.operationId ? `${operation.operationId} ` : ``}is missing a key to match against its ${typeName} response type`
1089
+ )
1090
+ );
1091
+ } else if (!((_b = payload.data.extensions.key) == null ? void 0 : _b.fields)) {
1092
+ valid = false;
1093
+ messages.push(
1094
+ getFormattedMessage(
1095
+ operation,
1096
+ `Operation ${operation.operationId ? `${operation.operationId} ` : ``}has a key but its ${typeName} response type doesn't have one to match against`
1097
+ )
1098
+ );
1099
+ } else if (!deepEquals(
1100
+ Object.keys(operation.cacheStrategy.key || {}),
1101
+ Object.keys(payload.data.extensions.key.fields)
1102
+ )) {
1103
+ valid = false;
1104
+ messages.push(
1105
+ getFormattedMessage(
1106
+ operation,
1107
+ `Operation ${operation.operationId ? `${operation.operationId} ` : ``}and its ${typeName} response type have mismatched keys`
1108
+ )
1109
+ );
1110
+ }
1111
+ }
1112
+ });
1113
+ });
1114
+ return valid ? ok(messages) : err(messages);
1021
1115
  }
1022
- util2.joinValues = joinValues;
1023
- util2.jsonStringifyReplacer = (_, value) => {
1024
- if (typeof value === "bigint") {
1025
- return value.toString();
1116
+ }
1117
+ class BodyDataValidator {
1118
+ constructor(target, keys, keySourcesValidatorSupplier) {
1119
+ this.target = target;
1120
+ this.keys = keys;
1121
+ this.keySourcesValidatorSupplier = keySourcesValidatorSupplier;
1122
+ }
1123
+ validate(operation) {
1124
+ if (this.keys.length === 0) {
1125
+ return ok([]);
1026
1126
  }
1027
- return value;
1127
+ const jsonPayload = this.target.payloads.find((p) => p.mediaType === "application/json");
1128
+ if (jsonPayload === void 0) {
1129
+ return err([
1130
+ getFormattedMessage(
1131
+ operation,
1132
+ `Use of 'body' keys requires a json payload: ${operation.method} ${operation.endpoint.path} has none.`
1133
+ )
1134
+ ]);
1135
+ }
1136
+ const result = this.keySourcesValidatorSupplier(this.keys).validate(jsonPayload.data);
1137
+ if (!result.isOk()) {
1138
+ const message = getFormattedMessage(
1139
+ operation,
1140
+ `Invalid body key(s) specified for ${operation.operationId || `${operation.method} ${operation.endpoint.path}`}`
1141
+ );
1142
+ message.subValidationMessages = result.error;
1143
+ return err([message]);
1144
+ }
1145
+ return ok([]);
1146
+ }
1147
+ }
1148
+ function buildOperationValidator(api) {
1149
+ const bodyDateValidatorSupplier = (target, sources) => {
1150
+ return new BodyDataValidator(target, sources, (keys) => {
1151
+ return new KeySourcesValidator(api.types, keys);
1152
+ });
1028
1153
  };
1029
- })(util || (util = {}));
1030
- var objectUtil;
1031
- (function(objectUtil2) {
1032
- objectUtil2.mergeShapes = (first, second) => {
1033
- return {
1034
- ...first,
1035
- ...second
1036
- // second overwrites first
1037
- };
1154
+ return compose([
1155
+ new InvalidationValidator(api.types, bodyDateValidatorSupplier),
1156
+ new KeySourceValidator(bodyDateValidatorSupplier),
1157
+ new Response200Validator(),
1158
+ new NoNormalizedTypesValidator(api.types),
1159
+ new KeyMatchValidator(api.types)
1160
+ ]);
1161
+ }
1162
+ function buildEndpointValidator(api) {
1163
+ const operationValidator = buildOperationValidator(api);
1164
+ return {
1165
+ validate(subject) {
1166
+ return combineValidationResults(
1167
+ subject.operations.map((operation) => operationValidator.validate(operation))
1168
+ );
1169
+ }
1038
1170
  };
1039
- })(objectUtil || (objectUtil = {}));
1040
- const ZodParsedType = util.arrayToEnum([
1041
- "string",
1042
- "nan",
1171
+ }
1172
+ class BindingsValidation {
1173
+ constructor() {
1174
+ }
1175
+ validate(api) {
1176
+ const messages = [];
1177
+ const endpoints = api.endpoints;
1178
+ const identToPathAndOperation = /* @__PURE__ */ new Map();
1179
+ for (const endpoint of endpoints) {
1180
+ const { path: path2, operations } = endpoint;
1181
+ for (const operation of operations) {
1182
+ const operationId = operation.operationId || `${operation.method} ${operation.endpoint.path}`;
1183
+ const { bindings } = operation;
1184
+ for (const binding of bindings) {
1185
+ const { identifier } = binding;
1186
+ if (identToPathAndOperation.has(identifier)) {
1187
+ const existing = identToPathAndOperation.get(identifier);
1188
+ messages.push({
1189
+ severity: ValidationSeverity.Error,
1190
+ message: `Binding identifier '${identifier}' in operation '${operationId}' is already used in path '${existing.path}' and operation '${existing.operationId}'`,
1191
+ subject: operation,
1192
+ validationType: ValidationType.Operation
1193
+ });
1194
+ } else {
1195
+ identToPathAndOperation.set(identifier, { path: path2, operationId });
1196
+ }
1197
+ }
1198
+ }
1199
+ }
1200
+ return messages.length > 0 ? err(messages) : ok(messages);
1201
+ }
1202
+ }
1203
+ class ApiValidator {
1204
+ constructor(apiValidators, typeValidator, endpointValidator) {
1205
+ this.apiValidators = apiValidators;
1206
+ this.typeValidator = typeValidator;
1207
+ this.endpointValidator = endpointValidator;
1208
+ }
1209
+ validate(subject) {
1210
+ const results = [
1211
+ this.validateCollection(subject.types.values(), this.typeValidator),
1212
+ this.validateCollection(subject.endpoints, this.endpointValidator),
1213
+ ...this.apiValidators.map((v) => v.validate(subject))
1214
+ ];
1215
+ return combineValidationResults(results);
1216
+ }
1217
+ validateCollection(items, validator) {
1218
+ const results = [];
1219
+ for (const item of items) {
1220
+ results.push(validator.validate(item));
1221
+ }
1222
+ return combineValidationResults(results);
1223
+ }
1224
+ }
1225
+ function buildApiValidatorFor(api) {
1226
+ const typeValidation = buildTypeValidator(api.types);
1227
+ const apiValidators = [new BindingsValidation()];
1228
+ const endpointValidation = buildEndpointValidator(api);
1229
+ return new ApiValidator(apiValidators, typeValidation, endpointValidation);
1230
+ }
1231
+ function validateUniqueBindingIdentfiers(operations) {
1232
+ const operationsBindings = operations.map(({ bindings }) => bindings.map(({ identifier }) => identifier)).flat();
1233
+ const uniqueBindings = new Set(operationsBindings);
1234
+ return operationsBindings.length === uniqueBindings.size;
1235
+ }
1236
+ var util;
1237
+ (function(util2) {
1238
+ util2.assertEqual = (val) => val;
1239
+ function assertIs(_arg) {
1240
+ }
1241
+ util2.assertIs = assertIs;
1242
+ function assertNever(_x) {
1243
+ throw new Error();
1244
+ }
1245
+ util2.assertNever = assertNever;
1246
+ util2.arrayToEnum = (items) => {
1247
+ const obj = {};
1248
+ for (const item of items) {
1249
+ obj[item] = item;
1250
+ }
1251
+ return obj;
1252
+ };
1253
+ util2.getValidEnumValues = (obj) => {
1254
+ const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
1255
+ const filtered = {};
1256
+ for (const k of validKeys) {
1257
+ filtered[k] = obj[k];
1258
+ }
1259
+ return util2.objectValues(filtered);
1260
+ };
1261
+ util2.objectValues = (obj) => {
1262
+ return util2.objectKeys(obj).map(function(e) {
1263
+ return obj[e];
1264
+ });
1265
+ };
1266
+ util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
1267
+ const keys = [];
1268
+ for (const key in object) {
1269
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
1270
+ keys.push(key);
1271
+ }
1272
+ }
1273
+ return keys;
1274
+ };
1275
+ util2.find = (arr, checker) => {
1276
+ for (const item of arr) {
1277
+ if (checker(item))
1278
+ return item;
1279
+ }
1280
+ return void 0;
1281
+ };
1282
+ util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
1283
+ function joinValues(array, separator = " | ") {
1284
+ return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
1285
+ }
1286
+ util2.joinValues = joinValues;
1287
+ util2.jsonStringifyReplacer = (_, value) => {
1288
+ if (typeof value === "bigint") {
1289
+ return value.toString();
1290
+ }
1291
+ return value;
1292
+ };
1293
+ })(util || (util = {}));
1294
+ var objectUtil;
1295
+ (function(objectUtil2) {
1296
+ objectUtil2.mergeShapes = (first, second) => {
1297
+ return {
1298
+ ...first,
1299
+ ...second
1300
+ // second overwrites first
1301
+ };
1302
+ };
1303
+ })(objectUtil || (objectUtil = {}));
1304
+ const ZodParsedType = util.arrayToEnum([
1305
+ "string",
1306
+ "nan",
1043
1307
  "number",
1044
1308
  "integer",
1045
1309
  "float",
@@ -5011,6 +5275,106 @@ var z = /* @__PURE__ */ Object.freeze({
5011
5275
  quotelessJson,
5012
5276
  ZodError
5013
5277
  });
5278
+ const serviceVariantDescriptorSchema = z.object({
5279
+ type: z.string(),
5280
+ version: z.string(),
5281
+ tags: z.record(z.string(), z.string()).optional(),
5282
+ default: z.boolean().optional()
5283
+ }).strict();
5284
+ const servicesCatalogSchema = z.record(z.string(), serviceVariantDescriptorSchema);
5285
+ const operationServiceRefSchema = z.object({
5286
+ ref: z.string()
5287
+ }).strict();
5288
+ const operationServiceInlineSchema = z.object({
5289
+ version: z.string(),
5290
+ tags: z.record(z.string(), z.string()).optional(),
5291
+ // Capture but disallow to provide a clearer error
5292
+ optional: z.boolean().optional()
5293
+ }).strict().superRefine((val, ctx) => {
5294
+ if (val.optional !== void 0) {
5295
+ ctx.addIssue({
5296
+ code: z.ZodIssueCode.custom,
5297
+ path: ["optional"],
5298
+ message: "optional is not allowed for service overrides"
5299
+ });
5300
+ }
5301
+ });
5302
+ const operationServicesSchema = z.record(
5303
+ z.string(),
5304
+ z.union([operationServiceRefSchema, operationServiceInlineSchema])
5305
+ );
5306
+ const componentsOnestoreServicesSchema = z.object({ onestore: z.object({ services: servicesCatalogSchema }).strict() }).strict();
5307
+ const operationOnestoreServicesSchema = z.object({ onestore: z.object({ services: operationServicesSchema }).strict() }).strict();
5308
+ function validateAndNormalizeCatalog(catalog) {
5309
+ const parsed = servicesCatalogSchema.safeParse(catalog);
5310
+ if (!parsed.success) {
5311
+ throw new Error(parsed.error.message);
5312
+ }
5313
+ const defaultsByType = {};
5314
+ for (const [alias, descriptor] of Object.entries(parsed.data)) {
5315
+ if (descriptor.default) {
5316
+ const prior = defaultsByType[descriptor.type];
5317
+ if (prior !== void 0 && prior !== alias) {
5318
+ throw new Error(
5319
+ `Multiple defaults defined for service type '${descriptor.type}': '${prior}' and '${alias}'`
5320
+ );
5321
+ }
5322
+ defaultsByType[descriptor.type] = alias;
5323
+ }
5324
+ }
5325
+ return { catalog: parsed.data, defaultsByType };
5326
+ }
5327
+ function resolveOperationServices(services, catalog) {
5328
+ const result = {};
5329
+ for (const [canonicalName, entry] of Object.entries(services)) {
5330
+ if ("ref" in entry) {
5331
+ const alias = entry.ref;
5332
+ const descriptor = catalog == null ? void 0 : catalog.catalog[alias];
5333
+ if (!descriptor) {
5334
+ throw new Error(`ref '${alias}' does not exist in the catalog`);
5335
+ } else if (descriptor.default) {
5336
+ throw new Error(`ref is not required for default service '${alias}'`);
5337
+ } else if (descriptor.type !== canonicalName) {
5338
+ throw new Error(
5339
+ `Service '${alias}' uses non-canonical type '${descriptor.type}'. Expected canonical type '${canonicalName}'`
5340
+ );
5341
+ }
5342
+ result[canonicalName] = {
5343
+ type: descriptor.type,
5344
+ version: descriptor.version,
5345
+ tags: descriptor.tags
5346
+ };
5347
+ } else {
5348
+ const inline = entry;
5349
+ result[canonicalName] = {
5350
+ type: canonicalName,
5351
+ version: inline.version,
5352
+ tags: inline.tags
5353
+ };
5354
+ }
5355
+ }
5356
+ return result;
5357
+ }
5358
+ function resolveDefaultServiceOverrides(catalog) {
5359
+ const result = {};
5360
+ if (catalog) {
5361
+ for (const [alias, type] of Object.entries(catalog.defaultsByType)) {
5362
+ const entry = catalog.catalog[type];
5363
+ if (entry && !result[entry.type]) {
5364
+ result[entry.type] = {
5365
+ type: entry.type,
5366
+ version: entry.version,
5367
+ tags: entry.tags
5368
+ };
5369
+ } else {
5370
+ throw new Error(
5371
+ `Missing or multiple default service overrides for service ${alias}`
5372
+ );
5373
+ }
5374
+ }
5375
+ }
5376
+ return result;
5377
+ }
5014
5378
  function formatZodError(err2) {
5015
5379
  const formattedIssues = err2.issues.map((iss) => {
5016
5380
  if (iss.code === "invalid_type") {
@@ -5175,6 +5539,15 @@ function buildExtensionScalar(graph) {
5175
5539
  const value = [DOUBLE_DATA_TYPE, INTEGER_DATA_TYPE, NUMBER_DATA_TYPE].includes(rawType) ? Number(rawValue) : rawType === BOOLEAN_DATA_TYPE ? rawValue === "true" : String(rawValue);
5176
5540
  return value;
5177
5541
  }
5542
+ const rootExtensionSchema = z.object({
5543
+ onestore: z.object({
5544
+ version: z.string().refine(stringIsVersion, () => {
5545
+ return {
5546
+ message: "Version must satisfy format major[.minor[.patch]]"
5547
+ };
5548
+ })
5549
+ })
5550
+ });
5178
5551
  const cacheControl = z.discriminatedUnion("type", [
5179
5552
  z.object({
5180
5553
  type: z.literal("max-age"),
@@ -5242,1512 +5615,1425 @@ const typeExtensions = z.object({
5242
5615
  // @todo: .strict();
5243
5616
  "cache-control": cacheControl
5244
5617
  }).strict();
5245
- const annotationSchema = z.object({
5246
- onestore: typeExtensions.optional()
5247
- });
5248
- class AMFBaseType {
5249
- constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
5250
- var _a;
5251
- this.api = api;
5252
- this.shape = shape;
5253
- this.typeRegistry = typeRegistry;
5254
- this.factory = factory;
5255
- this.logger = logger;
5256
- this.fileParserLogger = fileParserLogger;
5257
- this.resolved = false;
5258
- this.parsedExtensions = { type: "unidentifiable" };
5259
- const { line = 0, column = 0 } = ((_a = this.shape.position) == null ? void 0 : _a.start) || {};
5260
- this.shapePosition = { line, column };
5618
+ const baseExtensionsSchema = z.object({
5619
+ onestore: z.object({
5620
+ defaults: z.object({
5621
+ operations: z.object({
5622
+ "cache-strategy": z.discriminatedUnion("type", [
5623
+ z.object({ type: z.literal("none") }).strict(),
5624
+ z.object({ type: z.literal("resource") }).strict(),
5625
+ z.object({ type: z.literal("normalized") }).strict()
5626
+ ])
5627
+ }),
5628
+ schemas: z.object({
5629
+ "cache-control": cacheControl
5630
+ })
5631
+ }).partial().strict().optional(),
5632
+ // Allow service catalog at root-level for reliability
5633
+ services: servicesCatalogSchema.optional(),
5634
+ namespace: z.string().optional(),
5635
+ version: z.string()
5636
+ }).strict()
5637
+ });
5638
+ const cacheInvalidationEntrySchema = z.object({
5639
+ ref: z.string(),
5640
+ key: z.record(z.string(), z.string())
5641
+ });
5642
+ const cacheInvalidationSchema = z.object({
5643
+ onestore: z.object({
5644
+ invalidate: z.array(cacheInvalidationEntrySchema)
5645
+ })
5646
+ });
5647
+ class OperationSchemaBuilder {
5648
+ constructor(method, operationId, operationCacheStrategyType) {
5649
+ this.method = method;
5650
+ this.operationId = operationId;
5651
+ this.operationCacheStrategyType = operationCacheStrategyType;
5261
5652
  }
5262
- resolve() {
5263
- var _a;
5264
- if (!this.resolved) {
5265
- this.resolved = true;
5266
- const annotationResult = annotationSchema.safeParse(
5267
- extractExtensions(this.shape.customDomainProperties)
5268
- );
5269
- if (!annotationResult.success) {
5270
- const message = formatZodError(annotationResult.error);
5271
- this.fileParserLogger.error(
5272
- this.shape.position.start,
5273
- `Errors validating type:
5274
- ${message}`
5653
+ buildOperationSchema() {
5654
+ const bindingSchema = z.object({
5655
+ type: z.enum(BindingTypesEnum).default("wire"),
5656
+ identifier: z.string().default("")
5657
+ });
5658
+ const configSchema = z.object({
5659
+ "operation-type": z.enum(["query", "mutation", "graphql"]).default(this.method === "GET" ? "query" : "mutation"),
5660
+ schema: z.enum(["flattened", "default"]).default("default"),
5661
+ bindings: z.array(bindingSchema).default([]),
5662
+ exposeRefresh: z.boolean().default(false),
5663
+ "body-param": z.string().optional()
5664
+ }).default({}).transform((config, ctx) => {
5665
+ const { bindings, "operation-type": operationType } = config;
5666
+ if (bindings.length === 0) {
5667
+ if (!this.operationId) {
5668
+ ctx.addIssue({
5669
+ code: z.ZodIssueCode.custom,
5670
+ message: `operationId is required for adapter name generation when no explicit bindings defined for operation. Add an operationId or expicit bindings annotation.`
5671
+ });
5672
+ return config;
5673
+ }
5674
+ if (operationType === "graphql") {
5675
+ config.bindings = [{ type: "wire", identifier: this.operationId }];
5676
+ return config;
5677
+ } else {
5678
+ const bindingType = operationType === "query" ? "wire" : "imperative";
5679
+ config.bindings = [{ type: bindingType, identifier: this.operationId }];
5680
+ }
5681
+ } else if (bindings.length === 1) {
5682
+ if (!bindings[0].identifier) {
5683
+ if (!this.operationId) {
5684
+ ctx.addIssue({
5685
+ code: z.ZodIssueCode.custom,
5686
+ message: `operationId is required for adapter name generation when one explicit binding is requested without an identifier. Add an operationId or a binding identifier.`
5687
+ });
5688
+ return config;
5689
+ }
5690
+ bindings[0].identifier = this.operationId;
5691
+ }
5692
+ }
5693
+ return config;
5694
+ }).refine(
5695
+ (config) => {
5696
+ const { bindings, "operation-type": operationType } = config;
5697
+ if (operationType === "mutation") {
5698
+ return !bindings.some(
5699
+ (binding) => binding.type === "wire" || binding.type === "imperative-legacy"
5700
+ );
5701
+ }
5702
+ return true;
5703
+ },
5704
+ {
5705
+ message: 'Cannot use "wire" or "imperative-legacy" binding with operation-type "mutation"'
5706
+ }
5707
+ ).refine(
5708
+ (config) => {
5709
+ const { "operation-type": operationType, exposeRefresh } = config;
5710
+ return !(exposeRefresh && operationType === "mutation");
5711
+ },
5712
+ {
5713
+ message: 'Cannot exposeRefresh with operation-type "mutation"'
5714
+ }
5715
+ ).refine(
5716
+ (config) => {
5717
+ const { bindings, exposeRefresh } = config;
5718
+ if (!exposeRefresh) {
5719
+ return true;
5720
+ }
5721
+ return bindings.some(
5722
+ (binding) => binding.type === "wire" || binding.type === "imperative"
5275
5723
  );
5276
- throw new Error();
5724
+ },
5725
+ {
5726
+ message: 'Cannot use exposeRefresh without a "wire" or "imperative" binding'
5277
5727
  }
5278
- if ((_a = annotationResult.data.onestore) == null ? void 0 : _a.key) {
5279
- this.parsedExtensions = {
5280
- type: "identifiable",
5281
- ...annotationResult.data.onestore
5282
- };
5728
+ ).refine(
5729
+ (config) => {
5730
+ const { bindings } = config;
5731
+ if (bindings.length <= 1) {
5732
+ return true;
5733
+ }
5734
+ return bindings.every((binding) => !!binding.identifier);
5735
+ },
5736
+ {
5737
+ message: "Binding identifier is required if more than one binding is provided."
5283
5738
  }
5284
- this.logger.trace("Running this types resolution");
5285
- this.typeResolve();
5286
- } else {
5287
- this.logger.trace("Type was already resolved");
5288
- }
5289
- }
5290
- /*
5291
- Placeholder for type specific resolution
5292
- */
5293
- typeResolve() {
5739
+ ).refine(
5740
+ (config) => {
5741
+ const { bindings } = config;
5742
+ if (bindings.length <= 1) {
5743
+ return true;
5744
+ }
5745
+ const identifiers = bindings.map((binding) => binding.identifier);
5746
+ return new Set(identifiers).size === identifiers.length;
5747
+ },
5748
+ { message: "Binding identifier must be unique" }
5749
+ ).refine(
5750
+ (config) => {
5751
+ const { bindings, "operation-type": operationType } = config;
5752
+ if (operationType !== "graphql") {
5753
+ return !bindings.some((binding) => binding.type === "mutation");
5754
+ }
5755
+ return true;
5756
+ },
5757
+ {
5758
+ message: 'Cannot use "mutation" binding with non-graphql operations'
5759
+ }
5760
+ ).superRefine((config, ctx) => {
5761
+ config.bindings.forEach((binding) => {
5762
+ const tsSafeIdentifier = toTypeScriptSafeIdentifier(binding.identifier);
5763
+ if (binding.identifier !== tsSafeIdentifier) {
5764
+ ctx.addIssue({
5765
+ code: z.ZodIssueCode.custom,
5766
+ message: `Invalid identifier "${binding.identifier}" for adapter binding. This may be derived from operationId. Use a valid TypeScript variable name, e.g. '${tsSafeIdentifier}'.`
5767
+ });
5768
+ }
5769
+ });
5770
+ });
5771
+ return z.object({
5772
+ onestore: z.object({
5773
+ config: configSchema,
5774
+ "cache-strategy": operationCacheStrategy(this.operationCacheStrategyType),
5775
+ "error-strategy": z.discriminatedUnion("type", [
5776
+ z.object({ type: z.literal("stringified") }).strict(),
5777
+ z.object({ type: z.literal("fetchResponse") }).strict()
5778
+ ]).default({ type: "stringified" }),
5779
+ services: operationServicesSchema.optional()
5780
+ }).strict().default({}).transform((extensions) => {
5781
+ var _a;
5782
+ if (((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized" && extensions.config["operation-type"] === "mutation") {
5783
+ if (extensions["cache-strategy"]["cache-control"] === void 0) {
5784
+ extensions["cache-strategy"]["cache-control"] = {
5785
+ type: "no-cache"
5786
+ };
5787
+ }
5788
+ }
5789
+ return extensions;
5790
+ }).refine(
5791
+ (extensions) => {
5792
+ var _a;
5793
+ if (((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized") {
5794
+ const cacheControl2 = extensions["cache-strategy"]["cache-control"];
5795
+ if (extensions.config["operation-type"] === "mutation" && cacheControl2) {
5796
+ return cacheControl2.type === "no-cache";
5797
+ }
5798
+ }
5799
+ return true;
5800
+ },
5801
+ {
5802
+ message: 'Cannot use "cache-control" values other than "no-cache" with operation-type "mutation"'
5803
+ }
5804
+ ).refine(
5805
+ (extensions) => {
5806
+ var _a;
5807
+ if (((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized") {
5808
+ if (extensions.config["operation-type"] === "query") {
5809
+ return extensions["cache-strategy"]["cache-control"] !== void 0;
5810
+ }
5811
+ }
5812
+ return true;
5813
+ },
5814
+ {
5815
+ message: 'Cannot use undefined "cache-control" with operation-type "query"'
5816
+ }
5817
+ ).refine(
5818
+ (extensions) => {
5819
+ var _a;
5820
+ if (extensions.config["operation-type"] === "graphql") {
5821
+ return ((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized";
5822
+ }
5823
+ return true;
5824
+ },
5825
+ {
5826
+ message: "GraphQL operations must use normalized cache strategy"
5827
+ }
5828
+ )
5829
+ });
5294
5830
  }
5295
- get extensions() {
5296
- if (this.parsedExtensions.type === "identifiable") {
5297
- const CACHE_CONTROL = "cache-control";
5298
- const defaults = this.api.defaults.typeCacheControl;
5831
+ buildHttpOperationSchema() {
5832
+ return this.buildOperationSchema().transform((config, _ctx) => {
5833
+ let bodyParam = config.onestore.config["body-param"] === void 0 ? "inputPayload" : config.onestore.config["body-param"];
5299
5834
  return {
5300
- ...this.parsedExtensions,
5301
- [CACHE_CONTROL]: {
5302
- ...defaults,
5303
- ...this.parsedExtensions[CACHE_CONTROL]
5835
+ onestore: {
5836
+ config: {
5837
+ ...config.onestore.config,
5838
+ "body-param": bodyParam
5839
+ }
5304
5840
  }
5305
5841
  };
5306
- } else {
5307
- return this.parsedExtensions;
5308
- }
5842
+ });
5309
5843
  }
5310
- }
5311
- class AMFAnyTypeImpl extends AMFBaseType {
5312
- constructor() {
5313
- super(...arguments);
5314
- this.type = "any";
5315
- }
5316
- }
5317
- class AMFObjectTypeImpl extends AMFBaseType {
5318
- constructor() {
5319
- super(...arguments);
5320
- this.type = "object";
5321
- this.properties = {};
5322
- this.resolved = false;
5323
- this.additionalProperties = { type: "any" };
5324
- }
5325
- typeResolve() {
5326
- var _a;
5327
- if (((_a = this.shape.values) == null ? void 0 : _a.length) > 0) {
5328
- this.fileParserLogger.error(
5329
- this.shapePosition,
5330
- `Type Error (${this.shape.name.value()}). Object type may not specify enum property.`
5331
- );
5332
- throw new Error();
5333
- }
5334
- this.logger.trace("Resolving properties");
5335
- this.resolveProperties();
5336
- this.logger.trace("Resolving additional properties");
5337
- this.resolveAdditionalProperties();
5338
- }
5339
- resolveProperties() {
5340
- for (const property of this.shape.properties) {
5341
- const propertyName = property.name.value();
5342
- const type = this.factory(
5343
- this.api,
5344
- property.range,
5345
- this.typeRegistry,
5346
- this.logger,
5347
- this.fileParserLogger,
5348
- true
5349
- );
5350
- type.resolve();
5351
- const propertyType = {
5352
- type,
5353
- required: property.minCount.value() !== 0
5354
- };
5355
- this.properties[propertyName] = propertyType;
5356
- }
5844
+ buildAuraOperationSchema() {
5845
+ return this.buildOperationSchema().and(
5846
+ z.object({
5847
+ onestore: z.object({
5848
+ config: z.object({
5849
+ aura: z.object({
5850
+ method: z.string()
5851
+ })
5852
+ })
5853
+ })
5854
+ })
5855
+ );
5357
5856
  }
5358
- resolveAdditionalProperties() {
5359
- if (this.shape.closed.value()) {
5360
- this.additionalProperties = {
5361
- type: "not",
5362
- not: { type: "any" }
5857
+ buildAuraOperationWithBodySchema() {
5858
+ return this.buildAuraOperationSchema().and(
5859
+ z.object({
5860
+ onestore: z.object({
5861
+ config: z.object({
5862
+ aura: z.object({
5863
+ "body-param": z.string().optional()
5864
+ })
5865
+ })
5866
+ })
5867
+ })
5868
+ ).transform((config, ctx) => {
5869
+ let topLevelParam = config.onestore.config["body-param"];
5870
+ let auraParam = config.onestore.config.aura["body-param"];
5871
+ if (topLevelParam === void 0 && auraParam === void 0) {
5872
+ ctx.addIssue({
5873
+ code: z.ZodIssueCode.custom,
5874
+ message: "Missing body-param in both x-onestore.config and x-onestore.config.aura."
5875
+ });
5876
+ return z.NEVER;
5877
+ }
5878
+ if (topLevelParam !== void 0 && auraParam !== void 0) {
5879
+ return config;
5880
+ }
5881
+ if (topLevelParam === void 0) {
5882
+ topLevelParam = auraParam;
5883
+ }
5884
+ if (auraParam === void 0) {
5885
+ auraParam = topLevelParam;
5886
+ }
5887
+ return {
5888
+ onestore: {
5889
+ config: {
5890
+ ...config.onestore.config,
5891
+ "body-param": topLevelParam,
5892
+ aura: {
5893
+ ...config.onestore.config.aura,
5894
+ "body-param": auraParam
5895
+ }
5896
+ }
5897
+ }
5363
5898
  };
5364
- } else if (this.shape.additionalPropertiesSchema) {
5365
- this.additionalProperties = this.factory(
5366
- this.api,
5367
- this.shape.additionalPropertiesSchema,
5368
- this.typeRegistry,
5369
- this.logger,
5370
- this.fileParserLogger,
5371
- true
5372
- );
5373
- }
5899
+ });
5374
5900
  }
5375
- }
5376
- class AMFNilTypeImpl extends AMFBaseType {
5377
- constructor() {
5378
- super(...arguments);
5379
- this.type = "nil";
5901
+ buildGraphQLOperationSchema() {
5902
+ return this.buildOperationSchema().and(
5903
+ z.object({
5904
+ onestore: z.object({
5905
+ config: z.object({
5906
+ graphql: z.object({
5907
+ schema: z.string(),
5908
+ "type-metadata": z.array(
5909
+ z.object({
5910
+ typename: z.string(),
5911
+ "cache-control": cacheControl
5912
+ })
5913
+ ).default([])
5914
+ })
5915
+ })
5916
+ })
5917
+ })
5918
+ );
5380
5919
  }
5381
5920
  }
5382
- class AMFNotTypeImpl extends AMFBaseType {
5383
- constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
5384
- super(api, shape, typeRegistry, factory, logger, fileParserLogger);
5385
- this.shape = shape;
5921
+ class AmfBaseOperation {
5922
+ constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
5923
+ this.amfOperation = amfOperation;
5924
+ this.amfTypeFactory = amfTypeFactory2;
5386
5925
  this.typeRegistry = typeRegistry;
5387
- this.factory = factory;
5388
5926
  this.logger = logger;
5389
5927
  this.fileParserLogger = fileParserLogger;
5390
- this.type = "not";
5391
- const amfType = this.factory(
5392
- this.api,
5393
- this.shape.not,
5394
- this.typeRegistry,
5395
- this.logger,
5396
- this.fileParserLogger
5397
- );
5398
- amfType.resolve();
5399
- this.not = amfType;
5400
- }
5401
- }
5402
- class AMFAllOfTypeImpl extends AMFBaseType {
5403
- constructor() {
5404
- super(...arguments);
5405
- this.type = "allOf";
5406
- this.allOf = [];
5407
- }
5408
- typeResolve() {
5409
- this.logger.trace("Running resolution for inherited and composed shapes");
5410
- const allOfTypes = [...this.shape.inherits, ...this.shape.and].map(
5411
- (inheritedShape) => {
5412
- return this.factory(
5413
- this.api,
5414
- inheritedShape,
5415
- this.typeRegistry,
5416
- this.logger,
5417
- this.fileParserLogger,
5418
- true
5419
- );
5420
- }
5421
- );
5422
- const rootType = this.factory(
5423
- this.api,
5424
- this.shape,
5425
- this.typeRegistry,
5426
- this.logger,
5427
- this.fileParserLogger,
5428
- true,
5429
- /* @__PURE__ */ new Set([
5430
- "any",
5431
- "ref",
5432
- "array",
5433
- "boolean",
5434
- "date",
5435
- "number",
5436
- "datetime",
5437
- "datetime-only",
5438
- "double",
5439
- "integer",
5440
- "nil",
5441
- "not",
5442
- "number",
5443
- "object",
5444
- "string",
5445
- "time"
5446
- ]),
5447
- true
5928
+ this.endpoint = endpoint;
5929
+ this.server = server;
5930
+ this.defaults = endpoint.api.defaults;
5931
+ this.method = this.amfOperation.method.value().toUpperCase();
5932
+ this.position = {
5933
+ line: this.amfOperation.position.lineFrom.valueOf(),
5934
+ column: this.amfOperation.position.columnFrom.valueOf()
5935
+ };
5936
+ const extensionsRaw = extractExtensions(this.amfOperation.customDomainProperties);
5937
+ this.operationId = this.amfOperation.operationId.value() || this.amfOperation.name.value();
5938
+ this.operationSchemaBuilder = new OperationSchemaBuilder(
5939
+ this.method,
5940
+ this.operationId,
5941
+ this.defaults.operationCacheStrategy
5448
5942
  );
5449
- this.allOf = [rootType, ...allOfTypes];
5450
- if (isOneOfShape(this.shape)) {
5451
- const OneOf = this.factory(
5452
- this.api,
5453
- this.shape,
5454
- this.typeRegistry,
5455
- this.logger,
5456
- this.fileParserLogger,
5457
- true,
5458
- /* @__PURE__ */ new Set(["oneOf"]),
5459
- true
5460
- );
5461
- this.allOf.push(OneOf);
5462
- }
5463
- if (isEnumShape(this.shape)) {
5464
- const enumType2 = this.factory(
5465
- this.api,
5466
- this.shape,
5467
- this.typeRegistry,
5468
- this.logger,
5469
- this.fileParserLogger,
5470
- true,
5471
- /* @__PURE__ */ new Set(["enum"]),
5472
- true
5943
+ const extensionsResult = this.operationSchemaBuilder.buildOperationSchema().default({}).safeParse(extensionsRaw);
5944
+ if (!extensionsResult.success) {
5945
+ const message = formatZodError(extensionsResult.error);
5946
+ this.fileParserLogger.error(
5947
+ this.amfOperation.position.start,
5948
+ `Error validating operation:
5949
+ ${message}`
5473
5950
  );
5474
- this.allOf.push(enumType2);
5951
+ throw new Error(`Error validating operation:
5952
+ ${message}`);
5475
5953
  }
5476
- this.validateDiscriminators();
5477
- }
5478
- includes(t) {
5479
- return this.allOf.some((parent) => {
5480
- const canonicalizedParent = canonicalizeType(parent);
5481
- if (canonicalizedParent === t) {
5482
- return true;
5954
+ const extensions = extensionsResult.data;
5955
+ this.operationType = extensions.onestore.config["operation-type"];
5956
+ this.configSchemaType = extensions.onestore.config.schema;
5957
+ this.bindings = extensions.onestore.config.bindings;
5958
+ this.exposeRefresh = extensions.onestore.config.exposeRefresh;
5959
+ this.parsedCacheStrategy = extensions.onestore["cache-strategy"];
5960
+ this.errorStrategy = extensions.onestore["error-strategy"];
5961
+ this.basePath = this.endpoint.api.basePath;
5962
+ if (extensions.onestore.services) {
5963
+ this.serviceOverrides = resolveOperationServices(
5964
+ extensions.onestore.services,
5965
+ this.endpoint.api.serviceOverrides
5966
+ );
5967
+ } else {
5968
+ this.serviceOverrides = {};
5969
+ }
5970
+ this.requests = this.amfOperation.requests.map((request) => {
5971
+ return {
5972
+ queryParameters: this.buildParams(request.queryParameters),
5973
+ uriParameters: this.buildParams(request.uriParameters),
5974
+ payloads: this.buildPayloads(request),
5975
+ cookies: this.buildParams(request.cookieParameters),
5976
+ headers: this.buildParams(request.headers)
5977
+ };
5978
+ });
5979
+ this.responses = this.amfOperation.responses.map((response) => {
5980
+ const extensionsRaw2 = extractExtensions(response.customDomainProperties);
5981
+ if (extensionsRaw2.onestore !== void 0) {
5982
+ const extensionsResult2 = cacheInvalidationSchema.safeParse(extensionsRaw2);
5983
+ if (!extensionsResult2.success) {
5984
+ const message = formatZodError(extensionsResult2.error);
5985
+ this.fileParserLogger.error(
5986
+ this.amfOperation.position.start,
5987
+ `Error validating operation invalidation annotation:
5988
+ ${message}`
5989
+ );
5990
+ throw new Error(
5991
+ `Error validating operation invalidation annotation:
5992
+ ${message}`
5993
+ );
5994
+ }
5995
+ const extensions2 = extensionsResult2.data;
5996
+ if (Object.keys(extensions2.onestore.invalidate).length > 0 && this.operationType === "query") {
5997
+ this.fileParserLogger.error(
5998
+ this.position,
5999
+ `Cannot use an invalidate extension on a query type adapter`
6000
+ );
6001
+ throw new Error();
6002
+ }
6003
+ return {
6004
+ statusCode: response.statusCode.value(),
6005
+ headers: this.buildParams(response.headers),
6006
+ payloads: this.buildPayloads(response),
6007
+ invalidation: extensions2.onestore.invalidate
6008
+ };
5483
6009
  }
5484
- return canonicalizedParent.type === "allOf" && canonicalizedParent.includes(t);
6010
+ return {
6011
+ statusCode: response.statusCode.value(),
6012
+ headers: this.buildParams(response.headers),
6013
+ payloads: this.buildPayloads(response)
6014
+ };
5485
6015
  });
5486
6016
  }
5487
- get discriminatedParent() {
5488
- var _a;
5489
- const discriminatedParents = [
5490
- ...bfs(
5491
- [this],
5492
- (type) => {
5493
- return isDiscriminatedObjectType(type);
5494
- },
5495
- (type) => {
5496
- return type.type === "allOf" ? type.allOf : type.type === "ref" ? [type.$ref] : [];
5497
- }
5498
- ).values()
5499
- ];
5500
- if (discriminatedParents.length === 0) {
5501
- return;
6017
+ get cacheStrategy() {
6018
+ return this.parsedCacheStrategy;
6019
+ }
6020
+ buildPayloads(r) {
6021
+ return r.payloads.map((payload) => {
6022
+ return {
6023
+ mediaType: payload.mediaType.value(),
6024
+ data: this.amfTypeFactory(
6025
+ {},
6026
+ payload.schema,
6027
+ this.typeRegistry,
6028
+ this.logger,
6029
+ this.fileParserLogger,
6030
+ true
6031
+ )
6032
+ };
6033
+ });
6034
+ }
6035
+ getDefaultValue(param) {
6036
+ var _a, _b;
6037
+ const defaultValue = (_a = param.schema) == null ? void 0 : _a.defaultValue;
6038
+ if (defaultValue) {
6039
+ return (_b = defaultValue.value) == null ? void 0 : _b.value();
5502
6040
  }
5503
- if (discriminatedParents.length > 1) {
5504
- const { line = 0, column = 0 } = ((_a = this.shape.position) == null ? void 0 : _a.start) || {};
6041
+ }
6042
+ buildParams(p) {
6043
+ const params = {};
6044
+ p.forEach((param) => {
6045
+ params[`${param.name.value()}`] = {
6046
+ required: param.required.value(),
6047
+ type: this.amfTypeFactory(
6048
+ {},
6049
+ param.schema,
6050
+ this.typeRegistry,
6051
+ this.logger,
6052
+ this.fileParserLogger,
6053
+ true
6054
+ ),
6055
+ explode: param.explode.value(),
6056
+ defaultValue: this.getDefaultValue(param)
6057
+ };
6058
+ });
6059
+ return params;
6060
+ }
6061
+ }
6062
+ class AmfHttpOperation extends AmfBaseOperation {
6063
+ constructor() {
6064
+ super(...arguments);
6065
+ this.type = "http";
6066
+ }
6067
+ }
6068
+ class AmfHttpOperationWithRequestBody extends AmfBaseOperation {
6069
+ constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6070
+ super(
6071
+ amfOperation,
6072
+ amfTypeFactory2,
6073
+ typeRegistry,
6074
+ logger,
6075
+ fileParserLogger,
6076
+ endpoint,
6077
+ server
6078
+ );
6079
+ this.type = "http";
6080
+ const hasRequestBody = amfOperation.requests.some((request) => request.payloads.length > 0);
6081
+ if (!hasRequestBody) {
6082
+ throw new Error("Operation must have a request body defined");
6083
+ }
6084
+ this.method = amfOperation.method.value().toUpperCase();
6085
+ const extensionsRaw = extractExtensions(amfOperation.customDomainProperties);
6086
+ const extensionsResult = this.operationSchemaBuilder.buildHttpOperationSchema().default({}).safeParse(extensionsRaw);
6087
+ if (!extensionsResult.success) {
6088
+ const message = formatZodError(extensionsResult.error);
5505
6089
  this.fileParserLogger.error(
5506
- { line, column },
5507
- `Type ${this.typeRegistry.nameOf(
5508
- this
5509
- )} cannot inherit from multiple discriminated objects. Inherits from ${discriminatedParents.map(
5510
- (parent) => this.typeRegistry.nameOf(parent)
5511
- )}.`
6090
+ this.amfOperation.position.start,
6091
+ `Error validating aura operation:
6092
+ ${message}`
5512
6093
  );
5513
6094
  throw new Error();
5514
6095
  }
5515
- return discriminatedParents[0];
5516
- }
5517
- validateDiscriminators() {
5518
- this.discriminatedParent;
6096
+ const extensions = extensionsResult.data;
6097
+ if (!extensions.onestore.config["body-param"]) {
6098
+ throw new Error("Missing body-param");
6099
+ }
6100
+ this.configBodyParam = extensions.onestore.config["body-param"];
5519
6101
  }
5520
- get extensions() {
5521
- var _a, _b;
5522
- if (super.extensions.type === "identifiable") {
5523
- return super.extensions;
6102
+ }
6103
+ class AmfAuraOperation extends AmfBaseOperation {
6104
+ constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6105
+ super(
6106
+ amfOperation,
6107
+ amfTypeFactory2,
6108
+ typeRegistry,
6109
+ logger,
6110
+ fileParserLogger,
6111
+ endpoint,
6112
+ server
6113
+ );
6114
+ this.type = "aura";
6115
+ const hasRequestBody = amfOperation.requests.some((request) => request.payloads.length > 0);
6116
+ if (hasRequestBody) {
6117
+ throw new Error("Operation must not have a request body defined");
5524
6118
  }
5525
- if (((_b = (_a = this.discriminatedParent) == null ? void 0 : _a.extensions) == null ? void 0 : _b.type) === "identifiable") {
5526
- return this.discriminatedParent.extensions;
6119
+ this.method = amfOperation.method.value().toUpperCase();
6120
+ const extensionsRaw = extractExtensions(amfOperation.customDomainProperties);
6121
+ const extensionsResult = this.operationSchemaBuilder.buildAuraOperationSchema().safeParse(extensionsRaw);
6122
+ if (!extensionsResult.success) {
6123
+ const message = formatZodError(extensionsResult.error);
6124
+ this.fileParserLogger.error(
6125
+ this.amfOperation.position.start,
6126
+ `Error validating aura operation:
6127
+ ${message}`
6128
+ );
6129
+ throw new Error();
5527
6130
  }
5528
- return super.extensions;
6131
+ const extensions = extensionsResult.data;
6132
+ this.aura = { methodName: extensions.onestore.config.aura.method };
5529
6133
  }
5530
6134
  }
5531
- class AMFEnumerableScalarType extends AMFBaseType {
5532
- typeResolve() {
5533
- var _a;
5534
- if (((_a = this.shape.values) == null ? void 0 : _a.length) > 0) {
5535
- this.values = getEnumValuesFromShape(this.shape);
6135
+ class AmfAuraOperationWithRequestBody extends AmfBaseOperation {
6136
+ constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6137
+ super(
6138
+ amfOperation,
6139
+ amfTypeFactory2,
6140
+ typeRegistry,
6141
+ logger,
6142
+ fileParserLogger,
6143
+ endpoint,
6144
+ server
6145
+ );
6146
+ this.type = "aura";
6147
+ const hasRequestBody = amfOperation.requests.some((request) => request.payloads.length > 0);
6148
+ if (!hasRequestBody) {
6149
+ throw new Error("Operation must have a request body defined");
5536
6150
  }
5537
- if (this.parsedExtensions.type === "identifiable") {
6151
+ this.method = amfOperation.method.value().toUpperCase();
6152
+ const extensionsRaw = extractExtensions(amfOperation.customDomainProperties);
6153
+ const extensionsResult = this.operationSchemaBuilder.buildAuraOperationWithBodySchema().safeParse(extensionsRaw);
6154
+ if (!extensionsResult.success) {
6155
+ const message = formatZodError(extensionsResult.error);
5538
6156
  this.fileParserLogger.error(
5539
- this.shape.position.start,
5540
- `${this.shape.name} is scalar and thus cannot be made identifiable by specifying a key`
6157
+ this.amfOperation.position.start,
6158
+ `Error validating aura operation:
6159
+ ${message}`
5541
6160
  );
5542
6161
  throw new Error();
5543
6162
  }
6163
+ const extensions = extensionsResult.data;
6164
+ if (extensions.onestore.config["body-param"] === void 0) {
6165
+ throw new Error("Missing body param");
6166
+ }
6167
+ if (extensions.onestore.config.aura["body-param"] === void 0) {
6168
+ throw new Error("Missing aura body param");
6169
+ }
6170
+ this.configBodyParam = extensions.onestore.config["body-param"];
6171
+ this.aura = {
6172
+ methodName: extensions.onestore.config.aura.method,
6173
+ bodyParam: extensions.onestore.config.aura["body-param"]
6174
+ };
5544
6175
  }
5545
6176
  }
5546
- class AMFBooleanTypeImpl extends AMFEnumerableScalarType {
5547
- constructor() {
5548
- super(...arguments);
5549
- this.type = "boolean";
5550
- }
5551
- }
5552
- class AMFDoubleTypeImpl extends AMFEnumerableScalarType {
5553
- constructor() {
5554
- super(...arguments);
5555
- this.type = "double";
5556
- }
5557
- }
5558
- class AMFIntegerTypeImpl extends AMFEnumerableScalarType {
5559
- constructor() {
5560
- super(...arguments);
5561
- this.type = "integer";
5562
- }
5563
- }
5564
- class AMFNumberTypeImpl extends AMFEnumerableScalarType {
5565
- constructor() {
5566
- super(...arguments);
5567
- this.type = "number";
5568
- }
5569
- }
5570
- class AMFStringTypeImpl extends AMFEnumerableScalarType {
5571
- constructor() {
5572
- super(...arguments);
5573
- this.type = "string";
5574
- }
5575
- }
5576
- class AMFDateTypeImpl extends AMFEnumerableScalarType {
5577
- constructor() {
5578
- super(...arguments);
5579
- this.type = "date";
5580
- }
5581
- }
5582
- const DATE = "date";
5583
- const DATE_TIME = "date-time";
5584
- class AMFDateTimeImpl extends AMFEnumerableScalarType {
5585
- constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
5586
- super(api, shape, typeRegistry, factory, logger, fileParserLogger);
5587
- this.shape = shape;
5588
- this.type = "datetime";
5589
- const formatValue = shape.format.value();
5590
- this.format = formatValue === DATE ? DATE : DATE_TIME;
5591
- }
5592
- }
5593
- class AMFOneOfTypeImpl extends AMFBaseType {
5594
- constructor() {
5595
- super(...arguments);
5596
- this.type = "oneOf";
5597
- this.oneOf = [];
5598
- }
5599
- typeResolve() {
5600
- var _a;
5601
- let { anyOf = [], xone = [] } = this.shape;
5602
- this.oneOf = [...anyOf, ...xone].map((subTypeShape) => {
5603
- const subType = this.factory(
5604
- this.api,
5605
- subTypeShape,
5606
- this.typeRegistry,
5607
- this.logger,
5608
- this.fileParserLogger
5609
- );
5610
- subType.resolve();
5611
- return subType;
5612
- });
5613
- if (((_a = this.shape.values) == null ? void 0 : _a.length) > 0) {
5614
- this.values = getEnumValuesFromShape(this.shape);
5615
- }
5616
- this.preserveIdentifiableExtensionsFromNullablePattern();
5617
- }
5618
- /**
5619
- * When AMF encounters 'nullable: true' on an object with identifiable extensions,
5620
- * it converts it to a oneOf with [object, null]. This method detects this pattern
5621
- * and preserves the identifiable extensions from the object member on the union.
5622
- */
5623
- preserveIdentifiableExtensionsFromNullablePattern() {
5624
- var _a;
5625
- if (this.oneOf.length !== 2) {
5626
- return;
5627
- }
5628
- const nullMember = this.oneOf.find((member) => member.type === "nil");
5629
- const objectMember = this.oneOf.find((member) => member.type === "object");
5630
- if (!nullMember || !objectMember) {
5631
- return;
5632
- }
5633
- if (((_a = objectMember.extensions) == null ? void 0 : _a.type) === "identifiable") {
5634
- this.parsedExtensions = { ...objectMember.extensions };
6177
+ function AmfGraphQLOperationMixin(Base) {
6178
+ return class AmfGraphQLOperation extends Base {
6179
+ constructor(...args) {
6180
+ super(...args);
6181
+ this.operationType = "graphql";
6182
+ this.graphqlConfig = this.setupGraphQLConfig();
5635
6183
  }
5636
- }
5637
- }
5638
- class AMFEnumTypeImpl extends AMFBaseType {
5639
- constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
5640
- super(api, shape, typeRegistry, factory, logger, fileParserLogger);
5641
- this.shape = shape;
5642
- this.typeRegistry = typeRegistry;
5643
- this.factory = factory;
5644
- this.logger = logger;
5645
- this.fileParserLogger = fileParserLogger;
5646
- this.type = "enum";
5647
- this.values = [];
5648
- this.values = getEnumValuesFromShape(shape);
5649
- }
5650
- }
5651
- class AMFRefTypeImpl extends AMFBaseType {
5652
- constructor() {
5653
- super(...arguments);
5654
- this.type = "ref";
5655
- this.$ref = {
5656
- type: "not",
5657
- not: { type: "any" }
5658
- };
5659
- this.resolved = false;
5660
- }
5661
- typeResolve() {
5662
- this.logger.trace(`Resolving $ref at ${this.shape.id.split("#")[1]}`);
5663
- if (this.shape.isLink && this.shape.linkTarget) {
5664
- const inheritedType = this.typeRegistry.get(this.shape.linkLabel.toString());
5665
- if (inheritedType) {
5666
- this.logger.trace(`Found ${inheritedType.shape.name} for $ref`);
5667
- inheritedType.resolve();
5668
- this.$ref = inheritedType;
5669
- } else {
5670
- const errorMessage = `Failed to resolve $ref: ${this.shape.linkLabel.toString()} from ${this.shape.id}`;
5671
- this.fileParserLogger.error(this.shapePosition, errorMessage);
5672
- throw new Error(errorMessage);
6184
+ setupGraphQLConfig() {
6185
+ const extensionsRaw = extractExtensions(this.amfOperation.customDomainProperties);
6186
+ const extensionsResult = this.operationSchemaBuilder.buildGraphQLOperationSchema().safeParse(extensionsRaw);
6187
+ if (!extensionsResult.success) {
6188
+ const message = formatZodError(extensionsResult.error);
6189
+ this.fileParserLogger.error(
6190
+ this.amfOperation.position.start,
6191
+ `Error validating graphql operation:
6192
+ ${message}`
6193
+ );
6194
+ throw new Error(message);
5673
6195
  }
6196
+ const extensions = extensionsResult.data;
6197
+ const config = {
6198
+ schemaFilePath: extensions.onestore.config.graphql.schema,
6199
+ "type-metadata": extensions.onestore.config.graphql["type-metadata"]
6200
+ };
6201
+ return config;
5674
6202
  }
5675
- }
6203
+ };
5676
6204
  }
5677
- class AMFDiscriminatedObjectTypeImpl extends AMFBaseType {
5678
- constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
5679
- super(api, shape, typeRegistry, factory, logger, fileParserLogger);
5680
- this.shape = shape;
5681
- this.typeRegistry = typeRegistry;
5682
- this.factory = factory;
5683
- this.logger = logger;
5684
- this.fileParserLogger = fileParserLogger;
5685
- this.type = "discriminatedObject";
5686
- this._mapping = void 0;
5687
- if (this.shape.discriminator.isNullOrEmpty) {
5688
- this.fileParserLogger.error(
5689
- this.shapePosition,
5690
- "Supplied shape does not provide a discriminator"
6205
+ const endpointSchema = z.object({
6206
+ onestore: z.discriminatedUnion("endpoint-type", [
6207
+ z.object({
6208
+ "endpoint-type": z.literal("http")
6209
+ }).strict(),
6210
+ z.object({
6211
+ "endpoint-type": z.literal("aura"),
6212
+ config: z.object({
6213
+ aura: z.object({
6214
+ controller: z.string()
6215
+ })
6216
+ }),
6217
+ "network-preference": z.enum(["aura", "http"]).default("aura")
6218
+ }).strict()
6219
+ ]).optional()
6220
+ });
6221
+ const partialOperationSchema = z.object({
6222
+ onestore: z.object({
6223
+ config: z.object({
6224
+ "operation-type": z.enum(["query", "mutation", "graphql"]).optional()
6225
+ }).passthrough().optional()
6226
+ }).passthrough().optional()
6227
+ });
6228
+ function createAmfAuraEndpoint(amfEndpoint, amfTypeFactory2, typeRegistry, logger, fileParserLogger, server, api, networkPreference) {
6229
+ const endpoint = new AmfAuraEndpoint(
6230
+ amfEndpoint,
6231
+ [],
6232
+ amfTypeFactory2,
6233
+ typeRegistry,
6234
+ logger,
6235
+ fileParserLogger,
6236
+ api,
6237
+ networkPreference
6238
+ );
6239
+ const operations = amfEndpoint.operations.map((operation) => {
6240
+ var _a, _b;
6241
+ const extensionsRaw = extractExtensions(operation.customDomainProperties);
6242
+ const operationConfigValidationResult = partialOperationSchema.safeParse(extensionsRaw);
6243
+ if (!operationConfigValidationResult.success) {
6244
+ const message = formatZodError(operationConfigValidationResult.error);
6245
+ fileParserLogger.error(
6246
+ operation.position.start,
6247
+ `Errors validating operation:
6248
+ ${message}`
5691
6249
  );
5692
6250
  throw new Error();
5693
6251
  }
5694
- this.discriminator = this.shape.discriminator.value();
5695
- this.baseType = factory(
5696
- api,
5697
- shape,
6252
+ const hasRequestBody = operation.requests.some((request) => request.payloads.length > 0);
6253
+ const isGraphQLOperation = ((_b = (_a = operationConfigValidationResult.data.onestore) == null ? void 0 : _a.config) == null ? void 0 : _b["operation-type"]) === "graphql";
6254
+ let baseClass = isGraphQLOperation ? AmfGraphQLOperationMixin(
6255
+ hasRequestBody ? AmfAuraOperationWithRequestBody : AmfAuraOperation
6256
+ ) : hasRequestBody ? AmfAuraOperationWithRequestBody : AmfAuraOperation;
6257
+ return new baseClass(
6258
+ operation,
6259
+ amfTypeFactory2,
5698
6260
  typeRegistry,
5699
6261
  logger,
5700
6262
  fileParserLogger,
5701
- false,
5702
- /* @__PURE__ */ new Set(["object"])
6263
+ endpoint,
6264
+ server
5703
6265
  );
5704
- }
5705
- typeResolve() {
5706
- this.baseType.resolve();
5707
- if (this.typeRegistry.nameOf(this) === void 0) {
5708
- this.fileParserLogger.error(
5709
- this.shapePosition,
5710
- "Cannot use discriminator on inline types."
5711
- );
5712
- throw new Error();
6266
+ });
6267
+ endpoint.operations = operations;
6268
+ return endpoint;
6269
+ }
6270
+ function createAmfHttpEndpoint(amfEndpoint, amfTypeFactory2, typeRegistry, logger, fileParserLogger, server, api) {
6271
+ const endpoint = new AmfHttpEndPoint(
6272
+ amfEndpoint,
6273
+ [],
6274
+ amfTypeFactory2,
6275
+ typeRegistry,
6276
+ logger,
6277
+ fileParserLogger,
6278
+ api
6279
+ );
6280
+ const operations = amfEndpoint.operations.map((operation) => {
6281
+ var _a, _b;
6282
+ const operationConfigValidationResult = partialOperationSchema.safeParse(
6283
+ extractExtensions(operation.customDomainProperties)
6284
+ );
6285
+ if (!operationConfigValidationResult.success) {
6286
+ const message = formatZodError(operationConfigValidationResult.error);
6287
+ const errorMessage = `Error validating operation:
6288
+ ${message}`;
6289
+ fileParserLogger.error(operation.position.start, errorMessage);
6290
+ throw new Error(errorMessage);
5713
6291
  }
5714
- }
5715
- get mapping() {
5716
- if (this._mapping === void 0) {
5717
- this._mapping = {};
5718
- this.resolveDiscriminator();
5719
- }
5720
- return this._mapping;
5721
- }
5722
- resolveDiscriminator() {
5723
- this.buildExplicitMapping();
5724
- this.buildImplicitMapping();
5725
- }
5726
- /**
5727
- * Adds implicit discriminator values (i.e., type names) as mappings to types
5728
- *
5729
- * @private
5730
- */
5731
- buildImplicitMapping() {
5732
- const oneOfNames = this.shape.xone.reduce((result, shape) => {
5733
- if (shape.isLink) {
5734
- result.push(shape.linkLabel.value());
5735
- }
5736
- return result;
5737
- }, []);
5738
- this.typeRegistry.forEach((type, name) => {
5739
- type.resolve();
5740
- if ((type.type === "allOf" && type.includes(this) || oneOfNames.includes(name)) && !Object.values(this._mapping).includes(type)) {
5741
- this._mapping[name] = type;
5742
- }
5743
- });
5744
- }
5745
- /**
5746
- * Adds explicit discriminator values as mappings to types
5747
- *
5748
- * @private
5749
- */
5750
- buildExplicitMapping() {
5751
- this.shape.discriminatorMapping.forEach((el) => {
5752
- const value = el.templateVariable.value();
5753
- const linkExpressionSplit = el.linkExpression.value().split("/");
5754
- const typeName = linkExpressionSplit[linkExpressionSplit.length - 1];
5755
- const type = this.typeRegistry.get(typeName);
5756
- if (type === void 0) {
5757
- this.fileParserLogger.error(this.shapePosition, `Cannot find type ${typeName}`);
5758
- throw new Error();
5759
- }
5760
- this._mapping[value] = type;
5761
- });
5762
- }
5763
- }
5764
- function amfTypeFactory(api, shape, typeRegistry, logger, fileParserLogger, resolve = false, allowedTypes = void 0, skipRegistry = false) {
5765
- var _a;
5766
- if (!skipRegistry) {
5767
- for (const [_, type] of typeRegistry.entries()) {
5768
- if (shape.id === type.shape.id) {
5769
- return type;
5770
- }
5771
- }
5772
- }
5773
- const { line = 0, column = 0 } = ((_a = shape.position) == null ? void 0 : _a.start) || {};
5774
- let ctor;
5775
- if (isAnyOfShape(shape)) {
5776
- fileParserLogger.error(
5777
- { line, column },
5778
- `anyOf is not suppoort, found in type ${shape.name.value()}`
5779
- );
5780
- throw new Error();
5781
- }
5782
- if (isRefShape(shape)) {
5783
- ctor = AMFRefTypeImpl;
5784
- } else if ((!allowedTypes || allowedTypes.has("allOf")) && isAllOfShape(shape)) {
5785
- ctor = AMFAllOfTypeImpl;
5786
- } else if ((!allowedTypes || allowedTypes.has("oneOf")) && isOneOfShape(shape)) {
5787
- ctor = AMFOneOfTypeImpl;
5788
- } else if ((!allowedTypes || allowedTypes.has("enum")) && isEnumShape(shape)) {
5789
- ctor = AMFEnumTypeImpl;
5790
- } else if ((!allowedTypes || allowedTypes.has("nil")) && isNilShape(shape)) {
5791
- ctor = AMFNilTypeImpl;
5792
- } else if (isScalarShape(shape) && shape.dataType.value() in DATATYPE_TO_SCALAR_TYPE && (!allowedTypes || allowedTypes.has(DATATYPE_TO_SCALAR_TYPE[shape.dataType.value()]))) {
5793
- const scalarType = DATATYPE_TO_SCALAR_TYPE[shape.dataType.value()];
5794
- switch (scalarType) {
5795
- case "string":
5796
- ctor = AMFStringTypeImpl;
5797
- break;
5798
- case "number":
5799
- ctor = AMFNumberTypeImpl;
5800
- break;
5801
- case "boolean":
5802
- ctor = AMFBooleanTypeImpl;
5803
- break;
5804
- case "double":
5805
- ctor = AMFDoubleTypeImpl;
5806
- break;
5807
- case "integer":
5808
- ctor = AMFIntegerTypeImpl;
5809
- break;
5810
- case "date":
5811
- ctor = AMFDateTypeImpl;
5812
- break;
5813
- case "datetime":
5814
- ctor = AMFDateTimeImpl;
5815
- break;
5816
- default:
5817
- fileParserLogger.error(
5818
- { line, column },
5819
- `type of shape ${shape.name.value()} not recognized`
5820
- );
5821
- throw new Error();
5822
- }
5823
- } else if ((!allowedTypes || allowedTypes.has("discriminatedObject")) && isNodeShape(shape) && !shape.discriminator.isNullOrEmpty) {
5824
- ctor = AMFDiscriminatedObjectTypeImpl;
5825
- } else if ((!allowedTypes || allowedTypes.has("object")) && isNodeShape(shape)) {
5826
- ctor = AMFObjectTypeImpl;
5827
- } else if ((!allowedTypes || allowedTypes.has("array")) && isArrayShape(shape)) {
5828
- ctor = AMFArrayTypeImpl;
5829
- } else if ((!allowedTypes || allowedTypes.has("not")) && isNotShape(shape)) {
5830
- ctor = AMFNotTypeImpl;
5831
- } else if ((!allowedTypes || allowedTypes.has("any")) && isAnyShape(shape)) {
5832
- ctor = AMFAnyTypeImpl;
5833
- } else {
5834
- fileParserLogger.error(
5835
- { line, column },
5836
- `type of shape ${shape.name.value()} not recognized`
6292
+ const hasRequestBody = operation.requests.some((request) => request.payloads.length > 0);
6293
+ const isGraphQLOperation = ((_b = (_a = operationConfigValidationResult.data.onestore) == null ? void 0 : _a.config) == null ? void 0 : _b["operation-type"]) === "graphql";
6294
+ let baseClass = isGraphQLOperation ? AmfGraphQLOperationMixin(
6295
+ hasRequestBody ? AmfHttpOperationWithRequestBody : AmfHttpOperation
6296
+ ) : hasRequestBody ? AmfHttpOperationWithRequestBody : AmfHttpOperation;
6297
+ return new baseClass(
6298
+ operation,
6299
+ amfTypeFactory2,
6300
+ typeRegistry,
6301
+ logger,
6302
+ fileParserLogger,
6303
+ endpoint,
6304
+ server
5837
6305
  );
5838
- throw new Error();
5839
- }
5840
- const result = new ctor(api, shape, typeRegistry, amfTypeFactory, logger, fileParserLogger);
5841
- if (resolve) {
5842
- result.resolve();
5843
- }
5844
- return result;
6306
+ });
6307
+ endpoint.operations = operations;
6308
+ return endpoint;
5845
6309
  }
5846
- class AMFArrayTypeImpl extends AMFBaseType {
5847
- constructor() {
5848
- super(...arguments);
5849
- this.type = "array";
5850
- this.items = { type: "any" };
6310
+ function amfEndpointFactory(amfEndpoint, amfTypeFactory2, typeRegistry, logger, fileParserLogger, server, api) {
6311
+ const endpointConfigValidationResult = endpointSchema.safeParse(
6312
+ extractExtensions(amfEndpoint.customDomainProperties)
6313
+ );
6314
+ if (!endpointConfigValidationResult.success) {
6315
+ const message = formatZodError(endpointConfigValidationResult.error);
6316
+ const errorMessage = `Error validating endpoint:
6317
+ ${message}`;
6318
+ fileParserLogger.error(amfEndpoint.position.start, errorMessage);
6319
+ throw new Error(errorMessage);
5851
6320
  }
5852
- typeResolve() {
5853
- if (this.shape.items) {
5854
- const items = amfTypeFactory(
5855
- this.api,
5856
- this.shape.items,
5857
- this.typeRegistry,
5858
- this.logger,
5859
- this.fileParserLogger
5860
- );
5861
- items.resolve();
5862
- this.items = items;
5863
- }
6321
+ const config = endpointConfigValidationResult.data;
6322
+ if (config.onestore === void 0) {
6323
+ return void 0;
6324
+ }
6325
+ const endpoint = config.onestore["endpoint-type"] === "aura" ? createAmfAuraEndpoint(
6326
+ amfEndpoint,
6327
+ amfTypeFactory2,
6328
+ typeRegistry,
6329
+ logger,
6330
+ fileParserLogger,
6331
+ server,
6332
+ api,
6333
+ config.onestore["network-preference"]
6334
+ ) : createAmfHttpEndpoint(
6335
+ amfEndpoint,
6336
+ amfTypeFactory2,
6337
+ typeRegistry,
6338
+ logger,
6339
+ fileParserLogger,
6340
+ server,
6341
+ api
6342
+ );
6343
+ if (!validateUniqueBindingIdentfiers(endpoint.operations)) {
6344
+ const errorMessage = `All operations must have unique bindings`;
6345
+ fileParserLogger.error(amfEndpoint.position.start, errorMessage);
6346
+ throw new Error(errorMessage);
5864
6347
  }
6348
+ return endpoint;
5865
6349
  }
5866
- const serviceVariantDescriptorSchema = z.object({
5867
- type: z.string(),
5868
- version: z.string(),
5869
- tags: z.record(z.string(), z.string()).optional(),
5870
- default: z.boolean().optional()
5871
- }).strict();
5872
- const servicesCatalogSchema = z.record(z.string(), serviceVariantDescriptorSchema);
5873
- const operationServiceRefSchema = z.object({
5874
- ref: z.string()
5875
- }).strict();
5876
- const operationServiceInlineSchema = z.object({
5877
- version: z.string(),
5878
- tags: z.record(z.string(), z.string()).optional(),
5879
- // Capture but disallow to provide a clearer error
5880
- optional: z.boolean().optional()
5881
- }).strict().superRefine((val, ctx) => {
5882
- if (val.optional !== void 0) {
5883
- ctx.addIssue({
5884
- code: z.ZodIssueCode.custom,
5885
- path: ["optional"],
5886
- message: "optional is not allowed for service overrides"
6350
+ class AmfBaseEndpoint {
6351
+ constructor(amfEndpoint, operations, amfTypeFactory2, typeRegistry, logger, fileParserLogger, api) {
6352
+ this.amfEndpoint = amfEndpoint;
6353
+ this.operations = operations;
6354
+ this.logger = logger;
6355
+ this.fileParserLogger = fileParserLogger;
6356
+ this.api = api;
6357
+ this.path = this.amfEndpoint.path.value();
6358
+ this.uriParameters = {};
6359
+ this.amfEndpoint.parameters.forEach((param) => {
6360
+ this.uriParameters[`${param.name}`] = {
6361
+ required: param.required.value(),
6362
+ type: amfTypeFactory2(
6363
+ this.api,
6364
+ param.schema,
6365
+ typeRegistry,
6366
+ logger,
6367
+ fileParserLogger,
6368
+ true
6369
+ ),
6370
+ explode: param.explode.value()
6371
+ };
5887
6372
  });
5888
6373
  }
5889
- });
5890
- const operationServicesSchema = z.record(
5891
- z.string(),
5892
- z.union([operationServiceRefSchema, operationServiceInlineSchema])
5893
- );
5894
- const componentsOnestoreServicesSchema = z.object({ onestore: z.object({ services: servicesCatalogSchema }).strict() }).strict();
5895
- const operationOnestoreServicesSchema = z.object({ onestore: z.object({ services: operationServicesSchema }).strict() }).strict();
5896
- function validateAndNormalizeCatalog(catalog) {
5897
- const parsed = servicesCatalogSchema.safeParse(catalog);
5898
- if (!parsed.success) {
5899
- throw new Error(parsed.error.message);
5900
- }
5901
- const defaultsByType = {};
5902
- for (const [alias, descriptor] of Object.entries(parsed.data)) {
5903
- if (descriptor.default) {
5904
- const prior = defaultsByType[descriptor.type];
5905
- if (prior !== void 0 && prior !== alias) {
5906
- throw new Error(
5907
- `Multiple defaults defined for service type '${descriptor.type}': '${prior}' and '${alias}'`
5908
- );
5909
- }
5910
- defaultsByType[descriptor.type] = alias;
5911
- }
5912
- }
5913
- return { catalog: parsed.data, defaultsByType };
5914
- }
5915
- function resolveOperationServices(services, catalog) {
5916
- const result = {};
5917
- for (const [canonicalName, entry] of Object.entries(services)) {
5918
- if ("ref" in entry) {
5919
- const alias = entry.ref;
5920
- const descriptor = catalog == null ? void 0 : catalog.catalog[alias];
5921
- if (!descriptor) {
5922
- throw new Error(`ref '${alias}' does not exist in the catalog`);
5923
- } else if (descriptor.default) {
5924
- throw new Error(`ref is not required for default service '${alias}'`);
5925
- } else if (descriptor.type !== canonicalName) {
5926
- throw new Error(
5927
- `Service '${alias}' uses non-canonical type '${descriptor.type}'. Expected canonical type '${canonicalName}'`
5928
- );
5929
- }
5930
- result[canonicalName] = {
5931
- type: descriptor.type,
5932
- version: descriptor.version,
5933
- tags: descriptor.tags
5934
- };
5935
- } else {
5936
- const inline = entry;
5937
- result[canonicalName] = {
5938
- type: canonicalName,
5939
- version: inline.version,
5940
- tags: inline.tags
5941
- };
5942
- }
5943
- }
5944
- return result;
5945
- }
5946
- function resolveDefaultServiceOverrides(catalog) {
5947
- const result = {};
5948
- if (catalog) {
5949
- for (const [alias, type] of Object.entries(catalog.defaultsByType)) {
5950
- const entry = catalog.catalog[type];
5951
- if (entry && !result[entry.type]) {
5952
- result[entry.type] = {
5953
- type: entry.type,
5954
- version: entry.version,
5955
- tags: entry.tags
5956
- };
5957
- } else {
5958
- throw new Error(
5959
- `Missing or multiple default service overrides for service ${alias}`
5960
- );
5961
- }
5962
- }
5963
- }
5964
- return result;
5965
- }
5966
- const cacheInvalidationEntrySchema = z.object({
5967
- ref: z.string(),
5968
- key: z.record(z.string(), z.string())
5969
- });
5970
- const cacheInvalidationSchema = z.object({
5971
- onestore: z.object({
5972
- invalidate: z.array(cacheInvalidationEntrySchema)
5973
- })
5974
- });
5975
- class OperationSchemaBuilder {
5976
- constructor(method, operationId, operationCacheStrategyType) {
5977
- this.method = method;
5978
- this.operationId = operationId;
5979
- this.operationCacheStrategyType = operationCacheStrategyType;
5980
- }
5981
- buildOperationSchema() {
5982
- const bindingSchema = z.object({
5983
- type: z.enum(BindingTypesEnum).default("wire"),
5984
- identifier: z.string().default("")
5985
- });
5986
- const configSchema = z.object({
5987
- "operation-type": z.enum(["query", "mutation", "graphql"]).default(this.method === "GET" ? "query" : "mutation"),
5988
- schema: z.enum(["flattened", "default"]).default("default"),
5989
- bindings: z.array(bindingSchema).default([]),
5990
- exposeRefresh: z.boolean().default(false),
5991
- "body-param": z.string().optional()
5992
- }).default({}).transform((config, ctx) => {
5993
- const { bindings, "operation-type": operationType } = config;
5994
- if (bindings.length === 0) {
5995
- if (!this.operationId) {
5996
- ctx.addIssue({
5997
- code: z.ZodIssueCode.custom,
5998
- message: `operationId is required for adapter name generation when no explicit bindings defined for operation. Add an operationId or expicit bindings annotation.`
5999
- });
6000
- return config;
6001
- }
6002
- if (operationType === "graphql") {
6003
- config.bindings = [{ type: "wire", identifier: this.operationId }];
6004
- return config;
6005
- } else {
6006
- const bindingType = operationType === "query" ? "wire" : "imperative";
6007
- config.bindings = [{ type: bindingType, identifier: this.operationId }];
6008
- }
6009
- } else if (bindings.length === 1) {
6010
- if (!bindings[0].identifier) {
6011
- if (!this.operationId) {
6012
- ctx.addIssue({
6013
- code: z.ZodIssueCode.custom,
6014
- message: `operationId is required for adapter name generation when one explicit binding is requested without an identifier. Add an operationId or a binding identifier.`
6015
- });
6016
- return config;
6017
- }
6018
- bindings[0].identifier = this.operationId;
6019
- }
6020
- }
6021
- return config;
6022
- }).refine(
6023
- (config) => {
6024
- const { bindings, "operation-type": operationType } = config;
6025
- if (operationType === "mutation") {
6026
- return !bindings.some(
6027
- (binding) => binding.type === "wire" || binding.type === "imperative-legacy"
6028
- );
6029
- }
6030
- return true;
6031
- },
6032
- {
6033
- message: 'Cannot use "wire" or "imperative-legacy" binding with operation-type "mutation"'
6034
- }
6035
- ).refine(
6036
- (config) => {
6037
- const { "operation-type": operationType, exposeRefresh } = config;
6038
- return !(exposeRefresh && operationType === "mutation");
6039
- },
6040
- {
6041
- message: 'Cannot exposeRefresh with operation-type "mutation"'
6042
- }
6043
- ).refine(
6044
- (config) => {
6045
- const { bindings, exposeRefresh } = config;
6046
- if (exposeRefresh) {
6047
- return !bindings.some((binding) => binding.type === "imperative-legacy");
6048
- }
6049
- return true;
6050
- },
6051
- {
6052
- message: 'Cannot exposeRefresh with "imperative-legacy" binding'
6053
- }
6054
- ).refine(
6055
- (config) => {
6056
- const { bindings } = config;
6057
- if (bindings.length <= 1) {
6058
- return true;
6059
- }
6060
- return bindings.every((binding) => !!binding.identifier);
6061
- },
6062
- {
6063
- message: "Binding identifier is required if more than one binding is provided."
6064
- }
6065
- ).refine(
6066
- (config) => {
6067
- const { bindings } = config;
6068
- if (bindings.length <= 1) {
6069
- return true;
6070
- }
6071
- const identifiers = bindings.map((binding) => binding.identifier);
6072
- return new Set(identifiers).size === identifiers.length;
6073
- },
6074
- { message: "Binding identifier must be unique" }
6075
- ).refine(
6076
- (config) => {
6077
- const { bindings, "operation-type": operationType } = config;
6078
- if (operationType !== "graphql") {
6079
- return !bindings.some((binding) => binding.type === "mutation");
6080
- }
6081
- return true;
6082
- },
6083
- {
6084
- message: 'Cannot use "mutation" binding with non-graphql operations'
6085
- }
6086
- ).superRefine((config, ctx) => {
6087
- config.bindings.forEach((binding) => {
6088
- const tsSafeIdentifier = toTypeScriptSafeIdentifier(binding.identifier);
6089
- if (binding.identifier !== tsSafeIdentifier) {
6090
- ctx.addIssue({
6091
- code: z.ZodIssueCode.custom,
6092
- message: `Invalid identifier "${binding.identifier}" for adapter binding. This may be derived from operationId. Use a valid TypeScript variable name, e.g. '${tsSafeIdentifier}'.`
6093
- });
6094
- }
6095
- });
6096
- });
6097
- return z.object({
6098
- onestore: z.object({
6099
- config: configSchema,
6100
- "cache-strategy": operationCacheStrategy(this.operationCacheStrategyType),
6101
- "error-strategy": z.discriminatedUnion("type", [
6102
- z.object({ type: z.literal("stringified") }).strict(),
6103
- z.object({ type: z.literal("fetchResponse") }).strict()
6104
- ]).default({ type: "stringified" }),
6105
- services: operationServicesSchema.optional()
6106
- }).strict().default({}).transform((extensions) => {
6107
- var _a;
6108
- if (((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized" && extensions.config["operation-type"] === "mutation") {
6109
- if (extensions["cache-strategy"]["cache-control"] === void 0) {
6110
- extensions["cache-strategy"]["cache-control"] = {
6111
- type: "no-cache"
6112
- };
6113
- }
6114
- }
6115
- return extensions;
6116
- }).refine(
6117
- (extensions) => {
6118
- var _a;
6119
- if (((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized") {
6120
- const cacheControl2 = extensions["cache-strategy"]["cache-control"];
6121
- if (extensions.config["operation-type"] === "mutation" && cacheControl2) {
6122
- return cacheControl2.type === "no-cache";
6123
- }
6124
- }
6125
- return true;
6126
- },
6127
- {
6128
- message: 'Cannot use "cache-control" values other than "no-cache" with operation-type "mutation"'
6129
- }
6130
- ).refine(
6131
- (extensions) => {
6132
- var _a;
6133
- if (((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized") {
6134
- if (extensions.config["operation-type"] === "query") {
6135
- return extensions["cache-strategy"]["cache-control"] !== void 0;
6136
- }
6137
- }
6138
- return true;
6139
- },
6140
- {
6141
- message: 'Cannot use undefined "cache-control" with operation-type "query"'
6142
- }
6143
- ).refine(
6144
- (extensions) => {
6145
- var _a;
6146
- if (extensions.config["operation-type"] === "graphql") {
6147
- return ((_a = extensions["cache-strategy"]) == null ? void 0 : _a.type) === "normalized";
6148
- }
6149
- return true;
6150
- },
6151
- {
6152
- message: "GraphQL operations must use normalized cache strategy"
6153
- }
6154
- )
6155
- });
6156
- }
6157
- buildHttpOperationSchema() {
6158
- return this.buildOperationSchema().transform((config, _ctx) => {
6159
- let bodyParam = config.onestore.config["body-param"] === void 0 ? "inputPayload" : config.onestore.config["body-param"];
6160
- return {
6161
- onestore: {
6162
- config: {
6163
- ...config.onestore.config,
6164
- "body-param": bodyParam
6165
- }
6166
- }
6167
- };
6168
- });
6169
- }
6170
- buildAuraOperationSchema() {
6171
- return this.buildOperationSchema().and(
6172
- z.object({
6173
- onestore: z.object({
6174
- config: z.object({
6175
- aura: z.object({
6176
- method: z.string()
6177
- })
6178
- })
6179
- })
6180
- })
6181
- );
6182
- }
6183
- buildAuraOperationWithBodySchema() {
6184
- return this.buildAuraOperationSchema().and(
6185
- z.object({
6186
- onestore: z.object({
6187
- config: z.object({
6188
- aura: z.object({
6189
- "body-param": z.string().optional()
6190
- })
6191
- })
6192
- })
6193
- })
6194
- ).transform((config, ctx) => {
6195
- let topLevelParam = config.onestore.config["body-param"];
6196
- let auraParam = config.onestore.config.aura["body-param"];
6197
- if (topLevelParam === void 0 && auraParam === void 0) {
6198
- ctx.addIssue({
6199
- code: z.ZodIssueCode.custom,
6200
- message: "Missing body-param in both x-onestore.config and x-onestore.config.aura."
6201
- });
6202
- return z.NEVER;
6203
- }
6204
- if (topLevelParam !== void 0 && auraParam !== void 0) {
6205
- return config;
6206
- }
6207
- if (topLevelParam === void 0) {
6208
- topLevelParam = auraParam;
6209
- }
6210
- if (auraParam === void 0) {
6211
- auraParam = topLevelParam;
6212
- }
6213
- return {
6214
- onestore: {
6215
- config: {
6216
- ...config.onestore.config,
6217
- "body-param": topLevelParam,
6218
- aura: {
6219
- ...config.onestore.config.aura,
6220
- "body-param": auraParam
6221
- }
6222
- }
6223
- }
6224
- };
6225
- });
6374
+ }
6375
+ class AmfHttpEndPoint extends AmfBaseEndpoint {
6376
+ constructor() {
6377
+ super(...arguments);
6378
+ this.type = "http";
6226
6379
  }
6227
- buildGraphQLOperationSchema() {
6228
- return this.buildOperationSchema().and(
6229
- z.object({
6230
- onestore: z.object({
6231
- config: z.object({
6232
- graphql: z.object({
6233
- schema: z.string(),
6234
- "type-metadata": z.array(
6235
- z.object({
6236
- typename: z.string(),
6237
- "cache-control": cacheControl
6238
- })
6239
- ).default([])
6240
- })
6241
- })
6242
- })
6243
- })
6380
+ }
6381
+ class AmfAuraEndpoint extends AmfBaseEndpoint {
6382
+ constructor(amfEndPoint, operations, amfTypeFactory2, typeRegistry, logger, fileParserLogger, api, networkPreference) {
6383
+ super(amfEndPoint, operations, amfTypeFactory2, typeRegistry, logger, fileParserLogger, api);
6384
+ this.logger = logger;
6385
+ this.fileParserLogger = fileParserLogger;
6386
+ this.api = api;
6387
+ this.networkPreference = networkPreference;
6388
+ this.type = "aura";
6389
+ this.auraController = this.buildAuraController();
6390
+ }
6391
+ buildAuraController() {
6392
+ const configResult = endpointSchema.safeParse(
6393
+ extractExtensions(this.amfEndpoint.customDomainProperties)
6244
6394
  );
6395
+ if (!configResult.success) {
6396
+ const message = formatZodError(configResult.error);
6397
+ const errorMessage = `Error validating aura endpoint:
6398
+ ${message}`;
6399
+ this.fileParserLogger.error(this.amfEndpoint.position.start, errorMessage);
6400
+ throw new Error(errorMessage);
6401
+ }
6402
+ const config = configResult.data;
6403
+ if (!config.onestore || config.onestore["endpoint-type"] !== "aura") {
6404
+ throw new Error("invalid config");
6405
+ }
6406
+ const name = config.onestore.config.aura.controller;
6407
+ if (name === void 0) {
6408
+ throw new Error("Aura controller name must be defined for an Aura endpoint.");
6409
+ }
6410
+ return { name };
6245
6411
  }
6246
6412
  }
6247
- class AmfBaseOperation {
6248
- constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6249
- this.amfOperation = amfOperation;
6250
- this.amfTypeFactory = amfTypeFactory2;
6413
+ const annotationSchema = z.object({
6414
+ onestore: typeExtensions.optional()
6415
+ });
6416
+ class AMFBaseType {
6417
+ constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
6418
+ var _a;
6419
+ this.api = api;
6420
+ this.shape = shape;
6251
6421
  this.typeRegistry = typeRegistry;
6422
+ this.factory = factory;
6252
6423
  this.logger = logger;
6253
6424
  this.fileParserLogger = fileParserLogger;
6254
- this.endpoint = endpoint;
6255
- this.server = server;
6256
- this.defaults = endpoint.api.defaults;
6257
- this.method = this.amfOperation.method.value().toUpperCase();
6258
- this.position = {
6259
- line: this.amfOperation.position.lineFrom.valueOf(),
6260
- column: this.amfOperation.position.columnFrom.valueOf()
6261
- };
6262
- const extensionsRaw = extractExtensions(this.amfOperation.customDomainProperties);
6263
- this.operationId = this.amfOperation.operationId.value() || this.amfOperation.name.value();
6264
- this.operationSchemaBuilder = new OperationSchemaBuilder(
6265
- this.method,
6266
- this.operationId,
6267
- this.defaults.operationCacheStrategy
6268
- );
6269
- const extensionsResult = this.operationSchemaBuilder.buildOperationSchema().default({}).safeParse(extensionsRaw);
6270
- if (!extensionsResult.success) {
6271
- const message = formatZodError(extensionsResult.error);
6272
- this.fileParserLogger.error(
6273
- this.amfOperation.position.start,
6274
- `Error validating operation:
6275
- ${message}`
6276
- );
6277
- throw new Error(`Error validating operation:
6278
- ${message}`);
6279
- }
6280
- const extensions = extensionsResult.data;
6281
- this.operationType = extensions.onestore.config["operation-type"];
6282
- this.configSchemaType = extensions.onestore.config.schema;
6283
- this.bindings = extensions.onestore.config.bindings;
6284
- this.exposeRefresh = extensions.onestore.config.exposeRefresh;
6285
- this.parsedCacheStrategy = extensions.onestore["cache-strategy"];
6286
- this.errorStrategy = extensions.onestore["error-strategy"];
6287
- this.basePath = this.endpoint.api.basePath;
6288
- if (extensions.onestore.services) {
6289
- this.serviceOverrides = resolveOperationServices(
6290
- extensions.onestore.services,
6291
- this.endpoint.api.serviceOverrides
6425
+ this.resolved = false;
6426
+ this.parsedExtensions = { type: "unidentifiable" };
6427
+ const { line = 0, column = 0 } = ((_a = this.shape.position) == null ? void 0 : _a.start) || {};
6428
+ this.shapePosition = { line, column };
6429
+ }
6430
+ resolve() {
6431
+ var _a;
6432
+ if (!this.resolved) {
6433
+ this.resolved = true;
6434
+ const annotationResult = annotationSchema.safeParse(
6435
+ extractExtensions(this.shape.customDomainProperties)
6292
6436
  );
6293
- } else {
6294
- this.serviceOverrides = {};
6295
- }
6296
- this.requests = this.amfOperation.requests.map((request) => {
6297
- return {
6298
- queryParameters: this.buildParams(request.queryParameters),
6299
- uriParameters: this.buildParams(request.uriParameters),
6300
- payloads: this.buildPayloads(request),
6301
- cookies: this.buildParams(request.cookieParameters),
6302
- headers: this.buildParams(request.headers)
6303
- };
6304
- });
6305
- this.responses = this.amfOperation.responses.map((response) => {
6306
- const extensionsRaw2 = extractExtensions(response.customDomainProperties);
6307
- if (extensionsRaw2.onestore !== void 0) {
6308
- const extensionsResult2 = cacheInvalidationSchema.safeParse(extensionsRaw2);
6309
- if (!extensionsResult2.success) {
6310
- const message = formatZodError(extensionsResult2.error);
6311
- this.fileParserLogger.error(
6312
- this.amfOperation.position.start,
6313
- `Error validating operation invalidation annotation:
6314
- ${message}`
6315
- );
6316
- throw new Error(
6317
- `Error validating operation invalidation annotation:
6437
+ if (!annotationResult.success) {
6438
+ const message = formatZodError(annotationResult.error);
6439
+ this.fileParserLogger.error(
6440
+ this.shape.position.start,
6441
+ `Errors validating type:
6318
6442
  ${message}`
6319
- );
6320
- }
6321
- const extensions2 = extensionsResult2.data;
6322
- if (Object.keys(extensions2.onestore.invalidate).length > 0 && this.operationType === "query") {
6323
- this.fileParserLogger.error(
6324
- this.position,
6325
- `Cannot use an invalidate extension on a query type adapter`
6326
- );
6327
- throw new Error();
6328
- }
6329
- return {
6330
- statusCode: response.statusCode.value(),
6331
- headers: this.buildParams(response.headers),
6332
- payloads: this.buildPayloads(response),
6333
- invalidation: extensions2.onestore.invalidate
6443
+ );
6444
+ throw new Error();
6445
+ }
6446
+ if ((_a = annotationResult.data.onestore) == null ? void 0 : _a.key) {
6447
+ this.parsedExtensions = {
6448
+ type: "identifiable",
6449
+ ...annotationResult.data.onestore
6334
6450
  };
6335
6451
  }
6336
- return {
6337
- statusCode: response.statusCode.value(),
6338
- headers: this.buildParams(response.headers),
6339
- payloads: this.buildPayloads(response)
6340
- };
6341
- });
6452
+ this.logger.trace("Running this types resolution");
6453
+ this.typeResolve();
6454
+ } else {
6455
+ this.logger.trace("Type was already resolved");
6456
+ }
6342
6457
  }
6343
- get cacheStrategy() {
6344
- return this.parsedCacheStrategy;
6458
+ /*
6459
+ Placeholder for type specific resolution
6460
+ */
6461
+ typeResolve() {
6345
6462
  }
6346
- buildPayloads(r) {
6347
- return r.payloads.map((payload) => {
6463
+ get extensions() {
6464
+ if (this.parsedExtensions.type === "identifiable") {
6465
+ const CACHE_CONTROL = "cache-control";
6466
+ const defaults = this.api.defaults.typeCacheControl;
6348
6467
  return {
6349
- mediaType: payload.mediaType.value(),
6350
- data: this.amfTypeFactory(
6351
- {},
6352
- payload.schema,
6353
- this.typeRegistry,
6354
- this.logger,
6355
- this.fileParserLogger,
6356
- true
6357
- )
6468
+ ...this.parsedExtensions,
6469
+ [CACHE_CONTROL]: {
6470
+ ...defaults,
6471
+ ...this.parsedExtensions[CACHE_CONTROL]
6472
+ }
6358
6473
  };
6359
- });
6474
+ } else {
6475
+ return this.parsedExtensions;
6476
+ }
6360
6477
  }
6361
- getDefaultValue(param) {
6362
- var _a, _b;
6363
- const defaultValue = (_a = param.schema) == null ? void 0 : _a.defaultValue;
6364
- if (defaultValue) {
6365
- return (_b = defaultValue.value) == null ? void 0 : _b.value();
6478
+ }
6479
+ class AMFAnyTypeImpl extends AMFBaseType {
6480
+ constructor() {
6481
+ super(...arguments);
6482
+ this.type = "any";
6483
+ }
6484
+ }
6485
+ class AMFObjectTypeImpl extends AMFBaseType {
6486
+ constructor() {
6487
+ super(...arguments);
6488
+ this.type = "object";
6489
+ this.properties = {};
6490
+ this.resolved = false;
6491
+ this.additionalProperties = { type: "any" };
6492
+ }
6493
+ typeResolve() {
6494
+ var _a;
6495
+ if (((_a = this.shape.values) == null ? void 0 : _a.length) > 0) {
6496
+ this.fileParserLogger.error(
6497
+ this.shapePosition,
6498
+ `Type Error (${this.shape.name.value()}). Object type may not specify enum property.`
6499
+ );
6500
+ throw new Error();
6501
+ }
6502
+ this.logger.trace("Resolving properties");
6503
+ this.resolveProperties();
6504
+ this.logger.trace("Resolving additional properties");
6505
+ this.resolveAdditionalProperties();
6506
+ }
6507
+ resolveProperties() {
6508
+ for (const property of this.shape.properties) {
6509
+ const propertyName = property.name.value();
6510
+ const type = this.factory(
6511
+ this.api,
6512
+ property.range,
6513
+ this.typeRegistry,
6514
+ this.logger,
6515
+ this.fileParserLogger,
6516
+ true
6517
+ );
6518
+ type.resolve();
6519
+ const propertyType = {
6520
+ type,
6521
+ required: property.minCount.value() !== 0
6522
+ };
6523
+ this.properties[propertyName] = propertyType;
6366
6524
  }
6367
6525
  }
6368
- buildParams(p) {
6369
- const params = {};
6370
- p.forEach((param) => {
6371
- params[`${param.name.value()}`] = {
6372
- required: param.required.value(),
6373
- type: this.amfTypeFactory(
6374
- {},
6375
- param.schema,
6376
- this.typeRegistry,
6377
- this.logger,
6378
- this.fileParserLogger,
6379
- true
6380
- ),
6381
- explode: param.explode.value(),
6382
- defaultValue: this.getDefaultValue(param)
6526
+ resolveAdditionalProperties() {
6527
+ if (this.shape.closed.value()) {
6528
+ this.additionalProperties = {
6529
+ type: "not",
6530
+ not: { type: "any" }
6383
6531
  };
6384
- });
6385
- return params;
6532
+ } else if (this.shape.additionalPropertiesSchema) {
6533
+ this.additionalProperties = this.factory(
6534
+ this.api,
6535
+ this.shape.additionalPropertiesSchema,
6536
+ this.typeRegistry,
6537
+ this.logger,
6538
+ this.fileParserLogger,
6539
+ true
6540
+ );
6541
+ }
6386
6542
  }
6387
6543
  }
6388
- class AmfHttpOperation extends AmfBaseOperation {
6544
+ class AMFNilTypeImpl extends AMFBaseType {
6389
6545
  constructor() {
6390
6546
  super(...arguments);
6391
- this.type = "http";
6547
+ this.type = "nil";
6392
6548
  }
6393
6549
  }
6394
- class AmfHttpOperationWithRequestBody extends AmfBaseOperation {
6395
- constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6396
- super(
6397
- amfOperation,
6398
- amfTypeFactory2,
6399
- typeRegistry,
6400
- logger,
6401
- fileParserLogger,
6402
- endpoint,
6403
- server
6550
+ class AMFNotTypeImpl extends AMFBaseType {
6551
+ constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
6552
+ super(api, shape, typeRegistry, factory, logger, fileParserLogger);
6553
+ this.shape = shape;
6554
+ this.typeRegistry = typeRegistry;
6555
+ this.factory = factory;
6556
+ this.logger = logger;
6557
+ this.fileParserLogger = fileParserLogger;
6558
+ this.type = "not";
6559
+ const amfType = this.factory(
6560
+ this.api,
6561
+ this.shape.not,
6562
+ this.typeRegistry,
6563
+ this.logger,
6564
+ this.fileParserLogger
6404
6565
  );
6405
- this.type = "http";
6406
- const hasRequestBody = amfOperation.requests.some((request) => request.payloads.length > 0);
6407
- if (!hasRequestBody) {
6408
- throw new Error("Operation must have a request body defined");
6409
- }
6410
- this.method = amfOperation.method.value().toUpperCase();
6411
- const extensionsRaw = extractExtensions(amfOperation.customDomainProperties);
6412
- const extensionsResult = this.operationSchemaBuilder.buildHttpOperationSchema().default({}).safeParse(extensionsRaw);
6413
- if (!extensionsResult.success) {
6414
- const message = formatZodError(extensionsResult.error);
6415
- this.fileParserLogger.error(
6416
- this.amfOperation.position.start,
6417
- `Error validating aura operation:
6418
- ${message}`
6419
- );
6420
- throw new Error();
6421
- }
6422
- const extensions = extensionsResult.data;
6423
- if (!extensions.onestore.config["body-param"]) {
6424
- throw new Error("Missing body-param");
6425
- }
6426
- this.configBodyParam = extensions.onestore.config["body-param"];
6566
+ amfType.resolve();
6567
+ this.not = amfType;
6427
6568
  }
6428
6569
  }
6429
- class AmfAuraOperation extends AmfBaseOperation {
6430
- constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6431
- super(
6432
- amfOperation,
6433
- amfTypeFactory2,
6434
- typeRegistry,
6435
- logger,
6436
- fileParserLogger,
6437
- endpoint,
6438
- server
6570
+ class AMFAllOfTypeImpl extends AMFBaseType {
6571
+ constructor() {
6572
+ super(...arguments);
6573
+ this.type = "allOf";
6574
+ this.allOf = [];
6575
+ }
6576
+ typeResolve() {
6577
+ this.logger.trace("Running resolution for inherited and composed shapes");
6578
+ const allOfTypes = [...this.shape.inherits, ...this.shape.and].map(
6579
+ (inheritedShape) => {
6580
+ return this.factory(
6581
+ this.api,
6582
+ inheritedShape,
6583
+ this.typeRegistry,
6584
+ this.logger,
6585
+ this.fileParserLogger,
6586
+ true
6587
+ );
6588
+ }
6439
6589
  );
6440
- this.type = "aura";
6441
- const hasRequestBody = amfOperation.requests.some((request) => request.payloads.length > 0);
6442
- if (hasRequestBody) {
6443
- throw new Error("Operation must not have a request body defined");
6590
+ const rootType = this.factory(
6591
+ this.api,
6592
+ this.shape,
6593
+ this.typeRegistry,
6594
+ this.logger,
6595
+ this.fileParserLogger,
6596
+ true,
6597
+ /* @__PURE__ */ new Set([
6598
+ "any",
6599
+ "ref",
6600
+ "array",
6601
+ "boolean",
6602
+ "date",
6603
+ "number",
6604
+ "datetime",
6605
+ "datetime-only",
6606
+ "double",
6607
+ "integer",
6608
+ "nil",
6609
+ "not",
6610
+ "number",
6611
+ "object",
6612
+ "string",
6613
+ "time"
6614
+ ]),
6615
+ true
6616
+ );
6617
+ this.allOf = [rootType, ...allOfTypes];
6618
+ if (isOneOfShape(this.shape)) {
6619
+ const OneOf = this.factory(
6620
+ this.api,
6621
+ this.shape,
6622
+ this.typeRegistry,
6623
+ this.logger,
6624
+ this.fileParserLogger,
6625
+ true,
6626
+ /* @__PURE__ */ new Set(["oneOf"]),
6627
+ true
6628
+ );
6629
+ this.allOf.push(OneOf);
6444
6630
  }
6445
- this.method = amfOperation.method.value().toUpperCase();
6446
- const extensionsRaw = extractExtensions(amfOperation.customDomainProperties);
6447
- const extensionsResult = this.operationSchemaBuilder.buildAuraOperationSchema().safeParse(extensionsRaw);
6448
- if (!extensionsResult.success) {
6449
- const message = formatZodError(extensionsResult.error);
6450
- this.fileParserLogger.error(
6451
- this.amfOperation.position.start,
6452
- `Error validating aura operation:
6453
- ${message}`
6631
+ if (isEnumShape(this.shape)) {
6632
+ const enumType2 = this.factory(
6633
+ this.api,
6634
+ this.shape,
6635
+ this.typeRegistry,
6636
+ this.logger,
6637
+ this.fileParserLogger,
6638
+ true,
6639
+ /* @__PURE__ */ new Set(["enum"]),
6640
+ true
6454
6641
  );
6455
- throw new Error();
6642
+ this.allOf.push(enumType2);
6456
6643
  }
6457
- const extensions = extensionsResult.data;
6458
- this.aura = { methodName: extensions.onestore.config.aura.method };
6644
+ this.validateDiscriminators();
6459
6645
  }
6460
- }
6461
- class AmfAuraOperationWithRequestBody extends AmfBaseOperation {
6462
- constructor(amfOperation, amfTypeFactory2, typeRegistry, logger, fileParserLogger, endpoint, server) {
6463
- super(
6464
- amfOperation,
6465
- amfTypeFactory2,
6466
- typeRegistry,
6467
- logger,
6468
- fileParserLogger,
6469
- endpoint,
6470
- server
6471
- );
6472
- this.type = "aura";
6473
- const hasRequestBody = amfOperation.requests.some((request) => request.payloads.length > 0);
6474
- if (!hasRequestBody) {
6475
- throw new Error("Operation must have a request body defined");
6646
+ includes(t) {
6647
+ return this.allOf.some((parent) => {
6648
+ const canonicalizedParent = canonicalizeType(parent);
6649
+ if (canonicalizedParent === t) {
6650
+ return true;
6651
+ }
6652
+ return canonicalizedParent.type === "allOf" && canonicalizedParent.includes(t);
6653
+ });
6654
+ }
6655
+ get discriminatedParent() {
6656
+ var _a;
6657
+ const discriminatedParents = [
6658
+ ...bfs(
6659
+ [this],
6660
+ (type) => {
6661
+ return isDiscriminatedObjectType(type);
6662
+ },
6663
+ (type) => {
6664
+ return type.type === "allOf" ? type.allOf : type.type === "ref" ? [type.$ref] : [];
6665
+ }
6666
+ ).values()
6667
+ ];
6668
+ if (discriminatedParents.length === 0) {
6669
+ return;
6476
6670
  }
6477
- this.method = amfOperation.method.value().toUpperCase();
6478
- const extensionsRaw = extractExtensions(amfOperation.customDomainProperties);
6479
- const extensionsResult = this.operationSchemaBuilder.buildAuraOperationWithBodySchema().safeParse(extensionsRaw);
6480
- if (!extensionsResult.success) {
6481
- const message = formatZodError(extensionsResult.error);
6671
+ if (discriminatedParents.length > 1) {
6672
+ const { line = 0, column = 0 } = ((_a = this.shape.position) == null ? void 0 : _a.start) || {};
6482
6673
  this.fileParserLogger.error(
6483
- this.amfOperation.position.start,
6484
- `Error validating aura operation:
6485
- ${message}`
6674
+ { line, column },
6675
+ `Type ${this.typeRegistry.nameOf(
6676
+ this
6677
+ )} cannot inherit from multiple discriminated objects. Inherits from ${discriminatedParents.map(
6678
+ (parent) => this.typeRegistry.nameOf(parent)
6679
+ )}.`
6486
6680
  );
6487
6681
  throw new Error();
6488
6682
  }
6489
- const extensions = extensionsResult.data;
6490
- if (extensions.onestore.config["body-param"] === void 0) {
6491
- throw new Error("Missing body param");
6492
- }
6493
- if (extensions.onestore.config.aura["body-param"] === void 0) {
6494
- throw new Error("Missing aura body param");
6495
- }
6496
- this.configBodyParam = extensions.onestore.config["body-param"];
6497
- this.aura = {
6498
- methodName: extensions.onestore.config.aura.method,
6499
- bodyParam: extensions.onestore.config.aura["body-param"]
6500
- };
6683
+ return discriminatedParents[0];
6684
+ }
6685
+ validateDiscriminators() {
6686
+ this.discriminatedParent;
6501
6687
  }
6502
- }
6503
- function AmfGraphQLOperationMixin(Base) {
6504
- return class AmfGraphQLOperation extends Base {
6505
- constructor(...args) {
6506
- super(...args);
6507
- this.operationType = "graphql";
6508
- this.graphqlConfig = this.setupGraphQLConfig();
6688
+ get extensions() {
6689
+ var _a, _b;
6690
+ if (super.extensions.type === "identifiable") {
6691
+ return super.extensions;
6509
6692
  }
6510
- setupGraphQLConfig() {
6511
- const extensionsRaw = extractExtensions(this.amfOperation.customDomainProperties);
6512
- const extensionsResult = this.operationSchemaBuilder.buildGraphQLOperationSchema().safeParse(extensionsRaw);
6513
- if (!extensionsResult.success) {
6514
- const message = formatZodError(extensionsResult.error);
6515
- this.fileParserLogger.error(
6516
- this.amfOperation.position.start,
6517
- `Error validating graphql operation:
6518
- ${message}`
6519
- );
6520
- throw new Error(message);
6521
- }
6522
- const extensions = extensionsResult.data;
6523
- const config = {
6524
- schemaFilePath: extensions.onestore.config.graphql.schema,
6525
- "type-metadata": extensions.onestore.config.graphql["type-metadata"]
6526
- };
6527
- return config;
6693
+ if (((_b = (_a = this.discriminatedParent) == null ? void 0 : _a.extensions) == null ? void 0 : _b.type) === "identifiable") {
6694
+ return this.discriminatedParent.extensions;
6528
6695
  }
6529
- };
6696
+ return super.extensions;
6697
+ }
6530
6698
  }
6531
- const endpointSchema = z.object({
6532
- onestore: z.discriminatedUnion("endpoint-type", [
6533
- z.object({
6534
- "endpoint-type": z.literal("http")
6535
- }).strict(),
6536
- z.object({
6537
- "endpoint-type": z.literal("aura"),
6538
- config: z.object({
6539
- aura: z.object({
6540
- controller: z.string()
6541
- })
6542
- }),
6543
- "network-preference": z.enum(["aura", "http"]).default("aura")
6544
- }).strict()
6545
- ]).optional()
6546
- });
6547
- const partialOperationSchema = z.object({
6548
- onestore: z.object({
6549
- config: z.object({
6550
- "operation-type": z.enum(["query", "mutation", "graphql"]).optional()
6551
- }).passthrough().optional()
6552
- }).passthrough().optional()
6553
- });
6554
- function createAmfAuraEndpoint(amfEndpoint, amfTypeFactory2, typeRegistry, logger, fileParserLogger, server, api, networkPreference) {
6555
- const endpoint = new AmfAuraEndpoint(
6556
- amfEndpoint,
6557
- [],
6558
- amfTypeFactory2,
6559
- typeRegistry,
6560
- logger,
6561
- fileParserLogger,
6562
- api,
6563
- networkPreference
6564
- );
6565
- const operations = amfEndpoint.operations.map((operation) => {
6566
- var _a, _b;
6567
- const extensionsRaw = extractExtensions(operation.customDomainProperties);
6568
- const operationConfigValidationResult = partialOperationSchema.safeParse(extensionsRaw);
6569
- if (!operationConfigValidationResult.success) {
6570
- const message = formatZodError(operationConfigValidationResult.error);
6571
- fileParserLogger.error(
6572
- operation.position.start,
6573
- `Errors validating operation:
6574
- ${message}`
6699
+ class AMFEnumerableScalarType extends AMFBaseType {
6700
+ typeResolve() {
6701
+ var _a;
6702
+ if (((_a = this.shape.values) == null ? void 0 : _a.length) > 0) {
6703
+ this.values = getEnumValuesFromShape(this.shape);
6704
+ }
6705
+ if (this.parsedExtensions.type === "identifiable") {
6706
+ this.fileParserLogger.error(
6707
+ this.shape.position.start,
6708
+ `${this.shape.name} is scalar and thus cannot be made identifiable by specifying a key`
6575
6709
  );
6576
6710
  throw new Error();
6577
6711
  }
6578
- const hasRequestBody = operation.requests.some((request) => request.payloads.length > 0);
6579
- const isGraphQLOperation = ((_b = (_a = operationConfigValidationResult.data.onestore) == null ? void 0 : _a.config) == null ? void 0 : _b["operation-type"]) === "graphql";
6580
- let baseClass = isGraphQLOperation ? AmfGraphQLOperationMixin(
6581
- hasRequestBody ? AmfAuraOperationWithRequestBody : AmfAuraOperation
6582
- ) : hasRequestBody ? AmfAuraOperationWithRequestBody : AmfAuraOperation;
6583
- return new baseClass(
6584
- operation,
6585
- amfTypeFactory2,
6586
- typeRegistry,
6587
- logger,
6588
- fileParserLogger,
6589
- endpoint,
6590
- server
6591
- );
6592
- });
6593
- endpoint.operations = operations;
6594
- return endpoint;
6712
+ }
6595
6713
  }
6596
- function createAmfHttpEndpoint(amfEndpoint, amfTypeFactory2, typeRegistry, logger, fileParserLogger, server, api) {
6597
- const endpoint = new AmfHttpEndPoint(
6598
- amfEndpoint,
6599
- [],
6600
- amfTypeFactory2,
6601
- typeRegistry,
6602
- logger,
6603
- fileParserLogger,
6604
- api
6605
- );
6606
- const operations = amfEndpoint.operations.map((operation) => {
6607
- var _a, _b;
6608
- const operationConfigValidationResult = partialOperationSchema.safeParse(
6609
- extractExtensions(operation.customDomainProperties)
6610
- );
6611
- if (!operationConfigValidationResult.success) {
6612
- const message = formatZodError(operationConfigValidationResult.error);
6613
- const errorMessage = `Error validating operation:
6614
- ${message}`;
6615
- fileParserLogger.error(operation.position.start, errorMessage);
6616
- throw new Error(errorMessage);
6617
- }
6618
- const hasRequestBody = operation.requests.some((request) => request.payloads.length > 0);
6619
- const isGraphQLOperation = ((_b = (_a = operationConfigValidationResult.data.onestore) == null ? void 0 : _a.config) == null ? void 0 : _b["operation-type"]) === "graphql";
6620
- let baseClass = isGraphQLOperation ? AmfGraphQLOperationMixin(
6621
- hasRequestBody ? AmfHttpOperationWithRequestBody : AmfHttpOperation
6622
- ) : hasRequestBody ? AmfHttpOperationWithRequestBody : AmfHttpOperation;
6623
- return new baseClass(
6624
- operation,
6625
- amfTypeFactory2,
6626
- typeRegistry,
6627
- logger,
6628
- fileParserLogger,
6629
- endpoint,
6630
- server
6631
- );
6632
- });
6633
- endpoint.operations = operations;
6634
- return endpoint;
6714
+ class AMFBooleanTypeImpl extends AMFEnumerableScalarType {
6715
+ constructor() {
6716
+ super(...arguments);
6717
+ this.type = "boolean";
6718
+ }
6635
6719
  }
6636
- function amfEndpointFactory(amfEndpoint, amfTypeFactory2, typeRegistry, logger, fileParserLogger, server, api) {
6637
- const endpointConfigValidationResult = endpointSchema.safeParse(
6638
- extractExtensions(amfEndpoint.customDomainProperties)
6639
- );
6640
- if (!endpointConfigValidationResult.success) {
6641
- const message = formatZodError(endpointConfigValidationResult.error);
6642
- const errorMessage = `Error validating endpoint:
6643
- ${message}`;
6644
- fileParserLogger.error(amfEndpoint.position.start, errorMessage);
6645
- throw new Error(errorMessage);
6720
+ class AMFDoubleTypeImpl extends AMFEnumerableScalarType {
6721
+ constructor() {
6722
+ super(...arguments);
6723
+ this.type = "double";
6646
6724
  }
6647
- const config = endpointConfigValidationResult.data;
6648
- if (config.onestore === void 0) {
6649
- return void 0;
6725
+ }
6726
+ class AMFIntegerTypeImpl extends AMFEnumerableScalarType {
6727
+ constructor() {
6728
+ super(...arguments);
6729
+ this.type = "integer";
6650
6730
  }
6651
- const endpoint = config.onestore["endpoint-type"] === "aura" ? createAmfAuraEndpoint(
6652
- amfEndpoint,
6653
- amfTypeFactory2,
6654
- typeRegistry,
6655
- logger,
6656
- fileParserLogger,
6657
- server,
6658
- api,
6659
- config.onestore["network-preference"]
6660
- ) : createAmfHttpEndpoint(
6661
- amfEndpoint,
6662
- amfTypeFactory2,
6663
- typeRegistry,
6664
- logger,
6665
- fileParserLogger,
6666
- server,
6667
- api
6668
- );
6669
- if (!validateUniqueBindingIdentfiers(endpoint.operations)) {
6670
- const errorMessage = `All operations must have unique bindings`;
6671
- fileParserLogger.error(amfEndpoint.position.start, errorMessage);
6672
- throw new Error(errorMessage);
6731
+ }
6732
+ class AMFNumberTypeImpl extends AMFEnumerableScalarType {
6733
+ constructor() {
6734
+ super(...arguments);
6735
+ this.type = "number";
6736
+ }
6737
+ }
6738
+ class AMFStringTypeImpl extends AMFEnumerableScalarType {
6739
+ constructor() {
6740
+ super(...arguments);
6741
+ this.type = "string";
6742
+ }
6743
+ }
6744
+ class AMFDateTypeImpl extends AMFEnumerableScalarType {
6745
+ constructor() {
6746
+ super(...arguments);
6747
+ this.type = "date";
6748
+ }
6749
+ }
6750
+ const DATE = "date";
6751
+ const DATE_TIME = "date-time";
6752
+ class AMFDateTimeImpl extends AMFEnumerableScalarType {
6753
+ constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
6754
+ super(api, shape, typeRegistry, factory, logger, fileParserLogger);
6755
+ this.shape = shape;
6756
+ this.type = "datetime";
6757
+ const formatValue = shape.format.value();
6758
+ this.format = formatValue === DATE ? DATE : DATE_TIME;
6759
+ }
6760
+ }
6761
+ class AMFOneOfTypeImpl extends AMFBaseType {
6762
+ constructor() {
6763
+ super(...arguments);
6764
+ this.type = "oneOf";
6765
+ this.oneOf = [];
6766
+ }
6767
+ typeResolve() {
6768
+ var _a;
6769
+ let { anyOf = [], xone = [] } = this.shape;
6770
+ this.oneOf = [...anyOf, ...xone].map((subTypeShape) => {
6771
+ const subType = this.factory(
6772
+ this.api,
6773
+ subTypeShape,
6774
+ this.typeRegistry,
6775
+ this.logger,
6776
+ this.fileParserLogger
6777
+ );
6778
+ subType.resolve();
6779
+ return subType;
6780
+ });
6781
+ if (((_a = this.shape.values) == null ? void 0 : _a.length) > 0) {
6782
+ this.values = getEnumValuesFromShape(this.shape);
6783
+ }
6784
+ this.preserveIdentifiableExtensionsFromNullablePattern();
6785
+ }
6786
+ /**
6787
+ * When AMF encounters 'nullable: true' on an object with identifiable extensions,
6788
+ * it converts it to a oneOf with [object, null]. This method detects this pattern
6789
+ * and preserves the identifiable extensions from the object member on the union.
6790
+ */
6791
+ preserveIdentifiableExtensionsFromNullablePattern() {
6792
+ var _a;
6793
+ if (this.oneOf.length !== 2) {
6794
+ return;
6795
+ }
6796
+ const nullMember = this.oneOf.find((member) => member.type === "nil");
6797
+ const objectMember = this.oneOf.find((member) => member.type === "object");
6798
+ if (!nullMember || !objectMember) {
6799
+ return;
6800
+ }
6801
+ if (((_a = objectMember.extensions) == null ? void 0 : _a.type) === "identifiable") {
6802
+ this.parsedExtensions = { ...objectMember.extensions };
6803
+ }
6673
6804
  }
6674
- return endpoint;
6675
6805
  }
6676
- class AmfBaseEndpoint {
6677
- constructor(amfEndpoint, operations, amfTypeFactory2, typeRegistry, logger, fileParserLogger, api) {
6678
- this.amfEndpoint = amfEndpoint;
6679
- this.operations = operations;
6806
+ class AMFEnumTypeImpl extends AMFBaseType {
6807
+ constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
6808
+ super(api, shape, typeRegistry, factory, logger, fileParserLogger);
6809
+ this.shape = shape;
6810
+ this.typeRegistry = typeRegistry;
6811
+ this.factory = factory;
6680
6812
  this.logger = logger;
6681
6813
  this.fileParserLogger = fileParserLogger;
6682
- this.api = api;
6683
- this.path = this.amfEndpoint.path.value();
6684
- this.uriParameters = {};
6685
- this.amfEndpoint.parameters.forEach((param) => {
6686
- this.uriParameters[`${param.name}`] = {
6687
- required: param.required.value(),
6688
- type: amfTypeFactory2(
6689
- this.api,
6690
- param.schema,
6691
- typeRegistry,
6692
- logger,
6693
- fileParserLogger,
6694
- true
6695
- ),
6696
- explode: param.explode.value()
6697
- };
6698
- });
6814
+ this.type = "enum";
6815
+ this.values = [];
6816
+ this.values = getEnumValuesFromShape(shape);
6699
6817
  }
6700
6818
  }
6701
- class AmfHttpEndPoint extends AmfBaseEndpoint {
6819
+ class AMFRefTypeImpl extends AMFBaseType {
6702
6820
  constructor() {
6703
6821
  super(...arguments);
6704
- this.type = "http";
6822
+ this.type = "ref";
6823
+ this.$ref = {
6824
+ type: "not",
6825
+ not: { type: "any" }
6826
+ };
6827
+ this.resolved = false;
6828
+ }
6829
+ typeResolve() {
6830
+ this.logger.trace(`Resolving $ref at ${this.shape.id.split("#")[1]}`);
6831
+ if (this.shape.isLink && this.shape.linkTarget) {
6832
+ const inheritedType = this.typeRegistry.get(this.shape.linkLabel.toString());
6833
+ if (inheritedType) {
6834
+ this.logger.trace(`Found ${inheritedType.shape.name} for $ref`);
6835
+ inheritedType.resolve();
6836
+ this.$ref = inheritedType;
6837
+ } else {
6838
+ const errorMessage = `Failed to resolve $ref: ${this.shape.linkLabel.toString()} from ${this.shape.id}`;
6839
+ this.fileParserLogger.error(this.shapePosition, errorMessage);
6840
+ throw new Error(errorMessage);
6841
+ }
6842
+ }
6705
6843
  }
6706
6844
  }
6707
- class AmfAuraEndpoint extends AmfBaseEndpoint {
6708
- constructor(amfEndPoint, operations, amfTypeFactory2, typeRegistry, logger, fileParserLogger, api, networkPreference) {
6709
- super(amfEndPoint, operations, amfTypeFactory2, typeRegistry, logger, fileParserLogger, api);
6845
+ class AMFDiscriminatedObjectTypeImpl extends AMFBaseType {
6846
+ constructor(api, shape, typeRegistry, factory, logger, fileParserLogger) {
6847
+ super(api, shape, typeRegistry, factory, logger, fileParserLogger);
6848
+ this.shape = shape;
6849
+ this.typeRegistry = typeRegistry;
6850
+ this.factory = factory;
6710
6851
  this.logger = logger;
6711
6852
  this.fileParserLogger = fileParserLogger;
6712
- this.api = api;
6713
- this.networkPreference = networkPreference;
6714
- this.type = "aura";
6715
- this.auraController = this.buildAuraController();
6716
- }
6717
- buildAuraController() {
6718
- const configResult = endpointSchema.safeParse(
6719
- extractExtensions(this.amfEndpoint.customDomainProperties)
6853
+ this.type = "discriminatedObject";
6854
+ this._mapping = void 0;
6855
+ if (this.shape.discriminator.isNullOrEmpty) {
6856
+ this.fileParserLogger.error(
6857
+ this.shapePosition,
6858
+ "Supplied shape does not provide a discriminator"
6859
+ );
6860
+ throw new Error();
6861
+ }
6862
+ this.discriminator = this.shape.discriminator.value();
6863
+ this.baseType = factory(
6864
+ api,
6865
+ shape,
6866
+ typeRegistry,
6867
+ logger,
6868
+ fileParserLogger,
6869
+ false,
6870
+ /* @__PURE__ */ new Set(["object"])
6720
6871
  );
6721
- if (!configResult.success) {
6722
- const message = formatZodError(configResult.error);
6723
- const errorMessage = `Error validating aura endpoint:
6724
- ${message}`;
6725
- this.fileParserLogger.error(this.amfEndpoint.position.start, errorMessage);
6726
- throw new Error(errorMessage);
6872
+ }
6873
+ typeResolve() {
6874
+ this.baseType.resolve();
6875
+ if (this.typeRegistry.nameOf(this) === void 0) {
6876
+ this.fileParserLogger.error(
6877
+ this.shapePosition,
6878
+ "Cannot use discriminator on inline types."
6879
+ );
6880
+ throw new Error();
6727
6881
  }
6728
- const config = configResult.data;
6729
- if (!config.onestore || config.onestore["endpoint-type"] !== "aura") {
6730
- throw new Error("invalid config");
6882
+ }
6883
+ get mapping() {
6884
+ if (this._mapping === void 0) {
6885
+ this._mapping = {};
6886
+ this.resolveDiscriminator();
6731
6887
  }
6732
- const name = config.onestore.config.aura.controller;
6733
- if (name === void 0) {
6734
- throw new Error("Aura controller name must be defined for an Aura endpoint.");
6888
+ return this._mapping;
6889
+ }
6890
+ resolveDiscriminator() {
6891
+ this.buildExplicitMapping();
6892
+ this.buildImplicitMapping();
6893
+ }
6894
+ /**
6895
+ * Adds implicit discriminator values (i.e., type names) as mappings to types
6896
+ *
6897
+ * @private
6898
+ */
6899
+ buildImplicitMapping() {
6900
+ const oneOfNames = this.shape.xone.reduce((result, shape) => {
6901
+ if (shape.isLink) {
6902
+ result.push(shape.linkLabel.value());
6903
+ }
6904
+ return result;
6905
+ }, []);
6906
+ this.typeRegistry.forEach((type, name) => {
6907
+ type.resolve();
6908
+ if ((type.type === "allOf" && type.includes(this) || oneOfNames.includes(name)) && !Object.values(this._mapping).includes(type)) {
6909
+ this._mapping[name] = type;
6910
+ }
6911
+ });
6912
+ }
6913
+ /**
6914
+ * Adds explicit discriminator values as mappings to types
6915
+ *
6916
+ * @private
6917
+ */
6918
+ buildExplicitMapping() {
6919
+ this.shape.discriminatorMapping.forEach((el) => {
6920
+ const value = el.templateVariable.value();
6921
+ const linkExpressionSplit = el.linkExpression.value().split("/");
6922
+ const typeName = linkExpressionSplit[linkExpressionSplit.length - 1];
6923
+ const type = this.typeRegistry.get(typeName);
6924
+ if (type === void 0) {
6925
+ this.fileParserLogger.error(this.shapePosition, `Cannot find type ${typeName}`);
6926
+ throw new Error();
6927
+ }
6928
+ this._mapping[value] = type;
6929
+ });
6930
+ }
6931
+ }
6932
+ function amfTypeFactory(api, shape, typeRegistry, logger, fileParserLogger, resolve = false, allowedTypes = void 0, skipRegistry = false) {
6933
+ var _a;
6934
+ if (!skipRegistry) {
6935
+ for (const [_, type] of typeRegistry.entries()) {
6936
+ if (shape.id === type.shape.id) {
6937
+ return type;
6938
+ }
6939
+ }
6940
+ }
6941
+ const { line = 0, column = 0 } = ((_a = shape.position) == null ? void 0 : _a.start) || {};
6942
+ let ctor;
6943
+ if (isAnyOfShape(shape)) {
6944
+ fileParserLogger.error(
6945
+ { line, column },
6946
+ `anyOf is not suppoort, found in type ${shape.name.value()}`
6947
+ );
6948
+ throw new Error();
6949
+ }
6950
+ if (isRefShape(shape)) {
6951
+ ctor = AMFRefTypeImpl;
6952
+ } else if ((!allowedTypes || allowedTypes.has("allOf")) && isAllOfShape(shape)) {
6953
+ ctor = AMFAllOfTypeImpl;
6954
+ } else if ((!allowedTypes || allowedTypes.has("oneOf")) && isOneOfShape(shape)) {
6955
+ ctor = AMFOneOfTypeImpl;
6956
+ } else if ((!allowedTypes || allowedTypes.has("enum")) && isEnumShape(shape)) {
6957
+ ctor = AMFEnumTypeImpl;
6958
+ } else if ((!allowedTypes || allowedTypes.has("nil")) && isNilShape(shape)) {
6959
+ ctor = AMFNilTypeImpl;
6960
+ } else if (isScalarShape(shape) && shape.dataType.value() in DATATYPE_TO_SCALAR_TYPE && (!allowedTypes || allowedTypes.has(DATATYPE_TO_SCALAR_TYPE[shape.dataType.value()]))) {
6961
+ const scalarType = DATATYPE_TO_SCALAR_TYPE[shape.dataType.value()];
6962
+ switch (scalarType) {
6963
+ case "string":
6964
+ ctor = AMFStringTypeImpl;
6965
+ break;
6966
+ case "number":
6967
+ ctor = AMFNumberTypeImpl;
6968
+ break;
6969
+ case "boolean":
6970
+ ctor = AMFBooleanTypeImpl;
6971
+ break;
6972
+ case "double":
6973
+ ctor = AMFDoubleTypeImpl;
6974
+ break;
6975
+ case "integer":
6976
+ ctor = AMFIntegerTypeImpl;
6977
+ break;
6978
+ case "date":
6979
+ ctor = AMFDateTypeImpl;
6980
+ break;
6981
+ case "datetime":
6982
+ ctor = AMFDateTimeImpl;
6983
+ break;
6984
+ default:
6985
+ fileParserLogger.error(
6986
+ { line, column },
6987
+ `type of shape ${shape.name.value()} not recognized`
6988
+ );
6989
+ throw new Error();
6990
+ }
6991
+ } else if ((!allowedTypes || allowedTypes.has("discriminatedObject")) && isNodeShape(shape) && !shape.discriminator.isNullOrEmpty) {
6992
+ ctor = AMFDiscriminatedObjectTypeImpl;
6993
+ } else if ((!allowedTypes || allowedTypes.has("object")) && isNodeShape(shape)) {
6994
+ ctor = AMFObjectTypeImpl;
6995
+ } else if ((!allowedTypes || allowedTypes.has("array")) && isArrayShape(shape)) {
6996
+ ctor = AMFArrayTypeImpl;
6997
+ } else if ((!allowedTypes || allowedTypes.has("not")) && isNotShape(shape)) {
6998
+ ctor = AMFNotTypeImpl;
6999
+ } else if ((!allowedTypes || allowedTypes.has("any")) && isAnyShape(shape)) {
7000
+ ctor = AMFAnyTypeImpl;
7001
+ } else {
7002
+ fileParserLogger.error(
7003
+ { line, column },
7004
+ `type of shape ${shape.name.value()} not recognized`
7005
+ );
7006
+ throw new Error();
7007
+ }
7008
+ const result = new ctor(api, shape, typeRegistry, amfTypeFactory, logger, fileParserLogger);
7009
+ if (resolve) {
7010
+ result.resolve();
7011
+ }
7012
+ return result;
7013
+ }
7014
+ class AMFArrayTypeImpl extends AMFBaseType {
7015
+ constructor() {
7016
+ super(...arguments);
7017
+ this.type = "array";
7018
+ this.items = { type: "any" };
7019
+ }
7020
+ typeResolve() {
7021
+ if (this.shape.items) {
7022
+ const items = amfTypeFactory(
7023
+ this.api,
7024
+ this.shape.items,
7025
+ this.typeRegistry,
7026
+ this.logger,
7027
+ this.fileParserLogger
7028
+ );
7029
+ items.resolve();
7030
+ this.items = items;
6735
7031
  }
6736
- return { name };
6737
7032
  }
6738
7033
  }
6739
- const rootSchema = z.object({
6740
- onestore: z.object({
6741
- version: z.string().refine(stringIsVersion, () => {
6742
- return {
6743
- message: "Version must satisfy format major[.minor[.patch]]"
6744
- };
6745
- })
6746
- })
6747
- });
6748
7034
  function getAmfAnnotationVersion(webApi) {
6749
7035
  const configRaw = extractExtensions(webApi.customDomainProperties);
6750
- const config = rootSchema.safeParse(configRaw);
7036
+ const config = rootExtensionSchema.safeParse(configRaw);
6751
7037
  if (!config.success) {
6752
7038
  const validationMessage = formatZodError(config.error);
6753
7039
  throw new Error(`Error validating root x-onestore extension:
@@ -6802,28 +7088,6 @@ ${formattedValidation}`;
6802
7088
  }
6803
7089
  return isValid2;
6804
7090
  }
6805
- const V1_VERSION = "1.0.0";
6806
- const oneStoreExtensionsSchema = z.object({
6807
- onestore: z.object({
6808
- defaults: z.object({
6809
- operations: z.object({
6810
- "cache-strategy": z.discriminatedUnion("type", [
6811
- z.object({ type: z.literal("none") }).strict(),
6812
- z.object({ type: z.literal("resource") }).strict(),
6813
- z.object({ type: z.literal("normalized") }).strict()
6814
- ])
6815
- }),
6816
- schemas: z.object({
6817
- "cache-control": cacheControl
6818
- })
6819
- }).partial().strict().optional(),
6820
- // Allow service catalog at root-level for reliability
6821
- services: servicesCatalogSchema.optional(),
6822
- namespace: z.string().optional(),
6823
- version: z.string()
6824
- }).strict()
6825
- });
6826
- const ANONYMOUS_TYPE_NAME = "<anonymous>";
6827
7091
  class AMFAPI {
6828
7092
  constructor(document, services, fileParserlogger) {
6829
7093
  this.document = document;
@@ -6869,381 +7133,126 @@ class AMFAPI {
6869
7133
  if (this.webApi.servers.length === 0) {
6870
7134
  this.fileParserlogger.error(
6871
7135
  { line: this.webApi.position.lineFrom, column: this.webApi.position.columnFrom },
6872
- `At least one server must be specified in your OpenAPI file. e.g.:
6873
- servers:
6874
- - url: http://localhost:3000
6875
- description: Local development server`
6876
- );
6877
- throw new Error();
6878
- }
6879
- this._servers = this.webApi.servers.map((s) => {
6880
- const uriParameters = {};
6881
- s.variables.forEach((param) => {
6882
- uriParameters[`${param.name.value()}`] = {
6883
- required: param.required.value(),
6884
- type: amfTypeFactory(
6885
- this,
6886
- param.schema,
6887
- this.types,
6888
- this.services.logger,
6889
- this.fileParserlogger
6890
- ),
6891
- explode: param.explode.value()
6892
- };
6893
- });
6894
- return {
6895
- url: s.url.value(),
6896
- uriParameters
6897
- };
6898
- });
6899
- }
6900
- buildTypes() {
6901
- this.services.logger.debug("AMFAPI - Building the type registry");
6902
- const typeRegistry = this.typeRegistry = new BaseTypeRegistry();
6903
- this.document.declares.filter(isTypeShape).forEach((shape) => {
6904
- const name = shape.name.value();
6905
- this.services.logger.debug(`AMFAPI - Building AMF Type for ${name}`);
6906
- const amfType = amfTypeFactory(
6907
- this,
6908
- shape,
6909
- typeRegistry,
6910
- this.services.logger,
6911
- this.fileParserlogger
6912
- );
6913
- this.services.logger.debug(`AMFAPI - Setting ${name} in type registry`);
6914
- typeRegistry.set(shape.name.value(), amfType);
6915
- });
6916
- typeRegistry.forEach((type, name) => {
6917
- this.services.logger.debug(`AMFAPI - Resolving type ${name}`);
6918
- type.resolve();
6919
- });
6920
- }
6921
- get webApi() {
6922
- return this.document.encodes;
6923
- }
6924
- get endpoints() {
6925
- this.build();
6926
- return this._endpoints;
6927
- }
6928
- get defaults() {
6929
- const operationCacheStrategy2 = this.parsedDefaultOperationCacheStrategyType ?? { type: "none" };
6930
- const typeCacheControl = this.parsedDefaultTypeCacheControl;
6931
- const services = resolveDefaultServiceOverrides(this.serviceOverrides);
6932
- return {
6933
- operationCacheStrategy: operationCacheStrategy2,
6934
- typeCacheControl,
6935
- services
6936
- };
6937
- }
6938
- get servers() {
6939
- this.build();
6940
- return this._servers;
6941
- }
6942
- get types() {
6943
- this.build();
6944
- return this.typeRegistry;
6945
- }
6946
- get namespace() {
6947
- if (this.parsedNamespace === void 0) {
6948
- return this.defaultedNamespace;
6949
- }
6950
- return this.parsedNamespace;
6951
- }
6952
- checkAnnotationsVersion() {
6953
- const version = getAmfAnnotationVersion(this.webApi);
6954
- if (!satisfies(V1_VERSION, version)) {
6955
- throw new Error(
6956
- `Version ${version} requested cannot be satisfied by version ${V1_VERSION} of the AMF API.`
6957
- );
6958
- }
6959
- }
6960
- setRootLevelAnnotations() {
6961
- var _a, _b, _c, _d;
6962
- const extensionsRaw = extractExtensions(this.webApi.customDomainProperties);
6963
- const oneStoreExtensionsResult = oneStoreExtensionsSchema.safeParse(extensionsRaw);
6964
- if (!oneStoreExtensionsResult.success) {
6965
- const message = formatZodError(oneStoreExtensionsResult.error);
6966
- throw new Error(message);
6967
- }
6968
- const onestore = oneStoreExtensionsResult.data.onestore;
6969
- this.parsedDefaultOperationCacheStrategyType = (_b = (_a = onestore == null ? void 0 : onestore.defaults) == null ? void 0 : _a.operations) == null ? void 0 : _b["cache-strategy"];
6970
- this.parsedDefaultTypeCacheControl = (_d = (_c = onestore == null ? void 0 : onestore.defaults) == null ? void 0 : _c.schemas) == null ? void 0 : _d["cache-control"];
6971
- this.parsedNamespace = onestore == null ? void 0 : onestore.namespace;
6972
- if (this.parsedNamespace === void 0) {
6973
- this.services.logger.warn(
6974
- `AMFAPI - namespace is missing, will be defaulted "${this.defaultedNamespace}".`
6975
- );
6976
- }
6977
- if (onestore == null ? void 0 : onestore.services) {
6978
- this.serviceOverrides = validateAndNormalizeCatalog(onestore.services);
6979
- }
6980
- }
6981
- /**
6982
- * Validates all endpoints and types. A validation error will be thrown if any are invalid.
6983
- *
6984
- * @protected
6985
- */
6986
- validate() {
6987
- if (!isValidAmfAPI(this, this.fileParserlogger)) {
6988
- throw new Error("API OneStore configuration failed validation");
6989
- }
6990
- }
6991
- }
6992
- class NoNormalizedTypesValidator {
6993
- constructor(types) {
6994
- this.types = types;
6995
- }
6996
- validate(operation) {
6997
- if (isNormalizedOperation(operation)) {
6998
- return ok([]);
6999
- }
7000
- const identifiableTypes = /* @__PURE__ */ new Set();
7001
- operation.responses.forEach((response) => {
7002
- return response.payloads.forEach((payload) => {
7003
- this.findNestedIdentifiableTypes(payload.data).forEach(
7004
- (type) => identifiableTypes.add(type)
7005
- );
7006
- });
7007
- });
7008
- const messages = [];
7009
- if (identifiableTypes.size > 0) {
7010
- identifiableTypes.forEach((type) => {
7011
- const typeName = this.types.nameOf(type) || ANONYMOUS_TYPE_NAME;
7012
- messages.push(
7013
- getFormattedMessage(
7014
- operation,
7015
- `Operation ${operation.operationId ? `${operation.operationId} ` : ``}is not normalized but references the normalized type ${typeName} in its response`
7016
- )
7017
- );
7018
- });
7019
- return messages.length === 0 ? ok([]) : err(messages);
7020
- }
7021
- return ok([]);
7022
- }
7023
- /**
7024
- * Completes a breadth-first search of a Type to locate any nested types that are identifiable.
7025
- *
7026
- * @returns a Set of all nested types that are identifiable.
7027
- * @param start
7028
- * @protected
7029
- */
7030
- findNestedIdentifiableTypes(start) {
7031
- return bfs(
7032
- [start],
7033
- (type) => {
7034
- var _a;
7035
- return ((_a = type.extensions) == null ? void 0 : _a.type) === "identifiable";
7036
- },
7037
- (type) => {
7038
- const typing = type.type;
7039
- switch (typing) {
7040
- case "allOf":
7041
- return type.allOf;
7042
- case "array":
7043
- return [type.items];
7044
- case "object":
7045
- return [
7046
- ...Object.values(type.properties).map((property) => property.type),
7047
- type.additionalProperties
7048
- ];
7049
- case "oneOf":
7050
- return type.oneOf;
7051
- case "ref":
7052
- return [type.$ref];
7053
- case "discriminatedObject":
7054
- return [...Object.values(type.mapping), type.baseType];
7055
- case "any":
7056
- case "enum":
7057
- case "boolean":
7058
- case "double":
7059
- case "integer":
7060
- case "number":
7061
- case "string":
7062
- case "date":
7063
- case "datetime":
7064
- case "datetime-only":
7065
- case "nil":
7066
- case "not":
7067
- case "time":
7068
- return [];
7069
- default:
7070
- throw new Error(
7071
- `${typing} has not been accounted for when searching for nested identifiable types`
7072
- );
7073
- }
7074
- }
7075
- );
7076
- }
7077
- }
7078
- class KeyMatchValidator {
7079
- constructor(types) {
7080
- this.types = types;
7081
- }
7082
- validate(operation) {
7083
- if (!isNormalizedOperation(operation)) {
7084
- return ok([]);
7136
+ `At least one server must be specified in your OpenAPI file. e.g.:
7137
+ servers:
7138
+ - url: http://localhost:3000
7139
+ description: Local development server`
7140
+ );
7141
+ throw new Error();
7085
7142
  }
7086
- const operationHasKey = !!operation.cacheStrategy.key;
7087
- let valid = true;
7088
- const messages = [];
7089
- operation.responses.forEach((response) => {
7090
- response.payloads.forEach((payload) => {
7091
- var _a, _b;
7092
- if (((_a = payload.data.extensions) == null ? void 0 : _a.type) === "identifiable") {
7093
- const typeName = this.types.nameOf(payload.data) || ANONYMOUS_TYPE_NAME;
7094
- if (!operationHasKey) {
7095
- valid = false;
7096
- messages.push(
7097
- getFormattedMessage(
7098
- operation,
7099
- `Operation ${operation.operationId ? `${operation.operationId} ` : ``}is missing a key to match against its ${typeName} response type`
7100
- )
7101
- );
7102
- } else if (!((_b = payload.data.extensions.key) == null ? void 0 : _b.fields)) {
7103
- valid = false;
7104
- messages.push(
7105
- getFormattedMessage(
7106
- operation,
7107
- `Operation ${operation.operationId ? `${operation.operationId} ` : ``}has a key but its ${typeName} response type doesn't have one to match against`
7108
- )
7109
- );
7110
- } else if (!deepEquals(
7111
- Object.keys(operation.cacheStrategy.key || {}),
7112
- Object.keys(payload.data.extensions.key.fields)
7113
- )) {
7114
- valid = false;
7115
- messages.push(
7116
- getFormattedMessage(
7117
- operation,
7118
- `Operation ${operation.operationId ? `${operation.operationId} ` : ``}and its ${typeName} response type have mismatched keys`
7119
- )
7120
- );
7121
- }
7122
- }
7143
+ this._servers = this.webApi.servers.map((s) => {
7144
+ const uriParameters = {};
7145
+ s.variables.forEach((param) => {
7146
+ uriParameters[`${param.name.value()}`] = {
7147
+ required: param.required.value(),
7148
+ type: amfTypeFactory(
7149
+ this,
7150
+ param.schema,
7151
+ this.types,
7152
+ this.services.logger,
7153
+ this.fileParserlogger
7154
+ ),
7155
+ explode: param.explode.value()
7156
+ };
7123
7157
  });
7158
+ return {
7159
+ url: s.url.value(),
7160
+ uriParameters
7161
+ };
7124
7162
  });
7125
- return valid ? ok(messages) : err(messages);
7126
7163
  }
7127
- }
7128
- class BodyDataValidator {
7129
- constructor(target, keys, keySourcesValidatorSupplier) {
7130
- this.target = target;
7131
- this.keys = keys;
7132
- this.keySourcesValidatorSupplier = keySourcesValidatorSupplier;
7164
+ buildTypes() {
7165
+ this.services.logger.debug("AMFAPI - Building the type registry");
7166
+ const typeRegistry = this.typeRegistry = new BaseTypeRegistry();
7167
+ this.document.declares.filter(isTypeShape).forEach((shape) => {
7168
+ const name = shape.name.value();
7169
+ this.services.logger.debug(`AMFAPI - Building AMF Type for ${name}`);
7170
+ const amfType = amfTypeFactory(
7171
+ this,
7172
+ shape,
7173
+ typeRegistry,
7174
+ this.services.logger,
7175
+ this.fileParserlogger
7176
+ );
7177
+ this.services.logger.debug(`AMFAPI - Setting ${name} in type registry`);
7178
+ typeRegistry.set(shape.name.value(), amfType);
7179
+ });
7180
+ typeRegistry.forEach((type, name) => {
7181
+ this.services.logger.debug(`AMFAPI - Resolving type ${name}`);
7182
+ type.resolve();
7183
+ });
7133
7184
  }
7134
- validate(operation) {
7135
- if (this.keys.length === 0) {
7136
- return ok([]);
7137
- }
7138
- const jsonPayload = this.target.payloads.find((p) => p.mediaType === "application/json");
7139
- if (jsonPayload === void 0) {
7140
- return err([
7141
- getFormattedMessage(
7142
- operation,
7143
- `Use of 'body' keys requires a json payload: ${operation.method} ${operation.endpoint.path} has none.`
7144
- )
7145
- ]);
7185
+ get webApi() {
7186
+ return this.document.encodes;
7187
+ }
7188
+ get endpoints() {
7189
+ this.build();
7190
+ return this._endpoints;
7191
+ }
7192
+ get defaults() {
7193
+ const operationCacheStrategy2 = this.parsedDefaultOperationCacheStrategyType ?? { type: "none" };
7194
+ const typeCacheControl = this.parsedDefaultTypeCacheControl;
7195
+ const services = resolveDefaultServiceOverrides(this.serviceOverrides);
7196
+ return {
7197
+ operationCacheStrategy: operationCacheStrategy2,
7198
+ typeCacheControl,
7199
+ services
7200
+ };
7201
+ }
7202
+ get servers() {
7203
+ this.build();
7204
+ return this._servers;
7205
+ }
7206
+ get types() {
7207
+ this.build();
7208
+ return this.typeRegistry;
7209
+ }
7210
+ get namespace() {
7211
+ if (this.parsedNamespace === void 0) {
7212
+ return this.defaultedNamespace;
7146
7213
  }
7147
- const result = this.keySourcesValidatorSupplier(this.keys).validate(jsonPayload.data);
7148
- if (!result.isOk()) {
7149
- const message = getFormattedMessage(
7150
- operation,
7151
- `Invalid body key(s) specified for ${operation.operationId || `${operation.method} ${operation.endpoint.path}`}`
7214
+ return this.parsedNamespace;
7215
+ }
7216
+ checkAnnotationsVersion() {
7217
+ const version = getAmfAnnotationVersion(this.webApi);
7218
+ if (!satisfies(V1_VERSION, version)) {
7219
+ throw new Error(
7220
+ `Version ${version} requested cannot be satisfied by version ${V1_VERSION} of the AMF API.`
7152
7221
  );
7153
- message.subValidationMessages = result.error;
7154
- return err([message]);
7155
7222
  }
7156
- return ok([]);
7157
7223
  }
7158
- }
7159
- function buildOperationValidator(api) {
7160
- const bodyDateValidatorSupplier = (target, sources) => {
7161
- return new BodyDataValidator(target, sources, (keys) => {
7162
- return new KeySourcesValidator(api.types, keys);
7163
- });
7164
- };
7165
- return compose([
7166
- new InvalidationValidator(api.types, bodyDateValidatorSupplier),
7167
- new KeySourceValidator(bodyDateValidatorSupplier),
7168
- new Response200Validator(),
7169
- new NoNormalizedTypesValidator(api.types),
7170
- new KeyMatchValidator(api.types)
7171
- ]);
7172
- }
7173
- function buildEndpointValidator(api) {
7174
- const operationValidator = buildOperationValidator(api);
7175
- return {
7176
- validate(subject) {
7177
- return combineValidationResults(
7178
- subject.operations.map((operation) => operationValidator.validate(operation))
7224
+ setRootLevelAnnotations() {
7225
+ var _a, _b, _c, _d;
7226
+ const extensionsRaw = extractExtensions(this.webApi.customDomainProperties);
7227
+ const oneStoreExtensionsResult = baseExtensionsSchema.safeParse(extensionsRaw);
7228
+ if (!oneStoreExtensionsResult.success) {
7229
+ const message = formatZodError(oneStoreExtensionsResult.error);
7230
+ throw new Error(message);
7231
+ }
7232
+ const onestore = oneStoreExtensionsResult.data.onestore;
7233
+ this.parsedDefaultOperationCacheStrategyType = (_b = (_a = onestore == null ? void 0 : onestore.defaults) == null ? void 0 : _a.operations) == null ? void 0 : _b["cache-strategy"];
7234
+ this.parsedDefaultTypeCacheControl = (_d = (_c = onestore == null ? void 0 : onestore.defaults) == null ? void 0 : _c.schemas) == null ? void 0 : _d["cache-control"];
7235
+ this.parsedNamespace = onestore == null ? void 0 : onestore.namespace;
7236
+ if (this.parsedNamespace === void 0) {
7237
+ this.services.logger.warn(
7238
+ `AMFAPI - namespace is missing, will be defaulted "${this.defaultedNamespace}".`
7179
7239
  );
7180
7240
  }
7181
- };
7182
- }
7183
- class BindingsValidation {
7184
- constructor() {
7185
- }
7186
- validate(api) {
7187
- const messages = [];
7188
- const endpoints = api.endpoints;
7189
- const identToPathAndOperation = /* @__PURE__ */ new Map();
7190
- for (const endpoint of endpoints) {
7191
- const { path: path2, operations } = endpoint;
7192
- for (const operation of operations) {
7193
- const operationId = operation.operationId || `${operation.method} ${operation.endpoint.path}`;
7194
- const { bindings } = operation;
7195
- for (const binding of bindings) {
7196
- const { identifier } = binding;
7197
- if (identToPathAndOperation.has(identifier)) {
7198
- const existing = identToPathAndOperation.get(identifier);
7199
- messages.push({
7200
- severity: ValidationSeverity.Error,
7201
- message: `Binding identifier '${identifier}' in operation '${operationId}' is already used in path '${existing.path}' and operation '${existing.operationId}'`,
7202
- subject: operation,
7203
- validationType: ValidationType.Operation
7204
- });
7205
- } else {
7206
- identToPathAndOperation.set(identifier, { path: path2, operationId });
7207
- }
7208
- }
7209
- }
7241
+ if (onestore == null ? void 0 : onestore.services) {
7242
+ this.serviceOverrides = validateAndNormalizeCatalog(onestore.services);
7210
7243
  }
7211
- return messages.length > 0 ? err(messages) : ok(messages);
7212
- }
7213
- }
7214
- class ApiValidator {
7215
- constructor(apiValidators, typeValidator, endpointValidator) {
7216
- this.apiValidators = apiValidators;
7217
- this.typeValidator = typeValidator;
7218
- this.endpointValidator = endpointValidator;
7219
- }
7220
- validate(subject) {
7221
- const results = [
7222
- this.validateCollection(subject.types.values(), this.typeValidator),
7223
- this.validateCollection(subject.endpoints, this.endpointValidator),
7224
- ...this.apiValidators.map((v) => v.validate(subject))
7225
- ];
7226
- return combineValidationResults(results);
7227
7244
  }
7228
- validateCollection(items, validator) {
7229
- const results = [];
7230
- for (const item of items) {
7231
- results.push(validator.validate(item));
7245
+ /**
7246
+ * Validates all endpoints and types. A validation error will be thrown if any are invalid.
7247
+ *
7248
+ * @protected
7249
+ */
7250
+ validate() {
7251
+ if (!isValidAmfAPI(this, this.fileParserlogger)) {
7252
+ throw new Error("API OneStore configuration failed validation");
7232
7253
  }
7233
- return combineValidationResults(results);
7234
7254
  }
7235
7255
  }
7236
- function buildApiValidatorFor(api) {
7237
- const typeValidation = buildTypeValidator(api.types);
7238
- const apiValidators = [new BindingsValidation()];
7239
- const endpointValidation = buildEndpointValidator(api);
7240
- return new ApiValidator(apiValidators, typeValidation, endpointValidation);
7241
- }
7242
- function validateUniqueBindingIdentfiers(operations) {
7243
- const operationsBindings = operations.map(({ bindings }) => bindings.map(({ identifier }) => identifier)).flat();
7244
- const uniqueBindings = new Set(operationsBindings);
7245
- return operationsBindings.length === uniqueBindings.size;
7246
- }
7247
7256
  async function parseAmfDocument(source, logger) {
7248
7257
  const parseResult = await amf.APIConfiguration.API().baseUnitClient().parse(source.toString());
7249
7258
  parseResult.results.forEach((result) => logResult(result, logger));
@@ -7300,13 +7309,6 @@ class AMFAPIService {
7300
7309
  function amfAPIService(services) {
7301
7310
  return new AMFAPIService(services);
7302
7311
  }
7303
- function asAPIService(api) {
7304
- const p = Promise.resolve(api);
7305
- return {
7306
- build: () => p,
7307
- api
7308
- };
7309
- }
7310
7312
  export {
7311
7313
  AMFAnyTypeImpl,
7312
7314
  AMFArrayTypeImpl,
@@ -7321,6 +7323,7 @@ export {
7321
7323
  AMFObjectTypeImpl,
7322
7324
  AMFOneOfTypeImpl,
7323
7325
  AMFStringTypeImpl,
7326
+ ANONYMOUS_TYPE_NAME,
7324
7327
  BaseTypeRegistry,
7325
7328
  BindingTypesEnum,
7326
7329
  V1_VERSION,
@@ -7329,7 +7332,6 @@ export {
7329
7332
  asAPIService,
7330
7333
  buildApiValidatorFor,
7331
7334
  buildTypeValidator,
7332
- cacheControl,
7333
7335
  canonicalizeType,
7334
7336
  componentsOnestoreServicesSchema,
7335
7337
  getAmfAnnotationVersion,
@@ -7356,7 +7358,6 @@ export {
7356
7358
  isScalar$1 as isScalar,
7357
7359
  isStringType,
7358
7360
  isTimeType,
7359
- operationCacheStrategy,
7360
7361
  operationOnestoreServicesSchema,
7361
7362
  operationServiceInlineSchema,
7362
7363
  operationServiceRefSchema,
@@ -7365,10 +7366,8 @@ export {
7365
7366
  parseUrl,
7366
7367
  resolveDefaultServiceOverrides,
7367
7368
  resolveOperationServices,
7368
- resourceCacheControl,
7369
7369
  serviceVariantDescriptorSchema,
7370
7370
  servicesCatalogSchema,
7371
- typeExtensions,
7372
7371
  typesEqual,
7373
7372
  validateAndNormalizeCatalog
7374
7373
  };