aurabase-js 0.2.1 → 0.4.0
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/.omc/state/hud-state.json +3 -3
- package/.omc/state/hud-stdin-cache.json +1 -1
- package/README.md +2 -70
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +215 -120
- package/dist/cli.mjs +216 -0
- package/dist/index.js +75 -116
- package/dist/index.mjs +81 -111
- package/lib/aurabase.ts +9 -0
- package/package.json +6 -6
- package/src/AuraBaseClient.ts +16 -6
- package/src/QueryBuilder.ts +161 -122
- package/src/cli.ts +203 -115
package/dist/index.mjs
CHANGED
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
var QueryBuilder = class {
|
|
3
3
|
constructor(url, anonKey, accessToken, tableName, headers = {}) {
|
|
4
4
|
this.isSingle = false;
|
|
5
|
-
this._method = "GET";
|
|
6
|
-
this._body = void 0;
|
|
7
|
-
this._isUpsert = false;
|
|
8
|
-
this._onConflict = void 0;
|
|
9
|
-
this._idValue = void 0;
|
|
10
5
|
this.url = url;
|
|
11
6
|
this.anonKey = anonKey;
|
|
12
7
|
this.accessToken = accessToken;
|
|
@@ -14,120 +9,101 @@ var QueryBuilder = class {
|
|
|
14
9
|
this.queryParams = new URLSearchParams();
|
|
15
10
|
this.headers = { ...headers };
|
|
16
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Select columns
|
|
14
|
+
* @example
|
|
15
|
+
* .select('id, name, email')
|
|
16
|
+
* .select('*')
|
|
17
|
+
*/
|
|
17
18
|
select(columns = "*") {
|
|
18
|
-
|
|
19
|
+
this.queryParams.set("select", columns);
|
|
19
20
|
return this;
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Filter by column equality
|
|
24
|
+
* @example
|
|
25
|
+
* .eq('id', 1)
|
|
26
|
+
* .eq('status', 'active')
|
|
27
|
+
*/
|
|
21
28
|
eq(column, value) {
|
|
22
|
-
|
|
23
|
-
this.queryParams.append("eq", `${column}:${value}`);
|
|
29
|
+
this.queryParams.append(column, `eq.${value}`);
|
|
24
30
|
return this;
|
|
25
31
|
}
|
|
26
32
|
/**
|
|
27
33
|
* Filter by column inequality
|
|
28
34
|
*/
|
|
29
35
|
neq(column, value) {
|
|
30
|
-
this.queryParams.append(
|
|
36
|
+
this.queryParams.append(column, `neq.${value}`);
|
|
31
37
|
return this;
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
34
40
|
* Filter by greater than
|
|
35
41
|
*/
|
|
36
42
|
gt(column, value) {
|
|
37
|
-
this.queryParams.append(
|
|
43
|
+
this.queryParams.append(column, `gt.${value}`);
|
|
38
44
|
return this;
|
|
39
45
|
}
|
|
40
46
|
/**
|
|
41
47
|
* Filter by greater than or equal
|
|
42
48
|
*/
|
|
43
49
|
gte(column, value) {
|
|
44
|
-
this.queryParams.append(
|
|
50
|
+
this.queryParams.append(column, `gte.${value}`);
|
|
45
51
|
return this;
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
54
|
* Filter by less than
|
|
49
55
|
*/
|
|
50
56
|
lt(column, value) {
|
|
51
|
-
this.queryParams.append(
|
|
57
|
+
this.queryParams.append(column, `lt.${value}`);
|
|
52
58
|
return this;
|
|
53
59
|
}
|
|
54
60
|
/**
|
|
55
61
|
* Filter by less than or equal
|
|
56
62
|
*/
|
|
57
63
|
lte(column, value) {
|
|
58
|
-
this.queryParams.append(
|
|
64
|
+
this.queryParams.append(column, `lte.${value}`);
|
|
59
65
|
return this;
|
|
60
66
|
}
|
|
61
67
|
/**
|
|
62
68
|
* Filter by like pattern
|
|
63
69
|
*/
|
|
64
70
|
like(column, pattern) {
|
|
65
|
-
this.queryParams.append(
|
|
71
|
+
this.queryParams.append(column, `like.${pattern}`);
|
|
66
72
|
return this;
|
|
67
73
|
}
|
|
68
74
|
/**
|
|
69
75
|
* Filter by case-insensitive like pattern
|
|
70
76
|
*/
|
|
71
77
|
ilike(column, pattern) {
|
|
72
|
-
this.queryParams.append(
|
|
78
|
+
this.queryParams.append(column, `ilike.${pattern}`);
|
|
73
79
|
return this;
|
|
74
80
|
}
|
|
75
81
|
/**
|
|
76
82
|
* Filter by array contains
|
|
77
83
|
*/
|
|
78
84
|
contains(column, value) {
|
|
79
|
-
this.queryParams.append(
|
|
85
|
+
this.queryParams.append(column, `cs.{${value.join(",")}}`);
|
|
80
86
|
return this;
|
|
81
87
|
}
|
|
82
88
|
/**
|
|
83
89
|
* Filter by value in array
|
|
84
90
|
*/
|
|
85
91
|
in(column, values) {
|
|
86
|
-
this.queryParams.append(
|
|
92
|
+
this.queryParams.append(column, `in.(${values.join(",")})`);
|
|
87
93
|
return this;
|
|
88
94
|
}
|
|
89
95
|
/**
|
|
90
96
|
* Filter for null values
|
|
91
97
|
*/
|
|
92
98
|
isNull(column) {
|
|
93
|
-
this.queryParams.append("
|
|
99
|
+
this.queryParams.append(column, "is.null");
|
|
94
100
|
return this;
|
|
95
101
|
}
|
|
96
102
|
/**
|
|
97
103
|
* Filter for non-null values
|
|
98
104
|
*/
|
|
99
105
|
isNotNull(column) {
|
|
100
|
-
this.queryParams.append("
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Full-text search across all columns
|
|
105
|
-
*/
|
|
106
|
-
search(query) {
|
|
107
|
-
this.queryParams.set("search", query);
|
|
108
|
-
return this;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Negate a filter
|
|
112
|
-
* @example .not('eq', 'category', 'Electronics')
|
|
113
|
-
*/
|
|
114
|
-
not(operator, column, value) {
|
|
115
|
-
this.queryParams.append("not", `${operator}:${column}:${value}`);
|
|
116
|
-
return this;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* OR conditions
|
|
120
|
-
* @example .or('category.eq.Electronics,price.lt.100000')
|
|
121
|
-
*/
|
|
122
|
-
or(conditions) {
|
|
123
|
-
this.queryParams.set("or", conditions);
|
|
124
|
-
return this;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Filter by array contained by
|
|
128
|
-
*/
|
|
129
|
-
containedBy(column, value) {
|
|
130
|
-
this.queryParams.append("contained_by", `${column}:${JSON.stringify(value)}`);
|
|
106
|
+
this.queryParams.append(column, "is.not.null");
|
|
131
107
|
return this;
|
|
132
108
|
}
|
|
133
109
|
/**
|
|
@@ -142,8 +118,7 @@ var QueryBuilder = class {
|
|
|
142
118
|
if (nullsFirst !== void 0) {
|
|
143
119
|
orderStr += nullsFirst ? ".nullsfirst" : ".nullslast";
|
|
144
120
|
}
|
|
145
|
-
|
|
146
|
-
this.queryParams.set("order", existing ? `${existing},${orderStr}` : orderStr);
|
|
121
|
+
this.queryParams.append("order", orderStr);
|
|
147
122
|
return this;
|
|
148
123
|
}
|
|
149
124
|
/**
|
|
@@ -191,36 +166,28 @@ var QueryBuilder = class {
|
|
|
191
166
|
...this.headers
|
|
192
167
|
};
|
|
193
168
|
}
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
async execute() {
|
|
206
|
-
const fullUrl = this.buildUrl();
|
|
207
|
-
const reqHeaders = this.getHeaders();
|
|
208
|
-
const options = { method: this._method, headers: reqHeaders };
|
|
209
|
-
if (this._body !== void 0 && this._method !== "GET") {
|
|
210
|
-
options.body = JSON.stringify(this._body);
|
|
211
|
-
reqHeaders["Prefer"] = "return=representation";
|
|
169
|
+
async request(method, body) {
|
|
170
|
+
const queryString = this.queryParams.toString();
|
|
171
|
+
const fullUrl = `${this.url}/rest/v1/${this.tableName}${queryString ? `?${queryString}` : ""}`;
|
|
172
|
+
const options = {
|
|
173
|
+
method,
|
|
174
|
+
headers: this.getHeaders()
|
|
175
|
+
};
|
|
176
|
+
if (body && method !== "GET") {
|
|
177
|
+
options.body = JSON.stringify(body);
|
|
178
|
+
options.headers["Prefer"] = "return=representation";
|
|
212
179
|
}
|
|
213
180
|
try {
|
|
214
181
|
const response = await fetch(fullUrl, options);
|
|
215
|
-
const text = await response.text();
|
|
216
182
|
let data = null;
|
|
217
183
|
let error = null;
|
|
184
|
+
const text = await response.text();
|
|
218
185
|
if (text) {
|
|
219
186
|
try {
|
|
220
187
|
const parsed = JSON.parse(text);
|
|
221
188
|
if (!response.ok) {
|
|
222
189
|
error = {
|
|
223
|
-
message: parsed.message || parsed.error ||
|
|
190
|
+
message: parsed.message || parsed.error || `HTTP ${response.status}`,
|
|
224
191
|
code: parsed.code,
|
|
225
192
|
details: parsed.details
|
|
226
193
|
};
|
|
@@ -228,49 +195,69 @@ var QueryBuilder = class {
|
|
|
228
195
|
data = this.isSingle && Array.isArray(parsed) ? parsed[0] ?? null : parsed;
|
|
229
196
|
}
|
|
230
197
|
} catch {
|
|
231
|
-
if (!response.ok)
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
error = {
|
|
200
|
+
message: text || `HTTP ${response.status}`
|
|
201
|
+
};
|
|
202
|
+
}
|
|
232
203
|
}
|
|
233
204
|
}
|
|
234
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
data,
|
|
207
|
+
error,
|
|
208
|
+
status: response.status,
|
|
209
|
+
statusText: response.statusText
|
|
210
|
+
};
|
|
235
211
|
} catch (err) {
|
|
236
212
|
return {
|
|
237
213
|
data: null,
|
|
238
|
-
error: {
|
|
214
|
+
error: {
|
|
215
|
+
message: err instanceof Error ? err.message : "Network error"
|
|
216
|
+
},
|
|
239
217
|
status: 0,
|
|
240
218
|
statusText: "Network Error"
|
|
241
219
|
};
|
|
242
220
|
}
|
|
243
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Execute SELECT query
|
|
224
|
+
*/
|
|
244
225
|
async then(resolve, reject) {
|
|
245
226
|
try {
|
|
246
|
-
const result = await this.
|
|
227
|
+
const result = await this.request("GET");
|
|
247
228
|
await resolve(result);
|
|
248
229
|
} catch (err) {
|
|
249
|
-
if (reject)
|
|
230
|
+
if (reject) {
|
|
231
|
+
await reject(err);
|
|
232
|
+
}
|
|
250
233
|
}
|
|
251
234
|
}
|
|
252
|
-
|
|
253
|
-
|
|
235
|
+
/**
|
|
236
|
+
* Insert row(s)
|
|
237
|
+
*/
|
|
238
|
+
async insert(row) {
|
|
254
239
|
const rows = Array.isArray(row) ? row : [row];
|
|
255
|
-
this.
|
|
256
|
-
return this;
|
|
240
|
+
return this.request("POST", rows.length === 1 ? rows[0] : rows);
|
|
257
241
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Update row(s)
|
|
244
|
+
*/
|
|
245
|
+
async update(data) {
|
|
246
|
+
return this.request("PATCH", data);
|
|
262
247
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
248
|
+
/**
|
|
249
|
+
* Upsert row(s)
|
|
250
|
+
*/
|
|
251
|
+
async upsert(row) {
|
|
267
252
|
const rows = Array.isArray(row) ? row : [row];
|
|
268
|
-
this.
|
|
269
|
-
return this;
|
|
253
|
+
this.headers["Prefer"] = "resolution=merge-duplicates,return=representation";
|
|
254
|
+
return this.request("POST", rows.length === 1 ? rows[0] : rows);
|
|
270
255
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
256
|
+
/**
|
|
257
|
+
* Delete row(s)
|
|
258
|
+
*/
|
|
259
|
+
async delete() {
|
|
260
|
+
return this.request("DELETE");
|
|
274
261
|
}
|
|
275
262
|
};
|
|
276
263
|
|
|
@@ -570,7 +557,7 @@ var AuraBaseClient = class {
|
|
|
570
557
|
async rpc(functionName, params) {
|
|
571
558
|
const token = this.accessToken || this.anonKey;
|
|
572
559
|
try {
|
|
573
|
-
const response = await fetch(`${this.url}/
|
|
560
|
+
const response = await fetch(`${this.url}/rpc/v1/${functionName}`, {
|
|
574
561
|
method: "POST",
|
|
575
562
|
headers: {
|
|
576
563
|
"Content-Type": "application/json",
|
|
@@ -744,23 +731,6 @@ var StorageBucket = class {
|
|
|
744
731
|
|
|
745
732
|
// src/index.ts
|
|
746
733
|
function createClient(options) {
|
|
747
|
-
if (!options.url) {
|
|
748
|
-
console.warn(
|
|
749
|
-
"[aurabase-js] NEXT_PUBLIC_AURABASE_URL이 설정되지 않았습니다.\n" +
|
|
750
|
-
".env.local 파일에 다음 항목을 추가하세요:\n\n" +
|
|
751
|
-
" NEXT_PUBLIC_AURABASE_URL=https://your-project.cloudfront.net\n" +
|
|
752
|
-
" NEXT_PUBLIC_AURABASE_ANON_KEY=your-anon-key\n" +
|
|
753
|
-
" NEXT_PUBLIC_AURABASE_SERVICE_ROLE_KEY=your-service-role-key\n"
|
|
754
|
-
);
|
|
755
|
-
}
|
|
756
|
-
if (!options.anonKey) {
|
|
757
|
-
console.warn(
|
|
758
|
-
"[aurabase-js] anonKey가 설정되지 않았습니다.\n" +
|
|
759
|
-
".env.local 파일에 다음 항목을 추가하세요:\n\n" +
|
|
760
|
-
" NEXT_PUBLIC_AURABASE_ANON_KEY=your-anon-key (클라이언트용)\n" +
|
|
761
|
-
" NEXT_PUBLIC_AURABASE_SERVICE_ROLE_KEY=your-service-role-key (서버/admin용)\n"
|
|
762
|
-
);
|
|
763
|
-
}
|
|
764
734
|
return new AuraBaseClient(options);
|
|
765
735
|
}
|
|
766
736
|
var index_default = createClient;
|
package/lib/aurabase.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createClient } from 'aurabase-js';
|
|
2
|
+
|
|
3
|
+
const AURABASE_URL = process.env.NEXT_PUBLIC_AURABASE_URL || 'https://your-project.cloudfront.net';
|
|
4
|
+
const AURABASE_ANON_KEY = process.env.NEXT_PUBLIC_AURABASE_ANON_KEY || '';
|
|
5
|
+
|
|
6
|
+
export const aurabase = createClient({
|
|
7
|
+
url: AURABASE_URL,
|
|
8
|
+
anonKey: AURABASE_ANON_KEY,
|
|
9
|
+
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aurabase-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "AuraBase client library - Supabase-style SDK for AuraBase",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"aurabase-js": "
|
|
9
|
+
"aurabase-js": "dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -16,17 +16,17 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsup src/index.ts
|
|
19
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts",
|
|
20
20
|
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
21
|
-
"prepublishOnly": "
|
|
21
|
+
"prepublishOnly": "npm run build",
|
|
22
|
+
"postinstall": "node dist/cli.js init"
|
|
22
23
|
},
|
|
23
24
|
"keywords": [
|
|
24
25
|
"aurabase",
|
|
25
26
|
"database",
|
|
26
27
|
"rest",
|
|
27
28
|
"client",
|
|
28
|
-
"supabase-like"
|
|
29
|
-
"cli"
|
|
29
|
+
"supabase-like"
|
|
30
30
|
],
|
|
31
31
|
"author": "",
|
|
32
32
|
"license": "MIT",
|
package/src/AuraBaseClient.ts
CHANGED
|
@@ -46,16 +46,18 @@ export class AuraBaseClient {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* Execute raw SQL (RPC function call)
|
|
50
|
+
* @example
|
|
51
|
+
* const { data, error } = await client.rpc('my_function', { arg1: 'value' })
|
|
51
52
|
*/
|
|
52
53
|
async rpc<T = unknown>(
|
|
53
54
|
functionName: string,
|
|
54
55
|
params?: Record<string, unknown>
|
|
55
56
|
): Promise<{ data: T | null; error: { message: string } | null }> {
|
|
56
57
|
const token = this.accessToken || this.anonKey;
|
|
58
|
+
|
|
57
59
|
try {
|
|
58
|
-
const response = await fetch(`${this.url}/
|
|
60
|
+
const response = await fetch(`${this.url}/rpc/v1/${functionName}`, {
|
|
59
61
|
method: 'POST',
|
|
60
62
|
headers: {
|
|
61
63
|
'Content-Type': 'application/json',
|
|
@@ -65,24 +67,32 @@ export class AuraBaseClient {
|
|
|
65
67
|
},
|
|
66
68
|
body: JSON.stringify(params || {}),
|
|
67
69
|
});
|
|
70
|
+
|
|
68
71
|
const text = await response.text();
|
|
69
72
|
let data: T | null = null;
|
|
70
73
|
let error: { message: string } | null = null;
|
|
74
|
+
|
|
71
75
|
if (text) {
|
|
72
76
|
try {
|
|
73
77
|
const parsed = JSON.parse(text);
|
|
74
78
|
if (!response.ok) {
|
|
75
|
-
error = { message: parsed.message || parsed.error ||
|
|
79
|
+
error = { message: parsed.message || parsed.error || `HTTP ${response.status}` };
|
|
76
80
|
} else {
|
|
77
81
|
data = parsed;
|
|
78
82
|
}
|
|
79
83
|
} catch {
|
|
80
|
-
if (!response.ok)
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
error = { message: text || `HTTP ${response.status}` };
|
|
86
|
+
}
|
|
81
87
|
}
|
|
82
88
|
}
|
|
89
|
+
|
|
83
90
|
return { data, error };
|
|
84
91
|
} catch (err) {
|
|
85
|
-
return {
|
|
92
|
+
return {
|
|
93
|
+
data: null,
|
|
94
|
+
error: { message: err instanceof Error ? err.message : 'Network error' },
|
|
95
|
+
};
|
|
86
96
|
}
|
|
87
97
|
}
|
|
88
98
|
|