@openedc/sdk 3.8.1 → 3.8.2-next.1

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/README.md CHANGED
@@ -1,21 +1,26 @@
1
1
  <br>
2
2
  <div align="center">
3
- <img src="../public/icons/custom/openedc.svg" alt="OpenEDC Logo" width="48">
3
+ <img src="https://openedc.health/logo.png" alt="OpenEDC Logo" width="48">
4
4
 
5
5
  ### SDK for the OpenEDC Health Platform
6
6
  #### OpenEDC Health is a modular, standards-compliant platform for medical research
7
7
  </div>
8
8
  <br>
9
9
 
10
- The official TypeScript SDK for the OpenEDC Health Platform — a modular, standards-compliant platform for medical research.
10
+ The official TypeScript SDK for the OpenEDC Health Platform.
11
11
 
12
12
  Fully typed end-to-end, it runs on any modern JavaScript runtime (Node, Deno, Bun) and gives you a clean, expressive API to work with all aspects of a clinical study:
13
13
 
14
- - **Query** metadata, clinical data, administrative data, and more with filtering, sorting, and cross-project support
15
- - **Mutate** study data with a single `.commit()` call, including cascading saves across related records
16
- - **Stream live updates** via reactive queries that automatically reflect changes in real time
17
- - **Track changes** with a built-in audit trail for all relevant study data
18
- - **Manage files** with resumable uploads and signed downloads, supporting files up to 5 GB
14
+ - **Data access:** Query study metadata, clinical data, administrative data, and more, with flexible filtering, sorting, and cross-project support
15
+ - **Data editing:** Create or modify study data reliably with a single commit call, with all changes automatically recorded in the audit trail
16
+ - **Audit trail:** Query the complete history of all study data changes, supporting data integrity and GCP compliance
17
+ - **Live updates:** Subscribe to real-time changes via live queries that automatically reflect updates as they happen
18
+ - **File management:** Upload and download files securely with resumable transfers, supporting files up to 5 GB
19
+
20
+ The OpenEDC Health platform and the SDK are built around PostgreSQL Row Level Security (RLS) Policies and Triggers. This ensures that:
21
+
22
+ - **Scoped access:** Only the projects and data the authenticated user has been granted access to can be read or modified through the SDK
23
+ - **Automated records:** All data changes are automatically recorded in the audit trail, attributed to the user with a server-side timestamp
19
24
 
20
25
  ## Getting started
21
26
 
@@ -34,6 +39,12 @@ deno add npm:@openedc/sdk
34
39
 
35
40
  ### Initialization
36
41
 
42
+ Before you can authenticate within the SDK, please create an API key in the OpenEDC Health application. Click on your name in the bottom-left corner, select *Account*, and then create an API key at the bottom of the dialog.
43
+
44
+ ![API key creation](https://cappie.studio/images/74d309b5-ee64-4302-9a5c-3b33df49ede4.jpg)
45
+
46
+ The API key can then be used as shown below.
47
+
37
48
  ```ts
38
49
  import { login, logout } from "@openedc/sdk";
39
50
 
@@ -69,8 +80,8 @@ const location = await Location
69
80
  const subjects = await SubjectData
70
81
  .where({ location })
71
82
  .project(project)
72
- .sort("createdDate")
73
- .asc().all();
83
+ .sort("createdDate").asc()
84
+ .all();
74
85
 
75
86
  // Create a new subject within a location
76
87
  const subject = await new SubjectData("Patient-001", location.reference)
@@ -86,12 +97,12 @@ await subject.set({ subjectKey: "Patient-003" }).commit();
86
97
 
87
98
  #### Global project scope
88
99
 
100
+ Instead of specifying the project per call, a global scope can be set for all upcoming statements. This works well for linear, sequential flows but should be avoided in parallel or callback-based code that handles multiple projects concurrently. Assumed for the rest of the examples.
101
+
89
102
  ```ts
90
103
  import { Location, SubjectData } from "@openedc/sdk";
91
104
 
92
- // Instead of specifying the project for each query or commit, it can also be scoped globally for
93
- // all upcoming statements. This can be changed at any time but shouldn't be used when handling
94
- // multiple projects at the same time. Will be assumed to be set for the rest of the examples.
105
+ // Scope subsequent queries and commits
95
106
  scope(project);
96
107
 
97
108
  const sameLocation = await Location
@@ -100,8 +111,8 @@ const sameLocation = await Location
100
111
 
101
112
  const sameSubjects = await SubjectData
102
113
  .where({ location })
103
- .sort("createdDate")
104
- .asc().all();
114
+ .sort("createdDate").asc()
115
+ .all();
105
116
 
106
117
  // Create a new subject (note that Patient-003 would result in a unique constraint violation)
107
118
  const newSubject = await new SubjectData("Patient-004").commit();
package/openedc-sdk.js CHANGED
@@ -10636,11 +10636,13 @@ const kt = class kt {
10636
10636
  const [o, ...a] = s.split("."), u = a.at(0) === "ref" ? this.getLocalization(o, { locale: n, interpolation: r }) : r == null ? void 0 : r[o];
10637
10637
  return String(a.reduce(
10638
10638
  (c, h) => this.transform(c, h, n),
10639
- u ?? "—"
10639
+ u
10640
10640
  ));
10641
10641
  });
