@oystehr/sdk 4.3.7 → 4.3.9

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 (53) hide show
  1. package/README.md +105 -41
  2. package/dist/cjs/client/client.cjs +137 -5
  3. package/dist/cjs/client/client.cjs.map +1 -1
  4. package/dist/cjs/client/client.d.ts +28 -3
  5. package/dist/cjs/index.min.cjs +1 -1
  6. package/dist/cjs/index.min.cjs.map +1 -1
  7. package/dist/cjs/resources/classes/fhir-ext.cjs +108 -17
  8. package/dist/cjs/resources/classes/fhir-ext.cjs.map +1 -1
  9. package/dist/cjs/resources/classes/fhir-ext.d.ts +67 -12
  10. package/dist/cjs/resources/classes/fhir.cjs +3 -0
  11. package/dist/cjs/resources/classes/fhir.cjs.map +1 -1
  12. package/dist/cjs/resources/classes/fhir.d.ts +3 -0
  13. package/dist/cjs/resources/classes/zambda-ext.cjs +23 -3
  14. package/dist/cjs/resources/classes/zambda-ext.cjs.map +1 -1
  15. package/dist/cjs/resources/classes/zambda-ext.d.ts +3 -0
  16. package/dist/cjs/resources/classes/zambda.cjs +13 -0
  17. package/dist/cjs/resources/classes/zambda.cjs.map +1 -1
  18. package/dist/cjs/resources/classes/zambda.d.ts +12 -1
  19. package/dist/cjs/resources/types/ZambdaGetPresignedUrlParams.d.ts +11 -0
  20. package/dist/cjs/resources/types/ZambdaGetPresignedUrlResponse.d.ts +9 -0
  21. package/dist/cjs/resources/types/fhir.d.ts +67 -0
  22. package/dist/cjs/resources/types/index.d.ts +2 -0
  23. package/dist/esm/client/client.d.ts +28 -3
  24. package/dist/esm/client/client.js +137 -5
  25. package/dist/esm/client/client.js.map +1 -1
  26. package/dist/esm/index.min.js +1 -1
  27. package/dist/esm/index.min.js.map +1 -1
  28. package/dist/esm/resources/classes/fhir-ext.d.ts +67 -12
  29. package/dist/esm/resources/classes/fhir-ext.js +107 -19
  30. package/dist/esm/resources/classes/fhir-ext.js.map +1 -1
  31. package/dist/esm/resources/classes/fhir.d.ts +3 -0
  32. package/dist/esm/resources/classes/fhir.js +4 -1
  33. package/dist/esm/resources/classes/fhir.js.map +1 -1
  34. package/dist/esm/resources/classes/zambda-ext.d.ts +3 -0
  35. package/dist/esm/resources/classes/zambda-ext.js +23 -4
  36. package/dist/esm/resources/classes/zambda-ext.js.map +1 -1
  37. package/dist/esm/resources/classes/zambda.d.ts +12 -1
  38. package/dist/esm/resources/classes/zambda.js +14 -1
  39. package/dist/esm/resources/classes/zambda.js.map +1 -1
  40. package/dist/esm/resources/types/ZambdaGetPresignedUrlParams.d.ts +11 -0
  41. package/dist/esm/resources/types/ZambdaGetPresignedUrlResponse.d.ts +9 -0
  42. package/dist/esm/resources/types/fhir.d.ts +67 -0
  43. package/dist/esm/resources/types/index.d.ts +2 -0
  44. package/package.json +1 -1
  45. package/src/client/client.ts +214 -7
  46. package/src/resources/classes/fhir-ext.ts +278 -38
  47. package/src/resources/classes/fhir.ts +3 -0
  48. package/src/resources/classes/zambda-ext.ts +30 -3
  49. package/src/resources/classes/zambda.ts +18 -0
  50. package/src/resources/types/ZambdaGetPresignedUrlParams.ts +13 -0
  51. package/src/resources/types/ZambdaGetPresignedUrlResponse.ts +11 -0
  52. package/src/resources/types/fhir.ts +88 -0
  53. package/src/resources/types/index.ts +2 -0
@@ -1,15 +1,35 @@
1
1
  'use strict';
2
2
 
3
+ var index = require('../../errors/index.cjs');
4
+
3
5
  function baseUrlThunk() {
4
- return this.config.services?.['projectApiUrl'] ?? 'https://project-api.zapehr.com/v1';
6
+ return this.config.services?.['zambdaApiUrl'] ?? 'https://zambda-api.zapehr.com/v1';
5
7
  }
