orizu 0.0.2

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.
@@ -0,0 +1,30 @@
1
+ import { mkdirSync, readFileSync, rmSync, writeFileSync, chmodSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ function getConfigDir() {
5
+ return join(homedir(), '.config', 'orizu');
6
+ }
7
+ function getCredentialsPath() {
8
+ return join(getConfigDir(), 'credentials.json');
9
+ }
10
+ export function saveCredentials(credentials) {
11
+ const dir = getConfigDir();
12
+ mkdirSync(dir, { recursive: true });
13
+ const path = getCredentialsPath();
14
+ writeFileSync(path, JSON.stringify(credentials, null, 2), 'utf-8');
15
+ chmodSync(path, 0o600);
16
+ }
17
+ export function loadCredentials() {
18
+ const path = getCredentialsPath();
19
+ if (!existsSync(path)) {
20
+ return null;
21
+ }
22
+ const raw = readFileSync(path, 'utf-8');
23
+ return JSON.parse(raw);
24
+ }
25
+ export function clearCredentials() {
26
+ const path = getCredentialsPath();
27
+ if (existsSync(path)) {
28
+ rmSync(path);
29
+ }
30
+ }
package/dist/csv.js ADDED
@@ -0,0 +1,70 @@
1
+ export function parseCSV(csvText) {
2
+ const result = [];
3
+ let currentRow = [];
4
+ let currentField = '';
5
+ let inQuotes = false;
6
+ let i = 0;
7
+ while (i < csvText.length) {
8
+ const char = csvText[i];
9
+ const nextChar = csvText[i + 1];
10
+ if (char === '"') {
11
+ if (inQuotes && nextChar === '"') {
12
+ currentField += '"';
13
+ i += 2;
14
+ continue;
15
+ }
16
+ inQuotes = !inQuotes;
17
+ i++;
18
+ continue;
19
+ }
20
+ if (!inQuotes) {
21
+ if (char === ',') {
22
+ currentRow.push(currentField);
23
+ currentField = '';
24
+ i++;
25
+ continue;
26
+ }
27
+ if (char === '\n' || char === '\r') {
28
+ if (currentField || currentRow.length > 0) {
29
+ currentRow.push(currentField);
30
+ if (currentRow.some(field => field.trim())) {
31
+ result.push(currentRow);
32
+ }
33
+ currentRow = [];
34
+ currentField = '';
35
+ }
36
+ if (char === '\r' && nextChar === '\n') {
37
+ i += 2;
38
+ }
39
+ else {
40
+ i++;
41
+ }
42
+ continue;
43
+ }
44
+ }
45
+ currentField += char;
46
+ i++;
47
+ }
48
+ if (currentField || currentRow.length > 0) {
49
+ currentRow.push(currentField);
50
+ if (currentRow.some(field => field.trim())) {
51
+ result.push(currentRow);
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+ export function parseCSVToObjects(csvText) {
57
+ const rows = parseCSV(csvText);
58
+ if (rows.length < 2) {
59
+ return [];
60
+ }
61
+ const headers = rows[0].map(header => header.trim());
62
+ const dataRows = rows.slice(1);
63
+ return dataRows.map(row => {
64
+ const obj = {};
65
+ headers.forEach((header, index) => {
66
+ obj[header] = row[index]?.trim() || '';
67
+ });
68
+ return obj;
69
+ });
70
+ }
@@ -0,0 +1,64 @@
1
+ import { readFileSync } from 'fs';
2
+ import { extname } from 'path';
3
+ import { parseCSVToObjects } from './csv.js';
4
+ export function parseDatasetFile(filePath) {
5
+ const extension = extname(filePath).toLowerCase();
6
+ let content;
7
+ try {
8
+ content = readFileSync(filePath, 'utf-8');
9
+ }
10
+ catch (error) {
11
+ const maybeError = error;
12
+ if (maybeError.code === 'ENOENT') {
13
+ throw new Error(`File not found: ${filePath}. Check the path and filename, then retry.`);
14
+ }
15
+ if (maybeError.code === 'EPERM' || maybeError.code === 'EACCES') {
16
+ throw new Error(`Cannot read file: ${filePath}. macOS may be blocking access to this folder (for example Downloads). Grant folder permission to your terminal app and retry.`);
17
+ }
18
+ throw new Error(`Failed to read file ${filePath}: ${maybeError.message}`);
19
+ }
20
+ if (extension === '.csv') {
21
+ const rows = parseCSVToObjects(content);
22
+ return {
23
+ rows: ensureObjectRows(rows),
24
+ sourceType: 'csv',
25
+ };
26
+ }
27
+ if (extension === '.json') {
28
+ const data = JSON.parse(content);
29
+ if (!Array.isArray(data)) {
30
+ throw new Error('JSON file must contain a top-level array');
31
+ }
32
+ return {
33
+ rows: ensureObjectRows(data),
34
+ sourceType: 'json',
35
+ };
36
+ }
37
+ if (extension === '.jsonl') {
38
+ const lines = content.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
39
+ const parsed = lines.map((line, index) => {
40
+ try {
41
+ return JSON.parse(line);
42
+ }
43
+ catch {
44
+ throw new Error(`Invalid JSONL at line ${index + 1}`);
45
+ }
46
+ });
47
+ return {
48
+ rows: ensureObjectRows(parsed),
49
+ sourceType: 'jsonl',
50
+ };
51
+ }
52
+ throw new Error('Unsupported file type. Use .csv, .json, or .jsonl');
53
+ }
54
+ function ensureObjectRows(rows) {
55
+ if (rows.length === 0) {
56
+ throw new Error('Dataset file contains no rows');
57
+ }
58
+ return rows.map((row, index) => {
59
+ if (!row || Array.isArray(row) || typeof row !== 'object') {
60
+ throw new Error(`Row ${index + 1} must be a JSON object`);
61
+ }
62
+ return row;
63
+ });
64
+ }
package/dist/http.js ADDED
@@ -0,0 +1,55 @@
1
+ import { loadCredentials, saveCredentials } from './credentials.js';
2
+ export function getBaseUrl() {
3
+ return process.env.ORIZU_BASE_URL || 'http://localhost:3000';
4
+ }
5
+ function isExpired(expiresAt) {
6
+ const nowUnix = Math.floor(Date.now() / 1000);
7
+ return expiresAt <= nowUnix + 30;
8
+ }
9
+ async function refreshCredentials(credentials) {
10
+ const response = await fetch(`${credentials.baseUrl}/api/cli/auth/refresh`, {
11
+ method: 'POST',
12
+ headers: { 'Content-Type': 'application/json' },
13
+ body: JSON.stringify({ refreshToken: credentials.refreshToken }),
14
+ });
15
+ if (!response.ok) {
16
+ throw new Error('Session expired. Run `orizu login` again.');
17
+ }
18
+ const data = await response.json();
19
+ const refreshed = {
20
+ accessToken: data.accessToken,
21
+ refreshToken: data.refreshToken,
22
+ expiresAt: data.expiresAt,
23
+ baseUrl: credentials.baseUrl,
24
+ };
25
+ saveCredentials(refreshed);
26
+ return refreshed;
27
+ }
28
+ export async function authedFetch(path, init = {}) {
29
+ const credentials = loadCredentials();
30
+ if (!credentials) {
31
+ throw new Error('Not logged in. Run `orizu login` first.');
32
+ }
33
+ let activeCredentials = credentials;
34
+ if (isExpired(activeCredentials.expiresAt)) {
35
+ activeCredentials = await refreshCredentials(activeCredentials);
36
+ }
37
+ let response = await fetch(`${activeCredentials.baseUrl}${path}`, {
38
+ ...init,
39
+ headers: {
40
+ ...(init.headers || {}),
41
+ Authorization: `Bearer ${activeCredentials.accessToken}`,
42
+ },
43
+ });
44
+ if (response.status === 401) {
45
+ activeCredentials = await refreshCredentials(activeCredentials);
46
+ response = await fetch(`${activeCredentials.baseUrl}${path}`, {
47
+ ...init,
48
+ headers: {
49
+ ...(init.headers || {}),
50
+ Authorization: `Bearer ${activeCredentials.accessToken}`,
51
+ },
52
+ });
53
+ }
54
+ return response;
55
+ }