From ada8bb2b0cc063f0b3f7609ee8338454a75c0f2f Mon Sep 17 00:00:00 2001 From: Ed Ball Date: Thu, 18 Nov 2021 13:51:25 -0800 Subject: [PATCH 1/3] Support context on request methods. This would typically be used by clients to implement cancellation. --- example/js/exampleApi.js | 48 +++++++++---------- example/ts/src/exampleApi.ts | 48 +++++++++---------- example/ts/src/exampleApiTypes.ts | 24 +++++----- .../JavaScriptGenerator.cs | 6 +-- ts/src/facilityCore.ts | 7 +-- 5 files changed, 67 insertions(+), 66 deletions(-) diff --git a/example/js/exampleApi.js b/example/js/exampleApi.js index 3c4c91b..4219ce0 100644 --- a/example/js/exampleApi.js +++ b/example/js/exampleApi.js @@ -27,7 +27,7 @@ class ExampleApiHttpClient { } /** Gets widgets. */ - getWidgets(request) { + getWidgets(request, context) { let uri = 'widgets'; const query = []; request.query == null || query.push('q=' + encodeURIComponent(request.query)); @@ -42,7 +42,7 @@ class ExampleApiHttpClient { const fetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -62,14 +62,14 @@ class ExampleApiHttpClient { } /** Creates a new widget. */ - createWidget(request) { + createWidget(request, context) { const uri = 'widgets'; const fetchRequest = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request.widget) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -86,7 +86,7 @@ class ExampleApiHttpClient { } /** Gets the specified widget. */ - getWidget(request) { + getWidget(request, context) { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -99,7 +99,7 @@ class ExampleApiHttpClient { if (request.ifNoneMatch != null) { fetchRequest.headers['If-None-Match'] = request.ifNoneMatch; } - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -128,7 +128,7 @@ class ExampleApiHttpClient { } /** Deletes the specified widget. */ - deleteWidget(request) { + deleteWidget(request, context) { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -137,7 +137,7 @@ class ExampleApiHttpClient { const fetchRequest = { method: 'DELETE', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -154,7 +154,7 @@ class ExampleApiHttpClient { } /** Edits widget. */ - editWidget(request) { + editWidget(request, context) { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -168,7 +168,7 @@ class ExampleApiHttpClient { weight: request.weight }) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -188,14 +188,14 @@ class ExampleApiHttpClient { } /** Gets the specified widgets. */ - getWidgetBatch(request) { + getWidgetBatch(request, context) { const uri = 'widgets/get'; const fetchRequest = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request.ids) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -215,7 +215,7 @@ class ExampleApiHttpClient { * Gets the widget weight. * @deprecated */ - getWidgetWeight(request) { + getWidgetWeight(request, context) { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -224,7 +224,7 @@ class ExampleApiHttpClient { const fetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -241,7 +241,7 @@ class ExampleApiHttpClient { } /** Gets a widget preference. */ - getPreference(request) { + getPreference(request, context) { const uriPartKey = request.key != null && encodeURIComponent(request.key); if (!uriPartKey) { return Promise.resolve(createRequiredRequestFieldError('key')); @@ -250,7 +250,7 @@ class ExampleApiHttpClient { const fetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -267,7 +267,7 @@ class ExampleApiHttpClient { } /** Sets a widget preference. */ - setPreference(request) { + setPreference(request, context) { const uriPartKey = request.key != null && encodeURIComponent(request.key); if (!uriPartKey) { return Promise.resolve(createRequiredRequestFieldError('key')); @@ -278,7 +278,7 @@ class ExampleApiHttpClient { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request.value) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -295,12 +295,12 @@ class ExampleApiHttpClient { } /** Gets service info. */ - getInfo(request) { + getInfo(request, context) { const uri = ''; const fetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -317,12 +317,12 @@ class ExampleApiHttpClient { } /** Demonstrates the default HTTP behavior. */ - notRestful(request) { + notRestful(request, context) { const uri = 'notRestful'; const fetchRequest = { method: 'POST', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; @@ -338,14 +338,14 @@ class ExampleApiHttpClient { }); } - kitchen(request) { + kitchen(request, context) { const uri = 'kitchen'; const fetchRequest = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value = null; diff --git a/example/ts/src/exampleApi.ts b/example/ts/src/exampleApi.ts index d82d440..cb0d15f 100644 --- a/example/ts/src/exampleApi.ts +++ b/example/ts/src/exampleApi.ts @@ -30,7 +30,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets widgets. */ - public getWidgets(request: IGetWidgetsRequest): Promise> { + public getWidgets(request: IGetWidgetsRequest, context?: any): Promise> { let uri = 'widgets'; const query: string[] = []; request.query == null || query.push('q=' + encodeURIComponent(request.query)); @@ -45,7 +45,7 @@ class ExampleApiHttpClient implements IExampleApi { const fetchRequest: IFetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IGetWidgetsResponse | null = null; @@ -65,14 +65,14 @@ class ExampleApiHttpClient implements IExampleApi { } /** Creates a new widget. */ - public createWidget(request: ICreateWidgetRequest): Promise> { + public createWidget(request: ICreateWidgetRequest, context?: any): Promise> { const uri = 'widgets'; const fetchRequest: IFetchRequest = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request.widget) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: ICreateWidgetResponse | null = null; @@ -89,7 +89,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets the specified widget. */ - public getWidget(request: IGetWidgetRequest): Promise> { + public getWidget(request: IGetWidgetRequest, context?: any): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -102,7 +102,7 @@ class ExampleApiHttpClient implements IExampleApi { if (request.ifNoneMatch != null) { fetchRequest.headers!['If-None-Match'] = request.ifNoneMatch; } - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IGetWidgetResponse | null = null; @@ -131,7 +131,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Deletes the specified widget. */ - public deleteWidget(request: IDeleteWidgetRequest): Promise> { + public deleteWidget(request: IDeleteWidgetRequest, context?: any): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -140,7 +140,7 @@ class ExampleApiHttpClient implements IExampleApi { const fetchRequest: IFetchRequest = { method: 'DELETE', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IDeleteWidgetResponse | null = null; @@ -157,7 +157,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Edits widget. */ - public editWidget(request: IEditWidgetRequest): Promise> { + public editWidget(request: IEditWidgetRequest, context?: any): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -171,7 +171,7 @@ class ExampleApiHttpClient implements IExampleApi { weight: request.weight }) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IEditWidgetResponse | null = null; @@ -191,14 +191,14 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets the specified widgets. */ - public getWidgetBatch(request: IGetWidgetBatchRequest): Promise> { + public getWidgetBatch(request: IGetWidgetBatchRequest, context?: any): Promise> { const uri = 'widgets/get'; const fetchRequest: IFetchRequest = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request.ids) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IGetWidgetBatchResponse | null = null; @@ -218,7 +218,7 @@ class ExampleApiHttpClient implements IExampleApi { * Gets the widget weight. * @deprecated */ - public getWidgetWeight(request: IGetWidgetWeightRequest): Promise> { + public getWidgetWeight(request: IGetWidgetWeightRequest, context?: any): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -227,7 +227,7 @@ class ExampleApiHttpClient implements IExampleApi { const fetchRequest: IFetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IGetWidgetWeightResponse | null = null; @@ -244,7 +244,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets a widget preference. */ - public getPreference(request: IGetPreferenceRequest): Promise> { + public getPreference(request: IGetPreferenceRequest, context?: any): Promise> { const uriPartKey = request.key != null && encodeURIComponent(request.key); if (!uriPartKey) { return Promise.resolve(createRequiredRequestFieldError('key')); @@ -253,7 +253,7 @@ class ExampleApiHttpClient implements IExampleApi { const fetchRequest: IFetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IGetPreferenceResponse | null = null; @@ -270,7 +270,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Sets a widget preference. */ - public setPreference(request: ISetPreferenceRequest): Promise> { + public setPreference(request: ISetPreferenceRequest, context?: any): Promise> { const uriPartKey = request.key != null && encodeURIComponent(request.key); if (!uriPartKey) { return Promise.resolve(createRequiredRequestFieldError('key')); @@ -281,7 +281,7 @@ class ExampleApiHttpClient implements IExampleApi { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request.value) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: ISetPreferenceResponse | null = null; @@ -298,12 +298,12 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets service info. */ - public getInfo(request: IGetInfoRequest): Promise> { + public getInfo(request: IGetInfoRequest, context?: any): Promise> { const uri = ''; const fetchRequest: IFetchRequest = { method: 'GET', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IGetInfoResponse | null = null; @@ -320,12 +320,12 @@ class ExampleApiHttpClient implements IExampleApi { } /** Demonstrates the default HTTP behavior. */ - public notRestful(request: INotRestfulRequest): Promise> { + public notRestful(request: INotRestfulRequest, context?: any): Promise> { const uri = 'notRestful'; const fetchRequest: IFetchRequest = { method: 'POST', }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: INotRestfulResponse | null = null; @@ -341,14 +341,14 @@ class ExampleApiHttpClient implements IExampleApi { }); } - public kitchen(request: IKitchenRequest): Promise> { + public kitchen(request: IKitchenRequest, context?: any): Promise> { const uri = 'kitchen'; const fetchRequest: IFetchRequest = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request) }; - return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest) + return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context) .then(result => { const status = result.response.status; let value: IKitchenResponse | null = null; diff --git a/example/ts/src/exampleApiTypes.ts b/example/ts/src/exampleApiTypes.ts index 48962a2..20cf2fa 100644 --- a/example/ts/src/exampleApiTypes.ts +++ b/example/ts/src/exampleApiTypes.ts @@ -6,42 +6,42 @@ import { IServiceResult, IServiceError } from 'facility-core'; /** Example service for widgets. */ export interface IExampleApi { /** Gets widgets. */ - getWidgets(request: IGetWidgetsRequest): Promise>; + getWidgets(request: IGetWidgetsRequest, context?: any): Promise>; /** Creates a new widget. */ - createWidget(request: ICreateWidgetRequest): Promise>; + createWidget(request: ICreateWidgetRequest, context?: any): Promise>; /** Gets the specified widget. */ - getWidget(request: IGetWidgetRequest): Promise>; + getWidget(request: IGetWidgetRequest, context?: any): Promise>; /** Deletes the specified widget. */ - deleteWidget(request: IDeleteWidgetRequest): Promise>; + deleteWidget(request: IDeleteWidgetRequest, context?: any): Promise>; /** Edits widget. */ - editWidget(request: IEditWidgetRequest): Promise>; + editWidget(request: IEditWidgetRequest, context?: any): Promise>; /** Gets the specified widgets. */ - getWidgetBatch(request: IGetWidgetBatchRequest): Promise>; + getWidgetBatch(request: IGetWidgetBatchRequest, context?: any): Promise>; /** * Gets the widget weight. * @deprecated */ - getWidgetWeight(request: IGetWidgetWeightRequest): Promise>; + getWidgetWeight(request: IGetWidgetWeightRequest, context?: any): Promise>; /** Gets a widget preference. */ - getPreference(request: IGetPreferenceRequest): Promise>; + getPreference(request: IGetPreferenceRequest, context?: any): Promise>; /** Sets a widget preference. */ - setPreference(request: ISetPreferenceRequest): Promise>; + setPreference(request: ISetPreferenceRequest, context?: any): Promise>; /** Gets service info. */ - getInfo(request: IGetInfoRequest): Promise>; + getInfo(request: IGetInfoRequest, context?: any): Promise>; /** Demonstrates the default HTTP behavior. */ - notRestful(request: INotRestfulRequest): Promise>; + notRestful(request: INotRestfulRequest, context?: any): Promise>; - kitchen(request: IKitchenRequest): Promise>; + kitchen(request: IKitchenRequest, context?: any): Promise>; } /** Request for GetWidgets. */ diff --git a/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs b/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs index a700f97..9697ed5 100644 --- a/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs +++ b/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs @@ -84,7 +84,7 @@ public override CodeGenOutput GenerateOutput(ServiceInfo service) var capMethodName = CodeGenUtility.Capitalize(methodName); code.WriteLineSkipOnce(); WriteJsDoc(code, httpMethodInfo.ServiceMethod); - code.WriteLine($"{methodName}(request: I{capMethodName}Request): Promise>;"); + code.WriteLine($"{methodName}(request: I{capMethodName}Request, context?: any): Promise>;"); } } @@ -190,7 +190,7 @@ public override CodeGenOutput GenerateOutput(ServiceInfo service) code.WriteLine(); WriteJsDoc(code, httpMethodInfo.ServiceMethod); - using (code.Block(IfTypeScript("public ") + $"{methodName}(request" + IfTypeScript($": I{capMethodName}Request") + ")" + IfTypeScript($": Promise>") + " {", "}")) + using (code.Block(IfTypeScript("public ") + $"{methodName}(request" + IfTypeScript($": I{capMethodName}Request") + ", context" + IfTypeScript("?: any") + ")" + IfTypeScript($": Promise>") + " {", "}")) { var hasPathFields = httpMethodInfo.PathFields.Count != 0; var jsUriDelim = hasPathFields ? "`" : "'"; @@ -264,7 +264,7 @@ public override CodeGenOutput GenerateOutput(ServiceInfo service) } } - code.WriteLine("return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest)"); + code.WriteLine("return fetchResponse(this._fetch, this._baseUri + uri, fetchRequest, context)"); using (code.Indent()) using (code.Block(".then(result => {", "});")) { diff --git a/ts/src/facilityCore.ts b/ts/src/facilityCore.ts index 0e142e6..76c1c61 100644 --- a/ts/src/facilityCore.ts +++ b/ts/src/facilityCore.ts @@ -35,7 +35,7 @@ export interface IHttpClientOptions { export namespace HttpClientUtility { /** The fetch function. */ export interface IFetch { - (uri: string, request: IFetchRequest): Promise; + (uri: string, request: IFetchRequest, context?: any): Promise; } /** The minimal fetch request. */ @@ -81,9 +81,10 @@ export namespace HttpClientUtility { export function fetchResponse( fetch: IFetch, uri: string, - request: IFetchRequest + request: IFetchRequest, + context?: any ): Promise { - return fetch(uri, request).then((response) => { + return fetch(uri, request, context).then((response) => { if (!response.headers || !response.status || typeof response.json !== 'function') { throw new TypeError('fetch must resolve Promise with { status, headers, json() }.'); } From 3d144722c3764c12e27ad221061a6704ceaf3ded Mon Sep 17 00:00:00 2001 From: Ed Ball Date: Thu, 18 Nov 2021 14:50:20 -0800 Subject: [PATCH 2/3] Use 'unknown' instead of 'any' for the context. --- example/ts/src/exampleApi.ts | 24 +++++++++---------- example/ts/src/exampleApiTypes.ts | 24 +++++++++---------- .../JavaScriptGenerator.cs | 4 ++-- ts/src/facilityCore.ts | 4 ++-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/example/ts/src/exampleApi.ts b/example/ts/src/exampleApi.ts index cb0d15f..b8f4f50 100644 --- a/example/ts/src/exampleApi.ts +++ b/example/ts/src/exampleApi.ts @@ -30,7 +30,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets widgets. */ - public getWidgets(request: IGetWidgetsRequest, context?: any): Promise> { + public getWidgets(request: IGetWidgetsRequest, context?: unknown): Promise> { let uri = 'widgets'; const query: string[] = []; request.query == null || query.push('q=' + encodeURIComponent(request.query)); @@ -65,7 +65,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Creates a new widget. */ - public createWidget(request: ICreateWidgetRequest, context?: any): Promise> { + public createWidget(request: ICreateWidgetRequest, context?: unknown): Promise> { const uri = 'widgets'; const fetchRequest: IFetchRequest = { method: 'POST', @@ -89,7 +89,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets the specified widget. */ - public getWidget(request: IGetWidgetRequest, context?: any): Promise> { + public getWidget(request: IGetWidgetRequest, context?: unknown): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -131,7 +131,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Deletes the specified widget. */ - public deleteWidget(request: IDeleteWidgetRequest, context?: any): Promise> { + public deleteWidget(request: IDeleteWidgetRequest, context?: unknown): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -157,7 +157,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Edits widget. */ - public editWidget(request: IEditWidgetRequest, context?: any): Promise> { + public editWidget(request: IEditWidgetRequest, context?: unknown): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -191,7 +191,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets the specified widgets. */ - public getWidgetBatch(request: IGetWidgetBatchRequest, context?: any): Promise> { + public getWidgetBatch(request: IGetWidgetBatchRequest, context?: unknown): Promise> { const uri = 'widgets/get'; const fetchRequest: IFetchRequest = { method: 'POST', @@ -218,7 +218,7 @@ class ExampleApiHttpClient implements IExampleApi { * Gets the widget weight. * @deprecated */ - public getWidgetWeight(request: IGetWidgetWeightRequest, context?: any): Promise> { + public getWidgetWeight(request: IGetWidgetWeightRequest, context?: unknown): Promise> { const uriPartId = request.id != null && encodeURIComponent(request.id); if (!uriPartId) { return Promise.resolve(createRequiredRequestFieldError('id')); @@ -244,7 +244,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets a widget preference. */ - public getPreference(request: IGetPreferenceRequest, context?: any): Promise> { + public getPreference(request: IGetPreferenceRequest, context?: unknown): Promise> { const uriPartKey = request.key != null && encodeURIComponent(request.key); if (!uriPartKey) { return Promise.resolve(createRequiredRequestFieldError('key')); @@ -270,7 +270,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Sets a widget preference. */ - public setPreference(request: ISetPreferenceRequest, context?: any): Promise> { + public setPreference(request: ISetPreferenceRequest, context?: unknown): Promise> { const uriPartKey = request.key != null && encodeURIComponent(request.key); if (!uriPartKey) { return Promise.resolve(createRequiredRequestFieldError('key')); @@ -298,7 +298,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Gets service info. */ - public getInfo(request: IGetInfoRequest, context?: any): Promise> { + public getInfo(request: IGetInfoRequest, context?: unknown): Promise> { const uri = ''; const fetchRequest: IFetchRequest = { method: 'GET', @@ -320,7 +320,7 @@ class ExampleApiHttpClient implements IExampleApi { } /** Demonstrates the default HTTP behavior. */ - public notRestful(request: INotRestfulRequest, context?: any): Promise> { + public notRestful(request: INotRestfulRequest, context?: unknown): Promise> { const uri = 'notRestful'; const fetchRequest: IFetchRequest = { method: 'POST', @@ -341,7 +341,7 @@ class ExampleApiHttpClient implements IExampleApi { }); } - public kitchen(request: IKitchenRequest, context?: any): Promise> { + public kitchen(request: IKitchenRequest, context?: unknown): Promise> { const uri = 'kitchen'; const fetchRequest: IFetchRequest = { method: 'POST', diff --git a/example/ts/src/exampleApiTypes.ts b/example/ts/src/exampleApiTypes.ts index 20cf2fa..7c658d7 100644 --- a/example/ts/src/exampleApiTypes.ts +++ b/example/ts/src/exampleApiTypes.ts @@ -6,42 +6,42 @@ import { IServiceResult, IServiceError } from 'facility-core'; /** Example service for widgets. */ export interface IExampleApi { /** Gets widgets. */ - getWidgets(request: IGetWidgetsRequest, context?: any): Promise>; + getWidgets(request: IGetWidgetsRequest, context?: unknown): Promise>; /** Creates a new widget. */ - createWidget(request: ICreateWidgetRequest, context?: any): Promise>; + createWidget(request: ICreateWidgetRequest, context?: unknown): Promise>; /** Gets the specified widget. */ - getWidget(request: IGetWidgetRequest, context?: any): Promise>; + getWidget(request: IGetWidgetRequest, context?: unknown): Promise>; /** Deletes the specified widget. */ - deleteWidget(request: IDeleteWidgetRequest, context?: any): Promise>; + deleteWidget(request: IDeleteWidgetRequest, context?: unknown): Promise>; /** Edits widget. */ - editWidget(request: IEditWidgetRequest, context?: any): Promise>; + editWidget(request: IEditWidgetRequest, context?: unknown): Promise>; /** Gets the specified widgets. */ - getWidgetBatch(request: IGetWidgetBatchRequest, context?: any): Promise>; + getWidgetBatch(request: IGetWidgetBatchRequest, context?: unknown): Promise>; /** * Gets the widget weight. * @deprecated */ - getWidgetWeight(request: IGetWidgetWeightRequest, context?: any): Promise>; + getWidgetWeight(request: IGetWidgetWeightRequest, context?: unknown): Promise>; /** Gets a widget preference. */ - getPreference(request: IGetPreferenceRequest, context?: any): Promise>; + getPreference(request: IGetPreferenceRequest, context?: unknown): Promise>; /** Sets a widget preference. */ - setPreference(request: ISetPreferenceRequest, context?: any): Promise>; + setPreference(request: ISetPreferenceRequest, context?: unknown): Promise>; /** Gets service info. */ - getInfo(request: IGetInfoRequest, context?: any): Promise>; + getInfo(request: IGetInfoRequest, context?: unknown): Promise>; /** Demonstrates the default HTTP behavior. */ - notRestful(request: INotRestfulRequest, context?: any): Promise>; + notRestful(request: INotRestfulRequest, context?: unknown): Promise>; - kitchen(request: IKitchenRequest, context?: any): Promise>; + kitchen(request: IKitchenRequest, context?: unknown): Promise>; } /** Request for GetWidgets. */ diff --git a/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs b/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs index 9697ed5..6682851 100644 --- a/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs +++ b/src/Facility.CodeGen.JavaScript/JavaScriptGenerator.cs @@ -84,7 +84,7 @@ public override CodeGenOutput GenerateOutput(ServiceInfo service) var capMethodName = CodeGenUtility.Capitalize(methodName); code.WriteLineSkipOnce(); WriteJsDoc(code, httpMethodInfo.ServiceMethod); - code.WriteLine($"{methodName}(request: I{capMethodName}Request, context?: any): Promise>;"); + code.WriteLine($"{methodName}(request: I{capMethodName}Request, context?: unknown): Promise>;"); } } @@ -190,7 +190,7 @@ public override CodeGenOutput GenerateOutput(ServiceInfo service) code.WriteLine(); WriteJsDoc(code, httpMethodInfo.ServiceMethod); - using (code.Block(IfTypeScript("public ") + $"{methodName}(request" + IfTypeScript($": I{capMethodName}Request") + ", context" + IfTypeScript("?: any") + ")" + IfTypeScript($": Promise>") + " {", "}")) + using (code.Block(IfTypeScript("public ") + $"{methodName}(request" + IfTypeScript($": I{capMethodName}Request") + ", context" + IfTypeScript("?: unknown") + ")" + IfTypeScript($": Promise>") + " {", "}")) { var hasPathFields = httpMethodInfo.PathFields.Count != 0; var jsUriDelim = hasPathFields ? "`" : "'"; diff --git a/ts/src/facilityCore.ts b/ts/src/facilityCore.ts index 76c1c61..22ed707 100644 --- a/ts/src/facilityCore.ts +++ b/ts/src/facilityCore.ts @@ -35,7 +35,7 @@ export interface IHttpClientOptions { export namespace HttpClientUtility { /** The fetch function. */ export interface IFetch { - (uri: string, request: IFetchRequest, context?: any): Promise; + (uri: string, request: IFetchRequest, context?: unknown): Promise; } /** The minimal fetch request. */ @@ -82,7 +82,7 @@ export namespace HttpClientUtility { fetch: IFetch, uri: string, request: IFetchRequest, - context?: any + context?: unknown ): Promise { return fetch(uri, request, context).then((response) => { if (!response.headers || !response.status || typeof response.json !== 'function') { From ec7e2ff50c23966620af437c1ea0f79c37f61bf6 Mon Sep 17 00:00:00 2001 From: Ed Ball Date: Thu, 18 Nov 2021 15:12:50 -0800 Subject: [PATCH 3/3] Publish beta packages. --- Directory.Build.props | 3 ++- FacilityJavaScript.sln | 1 + ReleaseNotes.md | 6 ++++++ ReleaseNotesNpm.md | 11 +++++++++++ ts/package.json | 2 +- 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 ReleaseNotesNpm.md diff --git a/Directory.Build.props b/Directory.Build.props index ddc1c93..d5fb9e3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,8 @@ - 2.2.0 + 2.3.0 + beta.1 9.0 enable true diff --git a/FacilityJavaScript.sln b/FacilityJavaScript.sln index ab45f2b..c220fb3 100644 --- a/FacilityJavaScript.sln +++ b/FacilityJavaScript.sln @@ -19,6 +19,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ts\package.json = ts\package.json README.md = README.md ReleaseNotes.md = ReleaseNotes.md + ReleaseNotesNpm.md = ReleaseNotesNpm.md EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Facility.CodeGen.JavaScript", "src\Facility.CodeGen.JavaScript\Facility.CodeGen.JavaScript.csproj", "{89B9867C-5124-49BE-B201-0F1D8E9F7738}" diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 8717e1f..361eadb 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,11 @@ # Release Notes +These are the NuGet package releases. See also [npm Release Notes](ReleaseNotesNpm.md). + +## 2.3.0-beta.1 + +* Add `context` to request methods. + ## 2.2.0 * Include string enums for enums when generating TypeScript. diff --git a/ReleaseNotesNpm.md b/ReleaseNotesNpm.md new file mode 100644 index 0000000..6d579ee --- /dev/null +++ b/ReleaseNotesNpm.md @@ -0,0 +1,11 @@ +# Release Notes (npm) + +These are `facility-core` npm package releases. See also [Release Notes](ReleaseNotes.md). + +## 2.2.0-beta.1 + +* Add `context` to request methods. + +## 2.1.1 + +* Start tracking version history. diff --git a/ts/package.json b/ts/package.json index 3adb9a0..fc34c01 100644 --- a/ts/package.json +++ b/ts/package.json @@ -1,6 +1,6 @@ { "name": "facility-core", - "version": "2.1.1", + "version": "2.2.0-beta.1", "description": "Common code for the Facility API Framework.", "scripts": { "build": "tsc && eslint src --ext .ts",