@daocloud-proto/skoala 0.2.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.
package/.gitkeep ADDED
File without changes
@@ -0,0 +1,15 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+ export type Version = {
7
+ version?: string
8
+ gitCommit?: string
9
+ buildDate?: string
10
+ goVersion?: string
11
+ }
12
+
13
+ export type GetVersionRes = {
14
+ version?: Version
15
+ }
@@ -0,0 +1,100 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+
7
+ import * as fm from "..\..\..\fetch.pb"
8
+ import * as GoogleProtobufEmpty from "..\..\..\google\protobuf\empty.pb"
9
+ import * as GoogleProtobufTimestamp from "..\..\..\google\protobuf\timestamp.pb"
10
+
11
+ export enum Status {
12
+ TAKEDOWN = "TAKEDOWN",
13
+ ONSHELF = "ONSHELF",
14
+ }
15
+
16
+ export type GetBookReq = {
17
+ uid?: string
18
+ }
19
+
20
+ export type GetBookReply = {
21
+ uid?: string
22
+ name?: string
23
+ author?: string
24
+ status?: Status
25
+ isPublished?: boolean
26
+ publishedAt?: GoogleProtobufTimestamp.Timestamp
27
+ }
28
+
29
+ export type ListBookReq = {
30
+ pageNum?: number
31
+ pageSize?: number
32
+ }
33
+
34
+ export type ListBookReplyBook = {
35
+ uid?: string
36
+ name?: string
37
+ author?: string
38
+ status?: Status
39
+ isPublished?: boolean
40
+ publishedAt?: GoogleProtobufTimestamp.Timestamp
41
+ }
42
+
43
+ export type ListBookReply = {
44
+ results?: ListBookReplyBook[]
45
+ totalCount?: number
46
+ }
47
+
48
+ export type CreateBookReq = {
49
+ name?: string
50
+ author?: string
51
+ status?: Status
52
+ isPublished?: boolean
53
+ publishedAt?: GoogleProtobufTimestamp.Timestamp
54
+ }
55
+
56
+ export type CreateBookReply = {
57
+ uid?: string
58
+ name?: string
59
+ author?: string
60
+ status?: Status
61
+ isPublished?: boolean
62
+ publishedAt?: GoogleProtobufTimestamp.Timestamp
63
+ }
64
+
65
+ export type UpdateBookReq = {
66
+ uid?: string
67
+ author?: string
68
+ status?: Status
69
+ }
70
+
71
+ export type UpdateBookRely = {
72
+ uid?: string
73
+ name?: string
74
+ author?: string
75
+ status?: Status
76
+ isPublished?: boolean
77
+ publishedAt?: GoogleProtobufTimestamp.Timestamp
78
+ }
79
+
80
+ export type DeleteBookReq = {
81
+ uid?: string
82
+ }
83
+
84
+ export class Book {
85
+ static Get(req: GetBookReq, initReq?: fm.InitReq): Promise<GetBookReply> {
86
+ return fm.fetchReq<GetBookReq, GetBookReply>(`/v1alpha1/books/${req["uid"]}?${fm.renderURLSearchParams(req, ["uid"])}`, {...initReq, method: "GET"})
87
+ }
88
+ static List(req: ListBookReq, initReq?: fm.InitReq): Promise<ListBookReply> {
89
+ return fm.fetchReq<ListBookReq, ListBookReply>(`/v1alpha1/books?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
90
+ }
91
+ static Create(req: CreateBookReq, initReq?: fm.InitReq): Promise<CreateBookReply> {
92
+ return fm.fetchReq<CreateBookReq, CreateBookReply>(`/v1alpha1/books`, {...initReq, method: "POST", body: JSON.stringify(req)})
93
+ }
94
+ static Update(req: UpdateBookReq, initReq?: fm.InitReq): Promise<UpdateBookRely> {
95
+ return fm.fetchReq<UpdateBookReq, UpdateBookRely>(`/v1alpha1/books/${req["uid"]}`, {...initReq, method: "PUT", body: JSON.stringify(req)})
96
+ }
97
+ static Delete(req: DeleteBookReq, initReq?: fm.InitReq): Promise<GoogleProtobufEmpty.Empty> {
98
+ return fm.fetchReq<DeleteBookReq, GoogleProtobufEmpty.Empty>(`/v1alpha1/books/${req["uid"]}`, {...initReq, method: "DELETE"})
99
+ }
100
+ }
@@ -0,0 +1,62 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+
7
+ import * as fm from "..\..\..\fetch.pb"
8
+ import * as GoogleProtobufEmpty from "..\..\..\google\protobuf\empty.pb"
9
+ import * as SkoalaApiGeneralV1alpha1Version from "..\..\general\v1alpha1\version.pb"
10
+ import * as SkoalaApiIntegratedV1alpha1Instance from "..\..\integrated\v1alpha1\instance.pb"
11
+ import * as SkoalaApiIntegratedV1alpha1Registry from "..\..\integrated\v1alpha1\registry.pb"
12
+ import * as SkoalaApiIntegratedV1alpha1Service from "..\..\integrated\v1alpha1\service.pb"
13
+ export class Hive {
14
+ static GetVersion(req: GoogleProtobufEmpty.Empty, initReq?: fm.InitReq): Promise<SkoalaApiGeneralV1alpha1Version.GetVersionRes> {
15
+ return fm.fetchReq<GoogleProtobufEmpty.Empty, SkoalaApiGeneralV1alpha1Version.GetVersionRes>(`/apis/hive.skoala.io/v1alpha1/version?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
16
+ }
17
+ }
18
+ export class Registry {
19
+ static List(req: SkoalaApiIntegratedV1alpha1Registry.ListRegistryReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Registry.ListRegistryRes> {
20
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Registry.ListRegistryReq, SkoalaApiIntegratedV1alpha1Registry.ListRegistryRes>(`/apis/hive.skoala.io/v1alpha1/registries?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
21
+ }
22
+ static Get(req: SkoalaApiIntegratedV1alpha1Registry.GetRegistryReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Registry.GetRegistryRes> {
23
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Registry.GetRegistryReq, SkoalaApiIntegratedV1alpha1Registry.GetRegistryRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}?${fm.renderURLSearchParams(req, ["registryId"])}`, {...initReq, method: "GET"})
24
+ }
25
+ static Update(req: SkoalaApiIntegratedV1alpha1Registry.UpdateRegistryReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Registry.UpdateRegistryRes> {
26
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Registry.UpdateRegistryReq, SkoalaApiIntegratedV1alpha1Registry.UpdateRegistryRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}`, {...initReq, method: "PUT", body: JSON.stringify(req)})
27
+ }
28
+ static Create(req: SkoalaApiIntegratedV1alpha1Registry.CreateRegistryReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Registry.CreateRegistryRes> {
29
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Registry.CreateRegistryReq, SkoalaApiIntegratedV1alpha1Registry.CreateRegistryRes>(`/apis/hive.skoala.io/v1alpha1/registries`, {...initReq, method: "POST", body: JSON.stringify(req)})
30
+ }
31
+ static Delete(req: SkoalaApiIntegratedV1alpha1Registry.DeleteRegistryReq, initReq?: fm.InitReq): Promise<GoogleProtobufEmpty.Empty> {
32
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Registry.DeleteRegistryReq, GoogleProtobufEmpty.Empty>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}`, {...initReq, method: "DELETE"})
33
+ }
34
+ static Ping(req: SkoalaApiIntegratedV1alpha1Registry.PingRegistryReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Registry.PingRegistryRes> {
35
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Registry.PingRegistryReq, SkoalaApiIntegratedV1alpha1Registry.PingRegistryRes>(`/apis/hive.skoala.io/v1alpha1/registries/ping`, {...initReq, method: "POST", body: JSON.stringify(req)})
36
+ }
37
+ }
38
+ export class Service {
39
+ static ListAll(req: SkoalaApiIntegratedV1alpha1Service.ListServiceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Service.ListServiceRes> {
40
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Service.ListServiceReq, SkoalaApiIntegratedV1alpha1Service.ListServiceRes>(`/apis/hive.skoala.io/v1alpha1/services?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
41
+ }
42
+ static List(req: SkoalaApiIntegratedV1alpha1Service.ListServiceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Service.ListServiceRes> {
43
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Service.ListServiceReq, SkoalaApiIntegratedV1alpha1Service.ListServiceRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}/services?${fm.renderURLSearchParams(req, ["registryId"])}`, {...initReq, method: "GET"})
44
+ }
45
+ static Get(req: SkoalaApiIntegratedV1alpha1Service.GetServiceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Service.GetServiceRes> {
46
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Service.GetServiceReq, SkoalaApiIntegratedV1alpha1Service.GetServiceRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}/services/${req["serviceName"]}?${fm.renderURLSearchParams(req, ["registryId", "serviceName"])}`, {...initReq, method: "GET"})
47
+ }
48
+ }
49
+ export class Instance {
50
+ static ListAll(req: SkoalaApiIntegratedV1alpha1Instance.ListInstanceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Instance.ListInstanceRes> {
51
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Instance.ListInstanceReq, SkoalaApiIntegratedV1alpha1Instance.ListInstanceRes>(`/apis/hive.skoala.io/v1alpha1/instances?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
52
+ }
53
+ static ListRegistryAll(req: SkoalaApiIntegratedV1alpha1Instance.ListInstanceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Instance.ListInstanceRes> {
54
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Instance.ListInstanceReq, SkoalaApiIntegratedV1alpha1Instance.ListInstanceRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}/instances?${fm.renderURLSearchParams(req, ["registryId"])}`, {...initReq, method: "GET"})
55
+ }
56
+ static List(req: SkoalaApiIntegratedV1alpha1Instance.ListInstanceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Instance.ListInstanceRes> {
57
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Instance.ListInstanceReq, SkoalaApiIntegratedV1alpha1Instance.ListInstanceRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}/services/${req["serviceName"]}/instances?${fm.renderURLSearchParams(req, ["registryId", "serviceName"])}`, {...initReq, method: "GET"})
58
+ }
59
+ static Get(req: SkoalaApiIntegratedV1alpha1Instance.GetInstanceReq, initReq?: fm.InitReq): Promise<SkoalaApiIntegratedV1alpha1Instance.GetInstanceRes> {
60
+ return fm.fetchReq<SkoalaApiIntegratedV1alpha1Instance.GetInstanceReq, SkoalaApiIntegratedV1alpha1Instance.GetInstanceRes>(`/apis/hive.skoala.io/v1alpha1/registries/${req["registryId"]}/services/${req["serviceName"]}/instances/${req["instanceId"]}?${fm.renderURLSearchParams(req, ["registryId", "serviceName", "instanceId"])}`, {...initReq, method: "GET"})
61
+ }
62
+ }
@@ -0,0 +1,43 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+
7
+ import * as SkoalaApiIntegratedV1alpha1Registry from ".\registry.pb"
8
+ export type Instance = {
9
+ id?: string
10
+ serviceName?: string
11
+ frameworkType?: string
12
+ host?: string
13
+ port?: number
14
+ metadata?: {[key: string]: string}
15
+ registry?: SkoalaApiIntegratedV1alpha1Registry.Registry
16
+ detail?: {[key: string]: string}
17
+ }
18
+
19
+ export type ListInstanceReq = {
20
+ registryId?: string
21
+ namespaceId?: string
22
+ groupName?: string
23
+ serviceName?: string
24
+ }
25
+
26
+ export type GetInstanceReq = {
27
+ registryId?: string
28
+ namespaceId?: string
29
+ groupName?: string
30
+ serviceName?: string
31
+ instanceId?: string
32
+ }
33
+
34
+ export type ListInstanceRes = {
35
+ instances?: Instance[]
36
+ page?: number
37
+ size?: number
38
+ total?: number
39
+ }
40
+
41
+ export type GetInstanceRes = {
42
+ instance?: Instance
43
+ }
@@ -0,0 +1,77 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+ export type Registry = {
7
+ registryId?: string
8
+ name?: string
9
+ type?: string
10
+ addresses?: string[]
11
+ namespaces?: Namespace[]
12
+ serviceCount?: number
13
+ }
14
+
15
+ export type ListRegistryReq = {
16
+ page?: number
17
+ size?: number
18
+ }
19
+
20
+ export type ListRegistryRes = {
21
+ registries?: Registry[]
22
+ page?: number
23
+ size?: number
24
+ total?: number
25
+ }
26
+
27
+ export type GetRegistryReq = {
28
+ registryId?: string
29
+ }
30
+
31
+ export type GetRegistryRes = {
32
+ registry?: Registry
33
+ }
34
+
35
+ export type UpdateRegistryReq = {
36
+ registryId?: string
37
+ name?: string
38
+ type?: string
39
+ addresses?: string
40
+ namespaces?: string
41
+ }
42
+
43
+ export type UpdateRegistryRes = {
44
+ registry?: Registry
45
+ }
46
+
47
+ export type CreateRegistryReq = {
48
+ name?: string
49
+ type?: string
50
+ addresses?: string
51
+ namespaces?: string
52
+ }
53
+
54
+ export type CreateRegistryRes = {
55
+ registry?: Registry
56
+ }
57
+
58
+ export type DeleteRegistryReq = {
59
+ registryId?: string
60
+ }
61
+
62
+ export type PingRegistryReq = {
63
+ type?: string
64
+ addresses?: string
65
+ namespaces?: string
66
+ }
67
+
68
+ export type PingRegistryRes = {
69
+ serviceCount?: number
70
+ namespaces?: Namespace[]
71
+ }
72
+
73
+ export type Namespace = {
74
+ id?: string
75
+ name?: string
76
+ group?: string
77
+ }
@@ -0,0 +1,38 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+
7
+ import * as SkoalaApiIntegratedV1alpha1Registry from ".\registry.pb"
8
+ export type Service = {
9
+ name?: string
10
+ namespace?: SkoalaApiIntegratedV1alpha1Registry.Namespace
11
+ instanceCount?: number
12
+ registry?: SkoalaApiIntegratedV1alpha1Registry.Registry
13
+ detail?: {[key: string]: string}
14
+ }
15
+
16
+ export type ListServiceReq = {
17
+ registryId?: string
18
+ page?: number
19
+ size?: number
20
+ }
21
+
22
+ export type ListServiceRes = {
23
+ services?: Service[]
24
+ page?: number
25
+ size?: number
26
+ total?: number
27
+ }
28
+
29
+ export type GetServiceReq = {
30
+ registryId?: string
31
+ namespaceId?: string
32
+ groupName?: string
33
+ serviceName?: string
34
+ }
35
+
36
+ export type GetServiceRes = {
37
+ service?: Service
38
+ }
package/fetch.pb.ts ADDED
@@ -0,0 +1,232 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ /*
4
+ * This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
5
+ */
6
+
7
+ export interface InitReq extends RequestInit {
8
+ pathPrefix?: string
9
+ }
10
+
11
+ export function fetchReq<I, O>(path: string, init?: InitReq): Promise<O> {
12
+ const {pathPrefix, ...req} = init || {}
13
+
14
+ const url = pathPrefix ? `${pathPrefix}${path}` : path
15
+
16
+ return fetch(url, req).then(r => r.json().then((body: O) => {
17
+ if (!r.ok) { throw body; }
18
+ return body;
19
+ })) as Promise<O>
20
+ }
21
+
22
+ // NotifyStreamEntityArrival is a callback that will be called on streaming entity arrival
23
+ export type NotifyStreamEntityArrival<T> = (resp: T) => void
24
+
25
+ /**
26
+ * fetchStreamingRequest is able to handle grpc-gateway server side streaming call
27
+ * it takes NotifyStreamEntityArrival that lets users respond to entity arrival during the call
28
+ * all entities will be returned as an array after the call finishes.
29
+ **/
30
+ export async function fetchStreamingRequest<S, R>(path: string, callback?: NotifyStreamEntityArrival<R>, init?: InitReq) {
31
+ const {pathPrefix, ...req} = init || {}
32
+ const url = pathPrefix ?`${pathPrefix}${path}` : path
33
+ const result = await fetch(url, req)
34
+ // needs to use the .ok to check the status of HTTP status code
35
+ // http other than 200 will not throw an error, instead the .ok will become false.
36
+ // see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#
37
+ if (!result.ok) {
38
+ const resp = await result.json()
39
+ const errMsg = resp.error && resp.error.message ? resp.error.message : ""
40
+ throw new Error(errMsg)
41
+ }
42
+
43
+ if (!result.body) {
44
+ throw new Error("response doesnt have a body")
45
+ }
46
+
47
+ await result.body
48
+ .pipeThrough(new TextDecoderStream())
49
+ .pipeThrough<R>(getNewLineDelimitedJSONDecodingStream<R>())
50
+ .pipeTo(getNotifyEntityArrivalSink((e: R) => {
51
+ if (callback) {
52
+ callback(e)
53
+ }
54
+ }))
55
+
56
+ // wait for the streaming to finish and return the success respond
57
+ return
58
+ }
59
+
60
+ /**
61
+ * JSONStringStreamController represents the transform controller that's able to transform the incoming
62
+ * new line delimited json content stream into entities and able to push the entity to the down stream
63
+ */
64
+ interface JSONStringStreamController<T> extends TransformStreamDefaultController {
65
+ buf?: string
66
+ pos?: number
67
+ enqueue: (s: T) => void
68
+ }
69
+
70
+ /**
71
+ * getNewLineDelimitedJSONDecodingStream returns a TransformStream that's able to handle new line delimited json stream content into parsed entities
72
+ */
73
+ function getNewLineDelimitedJSONDecodingStream<T>(): TransformStream<string, T> {
74
+ return new TransformStream({
75
+ start(controller: JSONStringStreamController<T>) {
76
+ controller.buf = ''
77
+ controller.pos = 0
78
+ },
79
+
80
+ transform(chunk: string, controller: JSONStringStreamController<T>) {
81
+ if (controller.buf === undefined) {
82
+ controller.buf = ''
83
+ }
84
+ if (controller.pos === undefined) {
85
+ controller.pos = 0
86
+ }
87
+ controller.buf += chunk
88
+ while (controller.pos < controller.buf.length) {
89
+ if (controller.buf[controller.pos] === '\n') {
90
+ const line = controller.buf.substring(0, controller.pos)
91
+ const response = JSON.parse(line)
92
+ controller.enqueue(response.result)
93
+ controller.buf = controller.buf.substring(controller.pos + 1)
94
+ controller.pos = 0
95
+ } else {
96
+ ++controller.pos
97
+ }
98
+ }
99
+ }
100
+ })
101
+
102
+ }
103
+
104
+ /**
105
+ * getNotifyEntityArrivalSink takes the NotifyStreamEntityArrival callback and return
106
+ * a sink that will call the callback on entity arrival
107
+ * @param notifyCallback
108
+ */
109
+ function getNotifyEntityArrivalSink<T>(notifyCallback: NotifyStreamEntityArrival<T>) {
110
+ return new WritableStream<T>({
111
+ write(entity: T) {
112
+ notifyCallback(entity)
113
+ }
114
+ })
115
+ }
116
+
117
+ type Primitive = string | boolean | number;
118
+ type RequestPayload = Record<string, unknown>;
119
+ type FlattenedRequestPayload = Record<string, Primitive | Array<Primitive>>;
120
+
121
+ /**
122
+ * Checks if given value is a plain object
123
+ * Logic copied and adapted from below source:
124
+ * https://github.com/char0n/ramda-adjunct/blob/master/src/isPlainObj.js
125
+ * @param {unknown} value
126
+ * @return {boolean}
127
+ */
128
+ function isPlainObject(value: unknown): boolean {
129
+ const isObject =
130
+ Object.prototype.toString.call(value).slice(8, -1) === "Object";
131
+ const isObjLike = value !== null && isObject;
132
+
133
+ if (!isObjLike || !isObject) {
134
+ return false;
135
+ }
136
+
137
+ const proto = Object.getPrototypeOf(value);
138
+
139
+ const hasObjectConstructor =
140
+ typeof proto === "object" &&
141
+ proto.constructor === Object.prototype.constructor;
142
+
143
+ return hasObjectConstructor;
144
+ }
145
+
146
+ /**
147
+ * Checks if given value is of a primitive type
148
+ * @param {unknown} value
149
+ * @return {boolean}
150
+ */
151
+ function isPrimitive(value: unknown): boolean {
152
+ return ["string", "number", "boolean"].some(t => typeof value === t);
153
+ }
154
+
155
+ /**
156
+ * Checks if given primitive is zero-value
157
+ * @param {Primitive} value
158
+ * @return {boolean}
159
+ */
160
+ function isZeroValuePrimitive(value: Primitive): boolean {
161
+ return value === false || value === 0 || value === "";
162
+ }
163
+
164
+ /**
165
+ * Flattens a deeply nested request payload and returns an object
166
+ * with only primitive values and non-empty array of primitive values
167
+ * as per https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
168
+ * @param {RequestPayload} requestPayload
169
+ * @param {String} path
170
+ * @return {FlattenedRequestPayload>}
171
+ */
172
+ function flattenRequestPayload<T extends RequestPayload>(
173
+ requestPayload: T,
174
+ path: string = ""
175
+ ): FlattenedRequestPayload {
176
+ return Object.keys(requestPayload).reduce(
177
+ (acc: T, key: string): T => {
178
+ const value = requestPayload[key];
179
+ const newPath = path ? [path, key].join(".") : key;
180
+
181
+ const isNonEmptyPrimitiveArray =
182
+ Array.isArray(value) &&
183
+ value.every(v => isPrimitive(v)) &&
184
+ value.length > 0;
185
+
186
+ const isNonZeroValuePrimitive =
187
+ isPrimitive(value) && !isZeroValuePrimitive(value as Primitive);
188
+
189
+ let objectToMerge = {};
190
+
191
+ if (isPlainObject(value)) {
192
+ objectToMerge = flattenRequestPayload(value as RequestPayload, newPath);
193
+ } else if (isNonZeroValuePrimitive || isNonEmptyPrimitiveArray) {
194
+ objectToMerge = { [newPath]: value };
195
+ }
196
+
197
+ return { ...acc, ...objectToMerge };
198
+ },
199
+ {} as T
200
+ ) as FlattenedRequestPayload;
201
+ }
202
+
203
+ /**
204
+ * Renders a deeply nested request payload into a string of URL search
205
+ * parameters by first flattening the request payload and then removing keys
206
+ * which are already present in the URL path.
207
+ * @param {RequestPayload} requestPayload
208
+ * @param {string[]} urlPathParams
209
+ * @return {string}
210
+ */
211
+ export function renderURLSearchParams<T extends RequestPayload>(
212
+ requestPayload: T,
213
+ urlPathParams: string[] = []
214
+ ): string {
215
+ const flattenedRequestPayload = flattenRequestPayload(requestPayload);
216
+
217
+ const urlSearchParams = Object.keys(flattenedRequestPayload).reduce(
218
+ (acc: string[][], key: string): string[][] => {
219
+ // key should not be present in the url path as a parameter
220
+ const value = flattenedRequestPayload[key];
221
+ if (urlPathParams.find(f => f === key)) {
222
+ return acc;
223
+ }
224
+ return Array.isArray(value)
225
+ ? [...acc, ...value.map(m => [key, m.toString()])]
226
+ : (acc = [...acc, [key, value.toString()]]);
227
+ },
228
+ [] as string[][]
229
+ );
230
+
231
+ return new URLSearchParams(urlSearchParams).toString();
232
+ }
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@daocloud-proto/skoala",
3
+ "version": "0.2.0",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "keywords": [],
9
+ "author": "",
10
+ "license": "ISC",
11
+ "description": ""
12
+ }