6
8
  async function uploadFile({ id, file, filename, }) {
7
- const uploadUrl = await this.request('/zambda/{id}/s3-upload', 'post', baseUrlThunk.bind(this))({ id, filename });
8
- await fetch(uploadUrl.signedUrl, {
9
+ const uploadUrl = await this.request('/zambda/{id}/presigned-url', 'post', baseUrlThunk.bind(this))({ id, action: 'upload', filename });
10
+ const response = await fetch(uploadUrl.signedUrl, {
9
11
  method: 'PUT',
10
12
  body: file,
11
13
  });
14
+ if (!response.ok) {
15
+ throw new index.OystehrSdkError({ message: 'Failed to upload file', code: response.status, cause: response.statusText });
16
+ }
17
+ }
18
+ async function downloadFile({ id }) {
19
+ const downloadUrl = await this.request('/zambda/{id}/presigned-url', 'post', baseUrlThunk.bind(this))({ id, action: 'download' });
20
+ const response = await fetch(downloadUrl.signedUrl, {
21
+ method: 'GET',
22
+ });
23
+ if (!response.ok) {
24
+ throw new index.OystehrSdkError({
25
+ message: 'Failed to download file',
26
+ code: response.status,
27
+ cause: response.statusText,
28
+ });
29
+ }
30
+ return response.arrayBuffer();
12
31
  }
13
32
 
33
+ exports.downloadFile = downloadFile;
14
34
  exports.uploadFile = uploadFile;
15
35
  //# sourceMappingURL=zambda-ext.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"zambda-ext.cjs","sources":["../../../../src/resources/classes/zambda-ext.ts"],"sourcesContent":["import { SDKResource } from '../../client/client';\n\nfunction baseUrlThunk(this: SDKResource): string {\n return this.config.services?.['projectApiUrl'] ?? 'https://project-api.zapehr.com/v1';\n}\n\nexport async function uploadFile(\n this: SDKResource,\n {\n id,\n file,\n filename,\n }: {\n id: string;\n file: Blob;\n filename?: string | undefined;\n }\n): Promise<void> {\n const uploadUrl = await this.request('/zambda/{id}/s3-upload', 'post', baseUrlThunk.bind(this))({ id, filename });\n await fetch(uploadUrl.signedUrl, {\n method: 'PUT',\n body: file,\n });\n}\n"],"names":[],"mappings":";;AAEA,SAAS,YAAY,GAAA;IACnB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,eAAe,CAAC,IAAI,mCAAmC;AACvF;AAEO,eAAe,UAAU,CAE9B,EACE,EAAE,EACF,IAAI,EACJ,QAAQ,GAKT,EAAA;IAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;AACjH,IAAA,MAAM,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE;AAC/B,QAAA,MAAM,EAAE,KAAK;AACb,QAAA,IAAI,EAAE,IAAI;AACX,KAAA,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"zambda-ext.cjs","sources":["../../../../src/resources/classes/zambda-ext.ts"],"sourcesContent":["import { SDKResource } from '../../client/client';\nimport { OystehrSdkError } from '../../errors';\n\nfunction baseUrlThunk(this: SDKResource): string {\n return this.config.services?.['zambdaApiUrl'] ?? 'https://zambda-api.zapehr.com/v1';\n}\n\nexport async function uploadFile(\n this: SDKResource,\n {\n id,\n file,\n filename,\n }: {\n id: string;\n file: Blob;\n filename?: string | undefined;\n }\n): Promise<void> {\n const uploadUrl = await this.request(\n '/zambda/{id}/presigned-url',\n 'post',\n baseUrlThunk.bind(this)\n )({ id, action: 'upload', filename });\n const response = await fetch(uploadUrl.signedUrl, {\n method: 'PUT',\n body: file,\n });\n if (!response.ok) {\n throw new OystehrSdkError({ message: 'Failed to upload file', code: response.status, cause: response.statusText });\n }\n}\n\nexport async function downloadFile(this: SDKResource, { id }: { id: string }): Promise<ArrayBuffer> {\n const downloadUrl = await this.request(\n '/zambda/{id}/presigned-url',\n 'post',\n baseUrlThunk.bind(this)\n )({ id, action: 'download' });\n const response = await fetch(downloadUrl.signedUrl, {\n method: 'GET',\n });\n if (!response.ok) {\n throw new OystehrSdkError({\n message: 'Failed to download file',\n code: response.status,\n cause: response.statusText,\n });\n }\n return response.arrayBuffer();\n}\n"],"names":["OystehrSdkError"],"mappings":";;;;AAGA,SAAS,YAAY,GAAA;IACnB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,IAAI,kCAAkC;AACrF;AAEO,eAAe,UAAU,CAE9B,EACE,EAAE,EACF,IAAI,EACJ,QAAQ,GAKT,EAAA;AAED,IAAA,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAClC,4BAA4B,EAC5B,MAAM,EACN,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CACxB,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE;AAChD,QAAA,MAAM,EAAE,KAAK;AACb,QAAA,IAAI,EAAE,IAAI;AACX,KAAA,CAAC;AACF,IAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChB,MAAM,IAAIA,qBAAe,CAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC;IACpH;AACF;AAEO,eAAe,YAAY,CAAoB,EAAE,EAAE,EAAkB,EAAA;IAC1E,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,CACpC,4BAA4B,EAC5B,MAAM,EACN,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CACxB,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE;AAClD,QAAA,MAAM,EAAE,KAAK;AACd,KAAA,CAAC;AACF,IAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChB,MAAM,IAAIA,qBAAe,CAAC;AACxB,YAAA,OAAO,EAAE,yBAAyB;YAClC,IAAI,EAAE,QAAQ,CAAC,MAAM;YACrB,KAAK,EAAE,QAAQ,CAAC,UAAU;AAC3B,SAAA,CAAC;IACJ;AACA,IAAA,OAAO,QAAQ,CAAC,WAAW,EAAE;AAC/B;;;;;"}
@@ -4,3 +4,6 @@ export declare function uploadFile(this: SDKResource, { id, file, filename, }: {
4
4
  file: Blob;
5
5
  filename?: string | undefined;
6
6
  }): Promise<void>;
7
+ export declare function downloadFile(this: SDKResource, { id }: {
8
+ id: string;
9
+ }): Promise<ArrayBuffer>;
@@ -12,6 +12,7 @@ class Zambda extends client.SDKResource {
12
12
  return this.config.services?.['zambdaApiUrl'] ?? 'https://zambda-api.zapehr.com/v1';
13
13
  }
14
14
  uploadFile = zambdaExt.uploadFile;
15
+ downloadFile = zambdaExt.downloadFile;
15
16
  /**
16
17
  * Get a list of all Zambda Functions in the Project. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.
17
18
  *
@@ -75,6 +76,8 @@ class Zambda extends client.SDKResource {
75
76
  return this.request('/zambda/{id}/execute-public', 'post', this.#baseUrlThunk.bind(this))(params, request);
76
77
  }
77
78
  /**
79
+ * **Deprecated.** Use `POST /zambda/{id}/presigned-url` with `action: "upload"` instead. This endpoint will be removed in future releases.
80
+ *
78
81
  * Returns a URL that is used to deploy code to the Zambda Function with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.
79
82
  *
80
83
  * Access Policy Action: `Zambda:UpdateFunction`
@@ -83,6 +86,16 @@ class Zambda extends client.SDKResource {
83
86
  s3Upload(params, request) {
84
87
  return this.request('/zambda/{id}/s3-upload', 'post', this.#baseUrlThunk.bind(this))(params, request);
85
88
  }
89
+ /**
90
+ * Returns a presigned URL to upload or download code for the Zambda Function with the provided ID. Pass `action: "upload"` to get a URL for deploying a new code zip, or `action: "download"` to get a URL for retrieving the currently deployed zip. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.
91
+ *
92
+ * Upload: Access Policy Action: `Zambda:UpdateFunction`
93
+ * Download: Access Policy Action: `Zambda:GetFunctionSource`
94
+ * Access Policy Resource: `Zambda:Function`
95
+ */
96
+ getPresignedUrl(params, request) {
97
+ return this.request('/zambda/{id}/presigned-url', 'post', this.#baseUrlThunk.bind(this))(params, request);
98
+ }
86
99
  }
87
100
 
88
101
  exports.Zambda = Zambda;
@@ -1 +1 @@
1
- {"version":3,"file":"zambda.cjs","sources":["../../../../src/resources/classes/zambda.ts"],"sourcesContent":["// AUTOGENERATED -- DO NOT EDIT\n\nimport {\n OystehrClientRequest,\n ZambdaCreateParams,\n ZambdaCreateResponse,\n ZambdaDeleteParams,\n ZambdaExecuteParams,\n ZambdaExecutePublicParams,\n ZambdaExecutePublicResponse,\n ZambdaExecuteResponse,\n ZambdaGetParams,\n ZambdaGetResponse,\n ZambdaListResponse,\n ZambdaS3UploadParams,\n ZambdaS3UploadResponse,\n ZambdaUpdateParams,\n ZambdaUpdateResponse,\n} from '../..';\nimport { SDKResource } from '../../client/client';\nimport { OystehrConfig } from '../../config';\nimport * as ext from './zambda-ext';\n\nexport class Zambda extends SDKResource {\n constructor(config: OystehrConfig) {\n super(config);\n }\n #baseUrlThunk(): string {\n return this.config.services?.['zambdaApiUrl'] ?? 'https://zambda-api.zapehr.com/v1';\n }\n uploadFile = ext.uploadFile;\n /**\n * Get a list of all Zambda Functions in the Project. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:ListAllFunctions`\n * Access Policy Resource: `Zambda:Function`\n */\n list(request?: OystehrClientRequest): Promise<ZambdaListResponse> {\n return this.request('/zambda', 'get', this.#baseUrlThunk.bind(this))(request);\n }\n /**\n * Create a new Zambda Function. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:CreateFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n create(params: ZambdaCreateParams, request?: OystehrClientRequest): Promise<ZambdaCreateResponse> {\n return this.request('/zambda', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Get the Zambda Function with the provided ID or name. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:GetFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n get(params: ZambdaGetParams, request?: OystehrClientRequest): Promise<ZambdaGetResponse> {\n return this.request('/zambda/{id}', 'get', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Update the Zambda Function with the provided ID or name. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:UpdateFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n update(params: ZambdaUpdateParams, request?: OystehrClientRequest): Promise<ZambdaUpdateResponse> {\n return this.request('/zambda/{id}', 'patch', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Delete the Zambda Function with the provided ID or name. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:DeleteFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n delete(params: ZambdaDeleteParams, request?: OystehrClientRequest): Promise<void> {\n return this.request('/zambda/{id}', 'delete', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Execute the [Authenticated Zambda Function](https://docs.oystehr.com/oystehr/services/zambda/types/authenticated/) with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:InvokeFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n execute(params: ZambdaExecuteParams, request?: OystehrClientRequest): Promise<ZambdaExecuteResponse> {\n return this.request('/zambda/{id}/execute', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Execute the [Public Zambda Function](https://docs.oystehr.com/oystehr/services/zambda/types/public/) with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Execute a zambda that has method http_open. This endpoint is public so there are no access policy requirements.\n */\n executePublic(\n params: ZambdaExecutePublicParams,\n request?: OystehrClientRequest\n ): Promise<ZambdaExecutePublicResponse> {\n return this.request('/zambda/{id}/execute-public', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Returns a URL that is used to deploy code to the Zambda Function with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:UpdateFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n s3Upload(params: ZambdaS3UploadParams, request?: OystehrClientRequest): Promise<ZambdaS3UploadResponse> {\n return this.request('/zambda/{id}/s3-upload', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n}\n"],"names":["SDKResource","ext.uploadFile"],"mappings":";;;;;AAAA;AAuBM,MAAO,MAAO,SAAQA,kBAAW,CAAA;AACrC,IAAA,WAAA,CAAY,MAAqB,EAAA;QAC/B,KAAK,CAAC,MAAM,CAAC;IACf;IACA,aAAa,GAAA;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,IAAI,kCAAkC;IACrF;AACA,IAAA,UAAU,GAAGC,oBAAc;AAC3B;;;;;AAKG;AACH,IAAA,IAAI,CAAC,OAA8B,EAAA;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/E;AACA;;;;;AAKG;IACH,MAAM,CAAC,MAA0B,EAAE,OAA8B,EAAA;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IACxF;AACA;;;;;AAKG;IACH,GAAG,CAAC,MAAuB,EAAE,OAA8B,EAAA;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5F;AACA;;;;;AAKG;IACH,MAAM,CAAC,MAA0B,EAAE,OAA8B,EAAA;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9F;AACA;;;;;AAKG;IACH,MAAM,CAAC,MAA0B,EAAE,OAA8B,EAAA;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/F;AACA;;;;;AAKG;IACH,OAAO,CAAC,MAA2B,EAAE,OAA8B,EAAA;QACjE,OAAO,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IACrG;AACA;;;;AAIG;IACH,aAAa,CACX,MAAiC,EACjC,OAA8B,EAAA;QAE9B,OAAO,IAAI,CAAC,OAAO,CAAC,6BAA6B,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5G;AACA;;;;;AAKG;IACH,QAAQ,CAAC,MAA4B,EAAE,OAA8B,EAAA;QACnE,OAAO,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IACvG;AACD;;;;"}
1
+ {"version":3,"file":"zambda.cjs","sources":["../../../../src/resources/classes/zambda.ts"],"sourcesContent":["// AUTOGENERATED -- DO NOT EDIT\n\nimport {\n OystehrClientRequest,\n ZambdaCreateParams,\n ZambdaCreateResponse,\n ZambdaDeleteParams,\n ZambdaExecuteParams,\n ZambdaExecutePublicParams,\n ZambdaExecutePublicResponse,\n ZambdaExecuteResponse,\n ZambdaGetParams,\n ZambdaGetPresignedUrlParams,\n ZambdaGetPresignedUrlResponse,\n ZambdaGetResponse,\n ZambdaListResponse,\n ZambdaS3UploadParams,\n ZambdaS3UploadResponse,\n ZambdaUpdateParams,\n ZambdaUpdateResponse,\n} from '../..';\nimport { SDKResource } from '../../client/client';\nimport { OystehrConfig } from '../../config';\nimport * as ext from './zambda-ext';\n\nexport class Zambda extends SDKResource {\n constructor(config: OystehrConfig) {\n super(config);\n }\n #baseUrlThunk(): string {\n return this.config.services?.['zambdaApiUrl'] ?? 'https://zambda-api.zapehr.com/v1';\n }\n uploadFile = ext.uploadFile;\n downloadFile = ext.downloadFile;\n /**\n * Get a list of all Zambda Functions in the Project. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:ListAllFunctions`\n * Access Policy Resource: `Zambda:Function`\n */\n list(request?: OystehrClientRequest): Promise<ZambdaListResponse> {\n return this.request('/zambda', 'get', this.#baseUrlThunk.bind(this))(request);\n }\n /**\n * Create a new Zambda Function. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:CreateFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n create(params: ZambdaCreateParams, request?: OystehrClientRequest): Promise<ZambdaCreateResponse> {\n return this.request('/zambda', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Get the Zambda Function with the provided ID or name. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:GetFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n get(params: ZambdaGetParams, request?: OystehrClientRequest): Promise<ZambdaGetResponse> {\n return this.request('/zambda/{id}', 'get', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Update the Zambda Function with the provided ID or name. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:UpdateFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n update(params: ZambdaUpdateParams, request?: OystehrClientRequest): Promise<ZambdaUpdateResponse> {\n return this.request('/zambda/{id}', 'patch', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Delete the Zambda Function with the provided ID or name. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:DeleteFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n delete(params: ZambdaDeleteParams, request?: OystehrClientRequest): Promise<void> {\n return this.request('/zambda/{id}', 'delete', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Execute the [Authenticated Zambda Function](https://docs.oystehr.com/oystehr/services/zambda/types/authenticated/) with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:InvokeFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n execute(params: ZambdaExecuteParams, request?: OystehrClientRequest): Promise<ZambdaExecuteResponse> {\n return this.request('/zambda/{id}/execute', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Execute the [Public Zambda Function](https://docs.oystehr.com/oystehr/services/zambda/types/public/) with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Execute a zambda that has method http_open. This endpoint is public so there are no access policy requirements.\n */\n executePublic(\n params: ZambdaExecutePublicParams,\n request?: OystehrClientRequest\n ): Promise<ZambdaExecutePublicResponse> {\n return this.request('/zambda/{id}/execute-public', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * **Deprecated.** Use `POST /zambda/{id}/presigned-url` with `action: \"upload\"` instead. This endpoint will be removed in future releases.\n *\n * Returns a URL that is used to deploy code to the Zambda Function with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Access Policy Action: `Zambda:UpdateFunction`\n * Access Policy Resource: `Zambda:Function`\n */\n s3Upload(params: ZambdaS3UploadParams, request?: OystehrClientRequest): Promise<ZambdaS3UploadResponse> {\n return this.request('/zambda/{id}/s3-upload', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n /**\n * Returns a presigned URL to upload or download code for the Zambda Function with the provided ID. Pass `action: \"upload\"` to get a URL for deploying a new code zip, or `action: \"download\"` to get a URL for retrieving the currently deployed zip. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.\n *\n * Upload: Access Policy Action: `Zambda:UpdateFunction`\n * Download: Access Policy Action: `Zambda:GetFunctionSource`\n * Access Policy Resource: `Zambda:Function`\n */\n getPresignedUrl(\n params: ZambdaGetPresignedUrlParams,\n request?: OystehrClientRequest\n ): Promise<ZambdaGetPresignedUrlResponse> {\n return this.request('/zambda/{id}/presigned-url', 'post', this.#baseUrlThunk.bind(this))(params, request);\n }\n}\n"],"names":["SDKResource","ext.uploadFile","ext.downloadFile"],"mappings":";;;;;AAAA;AAyBM,MAAO,MAAO,SAAQA,kBAAW,CAAA;AACrC,IAAA,WAAA,CAAY,MAAqB,EAAA;QAC/B,KAAK,CAAC,MAAM,CAAC;IACf;IACA,aAAa,GAAA;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC,IAAI,kCAAkC;IACrF;AACA,IAAA,UAAU,GAAGC,oBAAc;AAC3B,IAAA,YAAY,GAAGC,sBAAgB;AAC/B;;;;;AAKG;AACH,IAAA,IAAI,CAAC,OAA8B,EAAA;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/E;AACA;;;;;AAKG;IACH,MAAM,CAAC,MAA0B,EAAE,OAA8B,EAAA;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IACxF;AACA;;;;;AAKG;IACH,GAAG,CAAC,MAAuB,EAAE,OAA8B,EAAA;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5F;AACA;;;;;AAKG;IACH,MAAM,CAAC,MAA0B,EAAE,OAA8B,EAAA;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9F;AACA;;;;;AAKG;IACH,MAAM,CAAC,MAA0B,EAAE,OAA8B,EAAA;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/F;AACA;;;;;AAKG;IACH,OAAO,CAAC,MAA2B,EAAE,OAA8B,EAAA;QACjE,OAAO,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IACrG;AACA;;;;AAIG;IACH,aAAa,CACX,MAAiC,EACjC,OAA8B,EAAA;QAE9B,OAAO,IAAI,CAAC,OAAO,CAAC,6BAA6B,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5G;AACA;;;;;;;AAOG;IACH,QAAQ,CAAC,MAA4B,EAAE,OAA8B,EAAA;QACnE,OAAO,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IACvG;AACA;;;;;;AAMG;IACH,eAAe,CACb,MAAmC,EACnC,OAA8B,EAAA;QAE9B,OAAO,IAAI,CAAC,OAAO,CAAC,4BAA4B,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3G;AACD;;;;"}
@@ -1,4 +1,4 @@
1
- import { OystehrClientRequest, ZambdaCreateParams, ZambdaCreateResponse, ZambdaDeleteParams, ZambdaExecuteParams, ZambdaExecutePublicParams, ZambdaExecutePublicResponse, ZambdaExecuteResponse, ZambdaGetParams, ZambdaGetResponse, ZambdaListResponse, ZambdaS3UploadParams, ZambdaS3UploadResponse, ZambdaUpdateParams, ZambdaUpdateResponse } from '../..';
1
+ import { OystehrClientRequest, ZambdaCreateParams, ZambdaCreateResponse, ZambdaDeleteParams, ZambdaExecuteParams, ZambdaExecutePublicParams, ZambdaExecutePublicResponse, ZambdaExecuteResponse, ZambdaGetParams, ZambdaGetPresignedUrlParams, ZambdaGetPresignedUrlResponse, ZambdaGetResponse, ZambdaListResponse, ZambdaS3UploadParams, ZambdaS3UploadResponse, ZambdaUpdateParams, ZambdaUpdateResponse } from '../..';
2
2
  import { SDKResource } from '../../client/client';
3
3
  import { OystehrConfig } from '../../config';
4
4
  import * as ext from './zambda-ext';
@@ -6,6 +6,7 @@ export declare class Zambda extends SDKResource {
6
6
  #private;
7
7
  constructor(config: OystehrConfig);
8
8
  uploadFile: typeof ext.uploadFile;
9
+ downloadFile: typeof ext.downloadFile;
9
10
  /**
10
11
  * Get a list of all Zambda Functions in the Project. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.
11
12
  *
@@ -55,10 +56,20 @@ export declare class Zambda extends SDKResource {
55
56
  */
56
57
  executePublic(params: ZambdaExecutePublicParams, request?: OystehrClientRequest): Promise<ZambdaExecutePublicResponse>;
57
58
  /**
59
+ * **Deprecated.** Use `POST /zambda/{id}/presigned-url` with `action: "upload"` instead. This endpoint will be removed in future releases.
60
+ *
58
61
  * Returns a URL that is used to deploy code to the Zambda Function with the provided ID. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.
59
62
  *
60
63
  * Access Policy Action: `Zambda:UpdateFunction`
61
64
  * Access Policy Resource: `Zambda:Function`
62
65
  */
63
66
  s3Upload(params: ZambdaS3UploadParams, request?: OystehrClientRequest): Promise<ZambdaS3UploadResponse>;
67
+ /**
68
+ * Returns a presigned URL to upload or download code for the Zambda Function with the provided ID. Pass `action: "upload"` to get a URL for deploying a new code zip, or `action: "download"` to get a URL for retrieving the currently deployed zip. [Zambdas](https://docs.oystehr.com/oystehr/services/zambda/) are functions that can be used to execute your code. They can be used to process data received from Oystehr's APIs or to perform operations on third-party services.
69
+ *
70
+ * Upload: Access Policy Action: `Zambda:UpdateFunction`
71
+ * Download: Access Policy Action: `Zambda:GetFunctionSource`
72
+ * Access Policy Resource: `Zambda:Function`
73
+ */
74
+ getPresignedUrl(params: ZambdaGetPresignedUrlParams, request?: OystehrClientRequest): Promise<ZambdaGetPresignedUrlResponse>;
64
75
  }
@@ -0,0 +1,11 @@
1
+ export interface ZambdaGetPresignedUrlParams {
2
+ /**
3
+ * Whether to get a presigned URL for uploading or downloading the Zambda Function code zip.
4
+ */
5
+ action: 'upload' | 'download';
6
+ /**
7
+ * Optional filename for the Zambda Function code zip (upload only). If not provided, the filename will be randomized.
8
+ */
9
+ filename?: string;
10
+ id: string;
11
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The presigned URL for the requested action.
3
+ */
4
+ export interface ZambdaGetPresignedUrlResponse {
5
+ /**
6
+ * The presigned URL to upload or download the Zambda Function code zip.
7
+ */
8
+ signedUrl: string;
9
+ }
@@ -117,4 +117,71 @@ export type BatchInputRequest<F extends FhirResource> = BatchInputGetRequest | B
117
117
  export interface BatchInput<F extends FhirResource> {
118
118
  requests: BatchInputRequest<F>[];
119
119
  }
120
+ export interface FhirAsyncJobHandle {
121
+ jobId: string;
122
+ contentLocation: string;
123
+ mode: FhirAsyncResponseMode;
124
+ }
125
+ export type FhirResponseMode = 'sync' | 'async-bundle' | 'async-bulk';
126
+ export type FhirAsyncResponseMode = 'bundle' | 'bulk';
127
+ export interface FhirAsyncCompletionBundleEntry<T extends FhirResource> {
128
+ response?: {
129
+ status?: string;
130
+ outcome?: OperationOutcome;
131
+ };
132
+ resource?: T | OperationOutcome;
133
+ }
134
+ export type FhirAsyncCompletionBundle<T extends FhirResource> = EntrylessFhirBundle<T | OperationOutcome> & {
135
+ resourceType: 'Bundle';
136
+ type: 'batch-response';
137
+ entry?: Array<FhirAsyncCompletionBundleEntry<T>>;
138
+ };
139
+ export interface FhirAsyncJobInProgress {
140
+ status: 202;
141
+ xProgress?: string;
142
+ retryAfter?: string;
143
+ }
144
+ export interface FhirAsyncJobCompletedBundle<T extends FhirResource = FhirResource> {
145
+ status: 200;
146
+ mode: 'bundle';
147
+ bundle: FhirAsyncCompletionBundle<T>;
148
+ interactionStatus?: string;
149
+ resource?: T | OperationOutcome;
150
+ outcome?: OperationOutcome;
151
+ }
152
+ export interface FhirAsyncBulkOutputFile {
153
+ type: string;
154
+ url: string;
155
+ }
156
+ export interface FhirAsyncBulkManifest {
157
+ transactionTime: string;
158
+ request: string;
159
+ requiresAccessToken: boolean;
160
+ output: FhirAsyncBulkOutputFile[];
161
+ error: FhirAsyncBulkOutputFile[];
162
+ deleted?: FhirAsyncBulkOutputFile[];
163
+ extension?: Record<string, unknown>;
164
+ }
165
+ export interface FhirAsyncJobCompletedBulk {
166
+ status: 200;
167
+ mode: 'bulk';
168
+ manifest: FhirAsyncBulkManifest;
169
+ }
170
+ export interface FhirAsyncJobExpired {
171
+ status: 410;
172
+ }
173
+ export interface FhirAsyncJobNotFound {
174
+ status: 404;
175
+ }
176
+ export interface FhirAsyncJobUnexpected {
177
+ status: Exclude<number, 200 | 202 | 404 | 410>;
178
+ body: unknown;
179
+ }
180
+ export type FhirAsyncJobStatus<T extends FhirResource = FhirResource> = FhirAsyncJobInProgress | FhirAsyncJobCompletedBundle<T> | FhirAsyncJobCompletedBulk | FhirAsyncJobExpired | FhirAsyncJobNotFound | FhirAsyncJobUnexpected;
181
+ export interface FhirAsyncWaitOptions {
182
+ /** Poll interval in milliseconds. Defaults to 1000 (1 second). */
183
+ pollIntervalMs: number;
184
+ /** Maximum wait time in milliseconds before timing out. Defaults to 900000 (15 minutes). */
185
+ timeoutMs: number;
186
+ }
120
187
  export {};
@@ -192,6 +192,8 @@ export * from './ZambdaLogStreamListParams';
192
192
  export * from './ZambdaLogStreamListResponse';
193
193
  export * from './ZambdaS3UploadParams';
194
194
  export * from './ZambdaS3UploadResponse';
195
+ export * from './ZambdaGetPresignedUrlParams';
196
+ export * from './ZambdaGetPresignedUrlResponse';
195
197
  export * from './ZambdaLogStreamSearchParams';
196
198
  export * from './ZambdaLogStreamSearchResponse';
197
199
  export * from './ZambdaLogStreamGetParams';
@@ -1,6 +1,6 @@
1
1
  import { OystehrConfig } from '../config';
2
2
  import { Logger } from '../logger';
3
- import { FhirBundle, FhirResource } from '../resources/types';
3
+ import { FhirAsyncJobHandle, FhirAsyncJobStatus, FhirBundle, FhirResource, FhirResponseMode } from '../resources/types';
4
4
  export declare const defaultProjectApiUrl = "https://project-api.zapehr.com/v1";
5
5
  /**
6
6
  * Optional parameter that can be passed to the client methods. It allows
@@ -24,9 +24,18 @@ export interface OystehrClientRequest {
24
24
  * Unique identifier for this request.
25
25
  */
26
26
  requestId?: string;
27
+ /**
28
+ * Optional execution mode for FHIR requests that support async behavior.
29
+ * Defaults to `sync` when omitted.
30
+ */
31
+ mode?: FhirResponseMode;
27
32
  }
28
33
  interface InternalClientRequest extends OystehrClientRequest {
29
34
  ifMatch?: string;
35
+ /**
36
+ * Internal-only: returns raw response metadata ({ status, headers, body }) instead of throwing on non-2xx statuses.
37
+ */
38
+ rawResponse?: boolean;
30
39
  }
31
40
  type FhirData<T extends FhirResource> = T | T[] | FhirBundle<T>;
32
41
  export type FhirFetcherResponse<T extends FhirData<FhirResource> = any> = T;
@@ -35,14 +44,30 @@ export declare class SDKResource {
35
44
  protected readonly logger: Logger;
36
45
  constructor(config: OystehrConfig);
37
46
  protected request(path: string, method: string, baseUrlThunk: () => string): FetcherFunction;
38
- protected fhirRequest<T extends FhirResource = any>(path: string, method: string): (params: any, request?: InternalClientRequest) => Promise<FhirFetcherResponse<T>>;
47
+ protected fhirRequest<T = FhirResource>(path: string, method: string): {
48
+ (params: any, request: InternalClientRequest & {
49
+ rawResponse: true;
50
+ }, requestMode?: FhirResponseMode): Promise<RawFetcherResponse<T>>;
51
+ (params: any, request?: InternalClientRequest, requestMode?: FhirResponseMode): Promise<T>;
52
+ };
53
+ protected startAsyncJob(path: string, method: string, params: Record<string, unknown>, requestMode: FhirResponseMode, request?: InternalClientRequest): Promise<FhirAsyncJobHandle>;
54
+ protected fetchAsyncJobStatus<T extends FhirResource>(jobId: string, request?: OystehrClientRequest): Promise<FhirAsyncJobStatus<T>>;
55
+ private readHeader;
56
+ private parseAsyncJobId;
57
+ private appendBulkOutputFormat;
58
+ private isBulkManifest;
39
59
  }
40
60
  export type FetcherError = {
41
61
  message: string;
42
62
  code: number;
43
63
  };
44
64
  export type FetcherResponse = any;
45
- export type FetcherFunction = (params?: Record<string, any> | [any] | InternalClientRequest, request?: InternalClientRequest) => Promise<FetcherResponse>;
65
+ export type RawFetcherResponse<T = unknown> = {
66
+ status: number;
67
+ headers: Record<string, string>;
68
+ body: T | null;
69
+ };
70
+ export type FetcherFunction = (params?: Record<string, any> | [any] | InternalClientRequest, request?: InternalClientRequest, requestMode?: FhirResponseMode) => Promise<FetcherResponse>;
46
71
  /**
47
72
  * Adds params to a URLSearchParams object in such a way as to preserve array values.
48
73
  * @param params params
@@ -40,13 +40,13 @@ class SDKResource {
40
40
  };
41
41
  }
42
42
  fhirRequest(path, method) {
43
- return async (params, request) => {
43
+ return async (params, request, requestMode) => {
44
44
  try {
45
45
  const baseUrlThunk = () => this.config.services?.fhirApiUrl ?? defaultFhirApiUrl;
46
46
  const configThunk = () => this.config;
47
47
  const loggerThunk = () => this.logger;
48
48
  // must await here to catch
49
- return await fetcher(baseUrlThunk, configThunk, loggerThunk, path, method)(params, request);
49
+ return await fetcher(baseUrlThunk, configThunk, loggerThunk, path, method)(params, request, requestMode);
50
50
  }
51
51
  catch (err) {
52
52
  // FHIR API error messages are JSON strings
@@ -65,13 +65,133 @@ class SDKResource {
65
65
  }
66
66
  };
67
67
  }
68
+ async startAsyncJob(path, method, params, requestMode, request) {
69
+ const mode = requestMode === 'async-bulk' ? 'bulk' : 'bundle';
70
+ const asyncPath = requestMode === 'async-bulk' ? this.appendBulkOutputFormat(path) : path;
71
+ const raw = await this.fhirRequest(asyncPath, method)(params, {
72
+ ...request,
73
+ rawResponse: true,
74
+ }, requestMode);
75
+ if (raw.status !== 202) {
76
+ throw new OystehrSdkError({
77
+ message: `Expected start async job to return 202 Accepted, received ${raw.status}`,
78
+ code: raw.status,
79
+ });
80
+ }
81
+ const contentLocation = this.readHeader(raw.headers, 'content-location');
82
+ if (!contentLocation) {
83
+ throw new OystehrSdkError({
84
+ message: 'Start Async job response missing Content-Location header',
85
+ code: 500,
86
+ });
87
+ }
88
+ const jobId = this.parseAsyncJobId(contentLocation);
89
+ if (!jobId) {
90
+ throw new OystehrSdkError({
91
+ message: `Could not parse async job id from Content-Location: ${contentLocation}`,
92
+ code: 500,
93
+ });
94
+ }
95
+ return { jobId, contentLocation, mode };
96
+ }
97
+ async fetchAsyncJobStatus(jobId, request) {
98
+ const raw = await this.fhirRequest(`/async-job/${jobId}`, 'GET')({}, {
99
+ ...request,
100
+ rawResponse: true,
101
+ });
102
+ if (raw.status === 202) {
103
+ return {
104
+ status: 202,
105
+ xProgress: this.readHeader(raw.headers, 'x-progress'),
106
+ retryAfter: this.readHeader(raw.headers, 'retry-after'),
107
+ };
108
+ }
109
+ if (raw.status === 410) {
110
+ return { status: 410 };
111
+ }
112
+ if (raw.status === 404) {
113
+ return { status: 404 };
114
+ }
115
+ if (raw.status === 200) {
116
+ if (this.isBulkManifest(raw.body)) {
117
+ return {
118
+ status: 200,
119
+ mode: 'bulk',
120
+ manifest: raw.body,
121
+ };
122
+ }
123
+ const bundle = raw.body;
124
+ if (bundle?.resourceType === 'Bundle' && bundle?.type === 'batch-response') {
125
+ const entry0 = bundle.entry?.[0];
126
+ const interactionStatus = entry0?.response?.status;
127
+ const resource = entry0?.resource;
128
+ const outcome = entry0?.response?.outcome;
129
+ return {
130
+ status: 200,
131
+ mode: 'bundle',
132
+ bundle,
133
+ interactionStatus,
134
+ resource,
135
+ outcome,
136
+ };
137
+ }
138
+ return {
139
+ status: 200,
140
+ body: raw.body,
141
+ };
142
+ }
143
+ return {
144
+ status: raw.status,
145
+ body: raw.body,
146
+ };
147
+ }
148
+ readHeader(headers, name) {
149
+ const direct = headers[name];
150
+ if (direct != null) {
151
+ return direct;
152
+ }
153
+ const lower = name.toLowerCase();
154
+ const key = Object.keys(headers).find((h) => h.toLowerCase() === lower);
155
+ return key ? headers[key] : undefined;
156
+ }
157
+ parseAsyncJobId(contentLocation) {
158
+ const segments = contentLocation.split('/').filter(Boolean);
159
+ const asyncJobIndex = segments.lastIndexOf('async-job');
160
+ if (asyncJobIndex < 0 || asyncJobIndex + 1 >= segments.length) {
161
+ return undefined;
162
+ }
163
+ return segments[asyncJobIndex + 1];
164
+ }
165
+ appendBulkOutputFormat(path) {
166
+ const separator = path.includes('?') ? '&' : '?';
167
+ return `${path}${separator}_outputFormat=${encodeURIComponent('application/fhir+ndjson')}`;
168
+ }
169
+ isBulkManifest(body) {
170
+ if (body == null || typeof body !== 'object') {
171
+ return false;
172
+ }
173
+ const maybe = body;
174
+ return (typeof maybe.transactionTime === 'string' &&
175
+ typeof maybe.request === 'string' &&
176
+ typeof maybe.requiresAccessToken === 'boolean' &&
177
+ Array.isArray(maybe.output) &&
178
+ Array.isArray(maybe.error));
179
+ }
68
180
  }
69
181
  function isInternalClientRequest(request) {
70
182
  return ('accessToken' in request ||
71
183
  ('projectId' in request && validate(request.projectId)) ||
72
184
  ('contentType' in request && request.contentType?.split('/').length === 2) ||
73
185
  'requestId' in request ||
74
- ('ifMatch' in request && request.ifMatch.startsWith('W/"')));
186
+ ('ifMatch' in request && request.ifMatch.startsWith('W/"')) ||
187
+ 'mode' in request ||
188
+ 'rawResponse' in request);
189
+ }
190
+ function getPreferHeaderFromMode(mode) {
191
+ if (mode === 'async-bundle' || mode === 'async-bulk') {
192
+ return 'respond-async';
193
+ }
194
+ return undefined;
75
195
  }
76
196
  /**
77
197
  * Parse XML response in format <response><status>...</status><output>...</output></response>
@@ -94,7 +214,7 @@ function parseXmlResponse(xmlString) {
94
214
  }
95
215
  }
96
216
  function fetcher(baseUrlThunk, configThunk, loggerThunk, path, methodParam) {
97
- return async (params, request) => {
217
+ return async (params, request, requestMode) => {
98
218
  // this function supports multiple signatures. fetcher(baseUrl, path, method)(params, request) or fetcher(baseUrl, path, method)(request)
99
219
  // or fetcher(baseUrl, path, method)(params) or fetcher(baseUrl, path, method)(). the types for this are handled by Client<Path, Methods>
100
220
  // and this is the backend implementation behind it. the heuristic we're using is that if the first param is an object with an accessToken
@@ -158,6 +278,7 @@ function fetcher(baseUrlThunk, configThunk, loggerThunk, path, methodParam) {
158
278
  path,
159
279
  requestId: requestCtx?.requestId,
160
280
  });
281
+ const preferHeader = getPreferHeaderFromMode(requestMode);
161
282
  const headers = Object.assign(projectId
162
283
  ? {
163
284
  'x-zapehr-project-id': projectId,
@@ -165,7 +286,7 @@ function fetcher(baseUrlThunk, configThunk, loggerThunk, path, methodParam) {
165
286
  }
166
287
  : {}, {
167
288
  'content-type': requestCtx?.contentType ?? 'application/json',
168
- }, accessToken ? { Authorization: `Bearer ${accessToken}` } : {}, requestCtx?.ifMatch ? { 'If-Match': requestCtx.ifMatch } : {}, { 'x-oystehr-request-id': requestCtx?.requestId });
289
+ }, preferHeader ? { Prefer: preferHeader } : {}, accessToken ? { Authorization: `Bearer ${accessToken}` } : {}, requestCtx?.ifMatch ? { 'If-Match': requestCtx.ifMatch } : {}, { 'x-oystehr-request-id': requestCtx?.requestId });
169
290
  const retryConfig = {
170
291
  retries: config.retry?.retries ?? 3,
171
292
  jitter: config.retry?.jitter ?? 20,
@@ -238,6 +359,17 @@ function fetcher(baseUrlThunk, configThunk, loggerThunk, path, methodParam) {
238
359
  url,
239
360
  requestId: requestCtx?.requestId,
240
361
  });
362
+ if (requestCtx?.rawResponse) {
363
+ const headersRecord = {};
364
+ response.headers.forEach((value, key) => {
365
+ headersRecord[key] = value;
366
+ });
367
+ return {
368
+ status: response.status,
369
+ headers: headersRecord,
370
+ body: responseJson ?? responseBody,
371
+ };
372
+ }
241
373
  const isError = !response.ok || response.status >= 400;
242
374
  if (isError) {
243
375
  const errObj = {