10642
10642
  }
10643
10643
  static transform(e, r, n) {
10644
+ if (e == null || e === "")
10645
+ return "—";
10644
10646
  switch (r) {
10645
10647
  case "upper":
10646
10648
  return String(e).toUpperCase();
@@ -10663,7 +10665,7 @@ const kt = class kt {
10663
10665
  }
10664
10666
  }
10665
10667
  };
10666
- kt.SELECTED_LANGUAGE = "SELECTED_LANGUAGE", kt.translationGlob = {}, kt.defaults = {}, kt.overwrites = {}, kt.localizedElements = /* @__PURE__ */ new Map(), kt.defaultLocale = new Intl.Locale("en"), kt.currentLocale = kt.defaultLocale;
10668
+ kt.SELECTED_LANGUAGE = "SELECTED_LANGUAGE", kt.defaults = {}, kt.overwrites = {}, kt.defaultLocale = new Intl.Locale("en"), kt.currentLocale = kt.defaultLocale, kt.translationGlob = {}, kt.localizedElements = /* @__PURE__ */ new Map();
10667
10669
  let ye = kt;
10668
10670
  var _p = Object.defineProperty, Ep = Object.getOwnPropertyDescriptor, Ur = (t, e, r, n) => {
10669
10671
  for (var i = n > 1 ? void 0 : n ? Ep(e, r) : e, s = t.length - 1, o; s >= 0; s--)
@@ -20777,7 +20779,7 @@ const xD = async ({ serverUrl: t, apiKey: e }) => {
20777
20779
  }
20778
20780
  }
20779
20781
  });
20780
- const s = await fetch(t + "/api/auth/api-key", {
20782
+ const s = await fetch(t + "/api/auth/token", {
20781
20783
  method: "POST",
20782
20784
  headers: {
20783
20785
  Authorization: `Bearer ${e}`
@@ -20786,9 +20788,10 @@ const xD = async ({ serverUrl: t, apiKey: e }) => {
20786
20788
  if (!s.ok) throw new Error("Invalid API key");
20787
20789
  const { email: o, token: a, type: u } = await s.json(), { data: c, error: h } = await Yn.auth.verifyOtp({ email: o, token: a, type: u });
20788
20790
  if (!c.user) throw h ?? new Error("Error during OTP verification");
20791
+ Ps.supabaseClient = Yn, V.adapter = Ps;
20789
20792
  const f = await ((d = ke.fromString(c.user.app_metadata.user)) == null ? void 0 : d.data);
20790
20793
  if (!f) throw new Error("User not found");
20791
- return Ps.supabaseClient = Yn, V.adapter = Ps, f;
20794
+ return f;
20792
20795
  }, TD = async () => {
20793
20796
  await Yn.auth.signOut();
20794
20797
  }, FD = (t) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedc/sdk",
3
- "version": "3.8.1",
3
+ "version": "3.8.2-next.1",
4
4
  "description": "TypeScript SDK for the OpenEDC Health Platform",
5
5
  "type": "module",
6
6
  "main": "./openedc-sdk.js",