-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathgenerate-method-id.ts
More file actions
133 lines (125 loc) · 4.02 KB
/
generate-method-id.ts
File metadata and controls
133 lines (125 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { MethodObject, ContentDescriptorObject } from "./types";
import { findIndex } from "./helper-functions";
/**
* Provides an error interface for handling when we are unable to find a contentDescriptor in a methodObject
* when it is expected.
*
* @category Errors
*
*/
export class ContentDescriptorNotFoundInMethodError implements Error {
public name = "OpenRPCDocumentDereferencingError";
public message: string;
/**
* @param method OpenRPC Method which was used for the lookup
* @param contentDescriptor OpenRPC Content Descriptor that was expected to be in the method param.
*/
constructor(public method: MethodObject, public contentDescriptor: ContentDescriptorObject) {
this.message = [
"Content Descriptor not found in method.",
`Method: ${JSON.stringify(method, undefined, " ")}`,
`ContentDescriptor: ${JSON.stringify(contentDescriptor, undefined, " ")}`,
].join("\n");
}
}
/**
* Create a unique identifier for a parameter within a given method.
* This is typically used to create hashmap keys for method to parameter mappings.
*
* @param method The OpenRPC Method which encloses the content descriptor
* @param contentDescriptor The OpenRPC Content Descriptor that is a param in the method
*
* @returns an ID for the param/method combo.
* It follows the format `{method.name}/{indexWithinParams}|{contentDescriptor.name}` where:
* 1. if the method's parameter structure is "by-name", the format returned uses the contentDescriptor.name
* 1. otherwise, the return value will use the params index in the list of params.
*
* @throws [[ContentDescriptorNotFoundInMethodError]]
*
* @example
* ```typescript
*
* const { generateMethodParamId }
* const methodObject = {
* name: "foo",
* params: [{
* name: "fooParam",
* schema: { type: "integer" }
* }],
* result: {}
* };
* const paramId = generateMethodParamId(methodObject, methodObject.params[0]);
* console.log(paramId);
* // outputs:
* // "foo/0/fooParam"
* ```
*
* @category GenerateID
*
*/
export function generateMethodParamId(
method: MethodObject,
contentDescriptor: ContentDescriptorObject
): string {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pos = findIndex(method.params, (o: any) => {
return o.name == contentDescriptor.name;
});
if (pos === -1) {
throw new ContentDescriptorNotFoundInMethodError(method, contentDescriptor);
}
let paramId: string;
if (method.paramStructure === "by-position") {
paramId = pos.toString();
} else if (method.paramStructure === "by-name") {
const paramCD = method.params[pos] as ContentDescriptorObject;
paramId = paramCD.name;
} else {
const paramCD = method.params[pos] as ContentDescriptorObject;
paramId = `${paramCD.name}/${pos.toString()}`;
}
return `${method.name}/${paramId}`;
}
/**
* Create a unique identifier for a result within a given method.
* This is typically used to create hashmap keys for method to result mappings.
*
* @param method The OpenRPC Method which encloses the content descriptor
* @param contentDescriptor The OpenRPC Content Descriptor (either a method param or the result).
*
* @returns an ID for the result/method combo.
* It follows the format `{method.name}/result`.
*
* @throws [[ContentDescriptorNotFoundInMethodError]]
*
* @example
* ```typescript
*
* const { generateMethodResultId }
* const methodObject = {
* name: "foo",
* params: [],
* result: {
* name: "fooResult",
* schema: { type: "string" }
* }
* };
* const resultId = generateMethodResultId(methodObject, methodObject.result);
* console.log(paramId);
* // outputs:
* // "foo/result"
* ```
*
* @category GenerateID
*
*/
export function generateMethodResultId(
method: MethodObject,
contentDescriptor: ContentDescriptorObject
): string {
const result = method.result as ContentDescriptorObject;
if (result.name !== contentDescriptor.name) {
throw new ContentDescriptorNotFoundInMethodError(method, contentDescriptor);
}
return `${method.name}/result`;
}