orizu 0.1.6 → 0.2.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
@@ -50,6 +50,7 @@ orizu login
50
50
  ```
51
51
 
52
52
  This will open a browser tab for you to login with. You must either have an account on the [Orizu platform](https://orizu.ai) or it will help you create one.
53
+ Approving the login creates a personal access token for the CLI and stores it in your local Orizu credentials file. You can revoke CLI tokens from the Personal Tokens page in Orizu.
53
54
 
54
55
  **Check the signed-in user**
55
56
 
@@ -120,6 +121,10 @@ orizu logout
120
121
  <td>Append dataset rows</td>
121
122
  <td><code>orizu datasets append --dataset &lt;datasetId&gt; --file ./datasets/support-extra.jsonl</code></td>
122
123
  </tr>
124
+ <tr>
125
+ <td>Delete a dataset</td>
126
+ <td><code>orizu datasets delete --dataset &lt;datasetId&gt;</code> (interactive confirmation required)</td>
127
+ </tr>
123
128
  <tr>
124
129
  <td>Lock a dataset</td>
125
130
  <td><code>orizu datasets lock --dataset &lt;datasetId&gt; --reason "Finalize for labeling"</code></td>
@@ -18,6 +18,13 @@ function isStoredCredentialsV2(value) {
18
18
  const typed = value;
19
19
  return typed.version === 2 && !!typed.servers && typeof typed.servers === 'object';
20
20
  }
21
+ function isStoredCredentialsV3(value) {
22
+ if (!value || typeof value !== 'object') {
23
+ return false;
24
+ }
25
+ const typed = value;
26
+ return typed.version === 3 && !!typed.servers && typeof typed.servers === 'object';
27
+ }
21
28
  function isStoredCredentialsV1(value) {
22
29
  if (!value || typeof value !== 'object') {
23
30
  return false;
@@ -74,7 +81,7 @@ function writeCredentials(config) {
74
81
  }
75
82
  function createEmptyCredentialsConfig() {
76
83
  return {
77
- version: 2,
84
+ version: 3,
78
85
  activeBaseUrl: null,
79
86
  servers: {},
80
87
  };
@@ -101,6 +108,9 @@ export function loadCredentialsConfig() {
101
108
  console.warn('Warning: credentials file contains invalid JSON — please re-login with `orizu login`');
102
109
  return null;
103
110
  }
111
+ if (isStoredCredentialsV3(parsed)) {
112
+ return parsed;
113
+ }
104
114
  if (isStoredCredentialsV2(parsed)) {
105
115
  return parsed;
106
116
  }
@@ -121,13 +131,27 @@ export function getServerCredentials(baseUrl) {
121
131
  return config.servers[baseUrl] || null;
122
132
  }
123
133
  export function saveServerCredentials(baseUrl, credentials) {
124
- const config = loadCredentialsConfigForWrite();
134
+ const loaded = loadCredentialsConfigForWrite();
135
+ const config = loaded.version === 3
136
+ ? loaded
137
+ : {
138
+ version: 3,
139
+ activeBaseUrl: loaded.activeBaseUrl,
140
+ servers: loaded.servers,
141
+ };
125
142
  config.servers[baseUrl] = credentials;
126
143
  config.activeBaseUrl = baseUrl;
127
144
  writeCredentials(config);
128
145
  }
129
146
  export function updateServerCredentials(baseUrl, credentials) {
130
- const config = loadCredentialsConfigForWrite();
147
+ const loaded = loadCredentialsConfigForWrite();
148
+ const config = loaded.version === 3
149
+ ? loaded
150
+ : {
151
+ version: 3,
152
+ activeBaseUrl: loaded.activeBaseUrl,
153
+ servers: loaded.servers,
154
+ };
131
155
  config.servers[baseUrl] = credentials;
132
156
  writeCredentials(config);
133
157
  }
package/dist/http.js CHANGED
@@ -55,11 +55,20 @@ export function assertSecureTokenTransport(baseUrl) {
55
55
  }
56
56
  throw new Error(`Refusing to send CLI tokens to ${baseUrl}. Use HTTPS, or --local for loopback development.`);
57
57
  }
58
+ function isSessionCredentials(credentials) {
59
+ return 'accessToken' in credentials;
60
+ }
61
+ function getAuthorizationToken(credentials) {
62
+ return isSessionCredentials(credentials) ? credentials.accessToken : credentials.apiKey;
63
+ }
58
64
  function isExpired(expiresAt) {
59
65
  const nowUnix = Math.floor(Date.now() / 1000);
60
66
  return expiresAt <= nowUnix + 30;
61
67
  }
62
68
  async function refreshCredentials(baseUrl, credentials) {
69
+ if (!isSessionCredentials(credentials)) {
70
+ throw new Error('API key credentials do not refresh. Run `orizu login` again if access fails.');
71
+ }
63
72
  assertSecureTokenTransport(baseUrl);
64
73
  const response = await fetch(`${baseUrl}/api/cli/auth/refresh`, {
65
74
  method: 'POST',
@@ -70,7 +79,11 @@ async function refreshCredentials(baseUrl, credentials) {
70
79
  throw new Error('Session expired. Run `orizu login` again.');
71
80
  }
72
81
  const data = await response.json();
82
+ if (!data.accessToken || !data.refreshToken || !data.expiresAt) {
83
+ throw new Error('Server returned invalid refresh credentials. Run `orizu login` again.');
84
+ }
73
85
  const refreshed = {
86
+ credentialType: 'session',
74
87
  accessToken: data.accessToken,
75
88
  refreshToken: data.refreshToken,
76
89
  expiresAt: data.expiresAt,
@@ -86,23 +99,23 @@ export async function authedFetch(path, init = {}) {
86
99
  throw new Error(`Not logged in for ${baseUrl}. Run \`orizu login --server ${baseUrl}\` (or \`--local\`) first.`);
87
100
  }
88
101
  let activeCredentials = credentials;
89
- if (isExpired(activeCredentials.expiresAt)) {
102
+ if (isSessionCredentials(activeCredentials) && isExpired(activeCredentials.expiresAt)) {
90
103
  activeCredentials = await refreshCredentials(baseUrl, activeCredentials);
91
104
  }
92
105
  let response = await fetch(`${baseUrl}${path}`, {
93
106
  ...init,
94
107
  headers: {
95
108
  ...(init.headers || {}),
96
- Authorization: `Bearer ${activeCredentials.accessToken}`,
109
+ Authorization: `Bearer ${getAuthorizationToken(activeCredentials)}`,
97
110
  },
98
111
  });
99
- if (response.status === 401) {
112
+ if (response.status === 401 && isSessionCredentials(activeCredentials)) {
100
113
  activeCredentials = await refreshCredentials(baseUrl, activeCredentials);
101
114
  response = await fetch(`${baseUrl}${path}`, {
102
115
  ...init,
103
116
  headers: {
104
117
  ...(init.headers || {}),
105
- Authorization: `Bearer ${activeCredentials.accessToken}`,
118
+ Authorization: `Bearer ${getAuthorizationToken(activeCredentials)}`,
106
119
  },
107
120
  });
108
121
  }