aurabase-js 0.3.0 → 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-stdin-cache.json +1 -1
- package/dist/cli.js +122 -15
- package/dist/cli.mjs +122 -15
- package/package.json +1 -1
- package/src/cli.ts +126 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"session_id":"1c1e8df6-335a-4058-8bd4-4c0a67d996cd","transcript_path":"C:\\Users\\Jay\\.claude\\projects\\D--000-FrontEnd-242-dino-game\\1c1e8df6-335a-4058-8bd4-4c0a67d996cd.jsonl","cwd":"D:\\000.FrontEnd\\242.dino_game\\packages\\aurabase-js","model":{"id":"GLM-5","display_name":"GLM-5"},"workspace":{"current_dir":"D:\\000.FrontEnd\\242.dino_game\\packages\\aurabase-js","project_dir":"D:\\000.FrontEnd\\242.dino_game","added_dirs":[]},"version":"2.1.71","output_style":{"name":"default"},"cost":{"total_cost_usd":2.
|
|
1
|
+
{"session_id":"1c1e8df6-335a-4058-8bd4-4c0a67d996cd","transcript_path":"C:\\Users\\Jay\\.claude\\projects\\D--000-FrontEnd-242-dino-game\\1c1e8df6-335a-4058-8bd4-4c0a67d996cd.jsonl","cwd":"D:\\000.FrontEnd\\242.dino_game\\packages\\aurabase-js","model":{"id":"GLM-5","display_name":"GLM-5"},"workspace":{"current_dir":"D:\\000.FrontEnd\\242.dino_game\\packages\\aurabase-js","project_dir":"D:\\000.FrontEnd\\242.dino_game","added_dirs":[]},"version":"2.1.71","output_style":{"name":"default"},"cost":{"total_cost_usd":2.500432,"total_duration_ms":1462926,"total_api_duration_ms":692143,"total_lines_added":329,"total_lines_removed":37},"context_window":{"total_input_tokens":71095,"total_output_tokens":15653,"context_window_size":200000,"current_usage":{"input_tokens":126,"output_tokens":66,"cache_creation_input_tokens":0,"cache_read_input_tokens":77504},"used_percentage":39,"remaining_percentage":61},"exceeds_200k_tokens":false}
|
package/dist/cli.js
CHANGED
|
@@ -36,6 +36,103 @@ export const aurabase = createClient({
|
|
|
36
36
|
url: AURABASE_URL,
|
|
37
37
|
anonKey: AURABASE_ANON_KEY,
|
|
38
38
|
});
|
|
39
|
+
`,
|
|
40
|
+
"lib/api-client.ts": `import { NextRequest, NextResponse } from 'next/server';
|
|
41
|
+
|
|
42
|
+
const AURABASE_URL = process.env.AURABASE_URL || 'https://your-project.cloudfront.net';
|
|
43
|
+
const AURABASE_ANON_KEY = process.env.AURABASE_ANON_KEY || '';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* \uC11C\uBC84 \uC0AC\uC774\uB4DC API \uD504\uB85D\uC2DC \uC720\uD2F8\uB9AC\uD2F0
|
|
47
|
+
* - \uB85C\uADF8\uC778\uB428: \uCFE0\uD0A4\uC758 access_token \uC0AC\uC6A9
|
|
48
|
+
* - \uB85C\uADF8\uC778 \uC548 \uB428: AURABASE_ANON_KEY \uC0AC\uC6A9
|
|
49
|
+
*/
|
|
50
|
+
export async function proxyApiRequest(
|
|
51
|
+
req: NextRequest,
|
|
52
|
+
path: string
|
|
53
|
+
): Promise<NextResponse> {
|
|
54
|
+
const accessToken = req.cookies.get('access_token')?.value;
|
|
55
|
+
const authToken = accessToken || AURABASE_ANON_KEY;
|
|
56
|
+
|
|
57
|
+
let body: string | undefined;
|
|
58
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
59
|
+
body = await req.text();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const headers: Record<string, string> = {
|
|
63
|
+
'Content-Type': 'application/json',
|
|
64
|
+
};
|
|
65
|
+
if (authToken) {
|
|
66
|
+
headers['Authorization'] = \`Bearer \${authToken}\`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const fetchOptions: RequestInit = {
|
|
70
|
+
method: req.method,
|
|
71
|
+
headers,
|
|
72
|
+
};
|
|
73
|
+
if (body) {
|
|
74
|
+
fetchOptions.body = body;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const res = await fetch(\`\${AURABASE_URL}\${path}\`, fetchOptions);
|
|
78
|
+
const data = await res.text();
|
|
79
|
+
return new NextResponse(data, {
|
|
80
|
+
status: res.status,
|
|
81
|
+
headers: { 'Content-Type': 'application/json' },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* \uD074\uB77C\uC774\uC5B8\uD2B8\uC6A9 fetch \uB798\uD37C
|
|
87
|
+
*/
|
|
88
|
+
export function createApiClient(baseUrl: string = '') {
|
|
89
|
+
return {
|
|
90
|
+
async get<T>(path: string): Promise<T> {
|
|
91
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, { credentials: 'include' });
|
|
92
|
+
if (!res.ok) throw new Error(\`API Error: \${res.status}\`);
|
|
93
|
+
return res.json();
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
async post<T>(path: string, data?: unknown): Promise<T> {
|
|
97
|
+
const options: RequestInit = {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: { 'Content-Type': 'application/json' },
|
|
100
|
+
credentials: 'include',
|
|
101
|
+
};
|
|
102
|
+
if (data) options.body = JSON.stringify(data);
|
|
103
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, options);
|
|
104
|
+
if (!res.ok) {
|
|
105
|
+
const error = await res.json().catch(() => ({ error: 'Unknown error' }));
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
return res.json();
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
async put<T>(path: string, data?: unknown): Promise<T> {
|
|
112
|
+
const options: RequestInit = {
|
|
113
|
+
method: 'PUT',
|
|
114
|
+
headers: { 'Content-Type': 'application/json' },
|
|
115
|
+
credentials: 'include',
|
|
116
|
+
};
|
|
117
|
+
if (data) options.body = JSON.stringify(data);
|
|
118
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, options);
|
|
119
|
+
if (!res.ok) {
|
|
120
|
+
const error = await res.json().catch(() => ({ error: 'Unknown error' }));
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
return res.json();
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
async delete<T>(path: string): Promise<T> {
|
|
127
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, {
|
|
128
|
+
method: 'DELETE',
|
|
129
|
+
credentials: 'include',
|
|
130
|
+
});
|
|
131
|
+
if (!res.ok) throw new Error(\`API Error: \${res.status}\`);
|
|
132
|
+
return res.json();
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
39
136
|
`,
|
|
40
137
|
"lib/supabase.ts": `import { createClient } from 'aurabase-js';
|
|
41
138
|
|
|
@@ -52,11 +149,15 @@ export const aurabase = supabase;
|
|
|
52
149
|
`
|
|
53
150
|
};
|
|
54
151
|
var ENV_TEMPLATE = `
|
|
55
|
-
# AuraBase Configuration
|
|
56
|
-
# Add these to your .env.local file:
|
|
152
|
+
# AuraBase Configuration (.env.local)
|
|
57
153
|
|
|
154
|
+
# \uD074\uB77C\uC774\uC5B8\uD2B8\uC6A9 (NEXT_PUBLIC_ \uD544\uC218)
|
|
58
155
|
NEXT_PUBLIC_AURABASE_URL=https://your-project.cloudfront.net
|
|
59
156
|
NEXT_PUBLIC_AURABASE_ANON_KEY=your-anon-key-here
|
|
157
|
+
|
|
158
|
+
# \uC11C\uBC84 \uC0AC\uC774\uB4DC\uC6A9
|
|
159
|
+
AURABASE_URL=https://your-project.cloudfront.net
|
|
160
|
+
AURABASE_ANON_KEY=your-anon-key-here
|
|
60
161
|
`;
|
|
61
162
|
function findProjectRoot() {
|
|
62
163
|
let dir = process.cwd();
|
|
@@ -68,20 +169,30 @@ function findProjectRoot() {
|
|
|
68
169
|
}
|
|
69
170
|
return process.cwd();
|
|
70
171
|
}
|
|
71
|
-
function
|
|
72
|
-
const projectRoot = findProjectRoot();
|
|
172
|
+
function createFile(projectRoot, filename) {
|
|
73
173
|
const filePath = path.join(projectRoot, filename);
|
|
74
174
|
const dir = path.dirname(filePath);
|
|
75
175
|
if (!fs.existsSync(dir)) {
|
|
76
176
|
fs.mkdirSync(dir, { recursive: true });
|
|
77
177
|
}
|
|
78
178
|
if (fs.existsSync(filePath)) {
|
|
79
|
-
console.log(`\x1B[33m\u26A0 ${filename} already exists. Skipping...\x1B[0m`);
|
|
80
|
-
return;
|
|
179
|
+
console.log(`\x1B[33m \u26A0 ${filename} already exists. Skipping...\x1B[0m`);
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
const template = TEMPLATES[filename];
|
|
183
|
+
if (!template) {
|
|
184
|
+
console.log(`\x1B[31m \u2717 Unknown template: ${filename}\x1B[0m`);
|
|
185
|
+
return false;
|
|
81
186
|
}
|
|
82
|
-
const template = TEMPLATES[filename] || TEMPLATES["lib/aurabase.ts"];
|
|
83
187
|
fs.writeFileSync(filePath, template.trim() + "\n");
|
|
84
|
-
console.log(`\x1B[32m\u2713 Created ${filename}\x1B[0m`);
|
|
188
|
+
console.log(`\x1B[32m \u2713 Created ${filename}\x1B[0m`);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
function init() {
|
|
192
|
+
const projectRoot = findProjectRoot();
|
|
193
|
+
console.log("\x1B[1m\n\u{1F680} Initializing AuraBase...\x1B[0m\n");
|
|
194
|
+
createFile(projectRoot, "lib/aurabase.ts");
|
|
195
|
+
createFile(projectRoot, "lib/api-client.ts");
|
|
85
196
|
console.log("\x1B[36m%s\x1B[0m", ENV_TEMPLATE);
|
|
86
197
|
}
|
|
87
198
|
function showHelp() {
|
|
@@ -89,11 +200,10 @@ function showHelp() {
|
|
|
89
200
|
\x1B[1mAuraBase JS CLI\x1B[0m
|
|
90
201
|
|
|
91
202
|
\x1B[1mUsage:\x1B[0m
|
|
92
|
-
npx aurabase-js init
|
|
203
|
+
npx aurabase-js init
|
|
93
204
|
|
|
94
205
|
\x1B[1mCommands:\x1B[0m
|
|
95
|
-
init Create lib/aurabase.ts
|
|
96
|
-
init --supabase Create lib/supabase.ts file (alias name)
|
|
206
|
+
init Create lib/aurabase.ts and lib/api-client.ts
|
|
97
207
|
|
|
98
208
|
\x1B[1mOptions:\x1B[0m
|
|
99
209
|
-h, --help Show this help message
|
|
@@ -101,7 +211,6 @@ function showHelp() {
|
|
|
101
211
|
|
|
102
212
|
\x1B[1mExamples:\x1B[0m
|
|
103
213
|
npx aurabase-js init
|
|
104
|
-
npx aurabase-js init --supabase
|
|
105
214
|
`);
|
|
106
215
|
}
|
|
107
216
|
function showVersion() {
|
|
@@ -120,9 +229,7 @@ function main() {
|
|
|
120
229
|
return;
|
|
121
230
|
}
|
|
122
231
|
if (args[0] === "init") {
|
|
123
|
-
|
|
124
|
-
const filename = useSupabase ? "lib/supabase.ts" : "lib/aurabase.ts";
|
|
125
|
-
init(filename);
|
|
232
|
+
init();
|
|
126
233
|
return;
|
|
127
234
|
}
|
|
128
235
|
console.log(`\x1B[31mUnknown command: ${args[0]}\x1B[0m`);
|
package/dist/cli.mjs
CHANGED
|
@@ -13,6 +13,103 @@ export const aurabase = createClient({
|
|
|
13
13
|
url: AURABASE_URL,
|
|
14
14
|
anonKey: AURABASE_ANON_KEY,
|
|
15
15
|
});
|
|
16
|
+
`,
|
|
17
|
+
"lib/api-client.ts": `import { NextRequest, NextResponse } from 'next/server';
|
|
18
|
+
|
|
19
|
+
const AURABASE_URL = process.env.AURABASE_URL || 'https://your-project.cloudfront.net';
|
|
20
|
+
const AURABASE_ANON_KEY = process.env.AURABASE_ANON_KEY || '';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* \uC11C\uBC84 \uC0AC\uC774\uB4DC API \uD504\uB85D\uC2DC \uC720\uD2F8\uB9AC\uD2F0
|
|
24
|
+
* - \uB85C\uADF8\uC778\uB428: \uCFE0\uD0A4\uC758 access_token \uC0AC\uC6A9
|
|
25
|
+
* - \uB85C\uADF8\uC778 \uC548 \uB428: AURABASE_ANON_KEY \uC0AC\uC6A9
|
|
26
|
+
*/
|
|
27
|
+
export async function proxyApiRequest(
|
|
28
|
+
req: NextRequest,
|
|
29
|
+
path: string
|
|
30
|
+
): Promise<NextResponse> {
|
|
31
|
+
const accessToken = req.cookies.get('access_token')?.value;
|
|
32
|
+
const authToken = accessToken || AURABASE_ANON_KEY;
|
|
33
|
+
|
|
34
|
+
let body: string | undefined;
|
|
35
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
36
|
+
body = await req.text();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const headers: Record<string, string> = {
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
};
|
|
42
|
+
if (authToken) {
|
|
43
|
+
headers['Authorization'] = \`Bearer \${authToken}\`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const fetchOptions: RequestInit = {
|
|
47
|
+
method: req.method,
|
|
48
|
+
headers,
|
|
49
|
+
};
|
|
50
|
+
if (body) {
|
|
51
|
+
fetchOptions.body = body;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const res = await fetch(\`\${AURABASE_URL}\${path}\`, fetchOptions);
|
|
55
|
+
const data = await res.text();
|
|
56
|
+
return new NextResponse(data, {
|
|
57
|
+
status: res.status,
|
|
58
|
+
headers: { 'Content-Type': 'application/json' },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* \uD074\uB77C\uC774\uC5B8\uD2B8\uC6A9 fetch \uB798\uD37C
|
|
64
|
+
*/
|
|
65
|
+
export function createApiClient(baseUrl: string = '') {
|
|
66
|
+
return {
|
|
67
|
+
async get<T>(path: string): Promise<T> {
|
|
68
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, { credentials: 'include' });
|
|
69
|
+
if (!res.ok) throw new Error(\`API Error: \${res.status}\`);
|
|
70
|
+
return res.json();
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
async post<T>(path: string, data?: unknown): Promise<T> {
|
|
74
|
+
const options: RequestInit = {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: { 'Content-Type': 'application/json' },
|
|
77
|
+
credentials: 'include',
|
|
78
|
+
};
|
|
79
|
+
if (data) options.body = JSON.stringify(data);
|
|
80
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, options);
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const error = await res.json().catch(() => ({ error: 'Unknown error' }));
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
return res.json();
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
async put<T>(path: string, data?: unknown): Promise<T> {
|
|
89
|
+
const options: RequestInit = {
|
|
90
|
+
method: 'PUT',
|
|
91
|
+
headers: { 'Content-Type': 'application/json' },
|
|
92
|
+
credentials: 'include',
|
|
93
|
+
};
|
|
94
|
+
if (data) options.body = JSON.stringify(data);
|
|
95
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, options);
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
const error = await res.json().catch(() => ({ error: 'Unknown error' }));
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
return res.json();
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
async delete<T>(path: string): Promise<T> {
|
|
104
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, {
|
|
105
|
+
method: 'DELETE',
|
|
106
|
+
credentials: 'include',
|
|
107
|
+
});
|
|
108
|
+
if (!res.ok) throw new Error(\`API Error: \${res.status}\`);
|
|
109
|
+
return res.json();
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
16
113
|
`,
|
|
17
114
|
"lib/supabase.ts": `import { createClient } from 'aurabase-js';
|
|
18
115
|
|
|
@@ -29,11 +126,15 @@ export const aurabase = supabase;
|
|
|
29
126
|
`
|
|
30
127
|
};
|
|
31
128
|
var ENV_TEMPLATE = `
|
|
32
|
-
# AuraBase Configuration
|
|
33
|
-
# Add these to your .env.local file:
|
|
129
|
+
# AuraBase Configuration (.env.local)
|
|
34
130
|
|
|
131
|
+
# \uD074\uB77C\uC774\uC5B8\uD2B8\uC6A9 (NEXT_PUBLIC_ \uD544\uC218)
|
|
35
132
|
NEXT_PUBLIC_AURABASE_URL=https://your-project.cloudfront.net
|
|
36
133
|
NEXT_PUBLIC_AURABASE_ANON_KEY=your-anon-key-here
|
|
134
|
+
|
|
135
|
+
# \uC11C\uBC84 \uC0AC\uC774\uB4DC\uC6A9
|
|
136
|
+
AURABASE_URL=https://your-project.cloudfront.net
|
|
137
|
+
AURABASE_ANON_KEY=your-anon-key-here
|
|
37
138
|
`;
|
|
38
139
|
function findProjectRoot() {
|
|
39
140
|
let dir = process.cwd();
|
|
@@ -45,20 +146,30 @@ function findProjectRoot() {
|
|
|
45
146
|
}
|
|
46
147
|
return process.cwd();
|
|
47
148
|
}
|
|
48
|
-
function
|
|
49
|
-
const projectRoot = findProjectRoot();
|
|
149
|
+
function createFile(projectRoot, filename) {
|
|
50
150
|
const filePath = path.join(projectRoot, filename);
|
|
51
151
|
const dir = path.dirname(filePath);
|
|
52
152
|
if (!fs.existsSync(dir)) {
|
|
53
153
|
fs.mkdirSync(dir, { recursive: true });
|
|
54
154
|
}
|
|
55
155
|
if (fs.existsSync(filePath)) {
|
|
56
|
-
console.log(`\x1B[33m\u26A0 ${filename} already exists. Skipping...\x1B[0m`);
|
|
57
|
-
return;
|
|
156
|
+
console.log(`\x1B[33m \u26A0 ${filename} already exists. Skipping...\x1B[0m`);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
const template = TEMPLATES[filename];
|
|
160
|
+
if (!template) {
|
|
161
|
+
console.log(`\x1B[31m \u2717 Unknown template: ${filename}\x1B[0m`);
|
|
162
|
+
return false;
|
|
58
163
|
}
|
|
59
|
-
const template = TEMPLATES[filename] || TEMPLATES["lib/aurabase.ts"];
|
|
60
164
|
fs.writeFileSync(filePath, template.trim() + "\n");
|
|
61
|
-
console.log(`\x1B[32m\u2713 Created ${filename}\x1B[0m`);
|
|
165
|
+
console.log(`\x1B[32m \u2713 Created ${filename}\x1B[0m`);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
function init() {
|
|
169
|
+
const projectRoot = findProjectRoot();
|
|
170
|
+
console.log("\x1B[1m\n\u{1F680} Initializing AuraBase...\x1B[0m\n");
|
|
171
|
+
createFile(projectRoot, "lib/aurabase.ts");
|
|
172
|
+
createFile(projectRoot, "lib/api-client.ts");
|
|
62
173
|
console.log("\x1B[36m%s\x1B[0m", ENV_TEMPLATE);
|
|
63
174
|
}
|
|
64
175
|
function showHelp() {
|
|
@@ -66,11 +177,10 @@ function showHelp() {
|
|
|
66
177
|
\x1B[1mAuraBase JS CLI\x1B[0m
|
|
67
178
|
|
|
68
179
|
\x1B[1mUsage:\x1B[0m
|
|
69
|
-
npx aurabase-js init
|
|
180
|
+
npx aurabase-js init
|
|
70
181
|
|
|
71
182
|
\x1B[1mCommands:\x1B[0m
|
|
72
|
-
init Create lib/aurabase.ts
|
|
73
|
-
init --supabase Create lib/supabase.ts file (alias name)
|
|
183
|
+
init Create lib/aurabase.ts and lib/api-client.ts
|
|
74
184
|
|
|
75
185
|
\x1B[1mOptions:\x1B[0m
|
|
76
186
|
-h, --help Show this help message
|
|
@@ -78,7 +188,6 @@ function showHelp() {
|
|
|
78
188
|
|
|
79
189
|
\x1B[1mExamples:\x1B[0m
|
|
80
190
|
npx aurabase-js init
|
|
81
|
-
npx aurabase-js init --supabase
|
|
82
191
|
`);
|
|
83
192
|
}
|
|
84
193
|
function showVersion() {
|
|
@@ -97,9 +206,7 @@ function main() {
|
|
|
97
206
|
return;
|
|
98
207
|
}
|
|
99
208
|
if (args[0] === "init") {
|
|
100
|
-
|
|
101
|
-
const filename = useSupabase ? "lib/supabase.ts" : "lib/aurabase.ts";
|
|
102
|
-
init(filename);
|
|
209
|
+
init();
|
|
103
210
|
return;
|
|
104
211
|
}
|
|
105
212
|
console.log(`\x1B[31mUnknown command: ${args[0]}\x1B[0m`);
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -13,6 +13,103 @@ export const aurabase = createClient({
|
|
|
13
13
|
url: AURABASE_URL,
|
|
14
14
|
anonKey: AURABASE_ANON_KEY,
|
|
15
15
|
});
|
|
16
|
+
`,
|
|
17
|
+
'lib/api-client.ts': `import { NextRequest, NextResponse } from 'next/server';
|
|
18
|
+
|
|
19
|
+
const AURABASE_URL = process.env.AURABASE_URL || 'https://your-project.cloudfront.net';
|
|
20
|
+
const AURABASE_ANON_KEY = process.env.AURABASE_ANON_KEY || '';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 서버 사이드 API 프록시 유틸리티
|
|
24
|
+
* - 로그인됨: 쿠키의 access_token 사용
|
|
25
|
+
* - 로그인 안 됨: AURABASE_ANON_KEY 사용
|
|
26
|
+
*/
|
|
27
|
+
export async function proxyApiRequest(
|
|
28
|
+
req: NextRequest,
|
|
29
|
+
path: string
|
|
30
|
+
): Promise<NextResponse> {
|
|
31
|
+
const accessToken = req.cookies.get('access_token')?.value;
|
|
32
|
+
const authToken = accessToken || AURABASE_ANON_KEY;
|
|
33
|
+
|
|
34
|
+
let body: string | undefined;
|
|
35
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
36
|
+
body = await req.text();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const headers: Record<string, string> = {
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
};
|
|
42
|
+
if (authToken) {
|
|
43
|
+
headers['Authorization'] = \`Bearer \${authToken}\`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const fetchOptions: RequestInit = {
|
|
47
|
+
method: req.method,
|
|
48
|
+
headers,
|
|
49
|
+
};
|
|
50
|
+
if (body) {
|
|
51
|
+
fetchOptions.body = body;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const res = await fetch(\`\${AURABASE_URL}\${path}\`, fetchOptions);
|
|
55
|
+
const data = await res.text();
|
|
56
|
+
return new NextResponse(data, {
|
|
57
|
+
status: res.status,
|
|
58
|
+
headers: { 'Content-Type': 'application/json' },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 클라이언트용 fetch 래퍼
|
|
64
|
+
*/
|
|
65
|
+
export function createApiClient(baseUrl: string = '') {
|
|
66
|
+
return {
|
|
67
|
+
async get<T>(path: string): Promise<T> {
|
|
68
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, { credentials: 'include' });
|
|
69
|
+
if (!res.ok) throw new Error(\`API Error: \${res.status}\`);
|
|
70
|
+
return res.json();
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
async post<T>(path: string, data?: unknown): Promise<T> {
|
|
74
|
+
const options: RequestInit = {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: { 'Content-Type': 'application/json' },
|
|
77
|
+
credentials: 'include',
|
|
78
|
+
};
|
|
79
|
+
if (data) options.body = JSON.stringify(data);
|
|
80
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, options);
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const error = await res.json().catch(() => ({ error: 'Unknown error' }));
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
return res.json();
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
async put<T>(path: string, data?: unknown): Promise<T> {
|
|
89
|
+
const options: RequestInit = {
|
|
90
|
+
method: 'PUT',
|
|
91
|
+
headers: { 'Content-Type': 'application/json' },
|
|
92
|
+
credentials: 'include',
|
|
93
|
+
};
|
|
94
|
+
if (data) options.body = JSON.stringify(data);
|
|
95
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, options);
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
const error = await res.json().catch(() => ({ error: 'Unknown error' }));
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
return res.json();
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
async delete<T>(path: string): Promise<T> {
|
|
104
|
+
const res = await fetch(\`\${baseUrl}\${path}\`, {
|
|
105
|
+
method: 'DELETE',
|
|
106
|
+
credentials: 'include',
|
|
107
|
+
});
|
|
108
|
+
if (!res.ok) throw new Error(\`API Error: \${res.status}\`);
|
|
109
|
+
return res.json();
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
16
113
|
`,
|
|
17
114
|
'lib/supabase.ts': `import { createClient } from 'aurabase-js';
|
|
18
115
|
|
|
@@ -30,11 +127,15 @@ export const aurabase = supabase;
|
|
|
30
127
|
};
|
|
31
128
|
|
|
32
129
|
const ENV_TEMPLATE = `
|
|
33
|
-
# AuraBase Configuration
|
|
34
|
-
# Add these to your .env.local file:
|
|
130
|
+
# AuraBase Configuration (.env.local)
|
|
35
131
|
|
|
132
|
+
# 클라이언트용 (NEXT_PUBLIC_ 필수)
|
|
36
133
|
NEXT_PUBLIC_AURABASE_URL=https://your-project.cloudfront.net
|
|
37
134
|
NEXT_PUBLIC_AURABASE_ANON_KEY=your-anon-key-here
|
|
135
|
+
|
|
136
|
+
# 서버 사이드용
|
|
137
|
+
AURABASE_URL=https://your-project.cloudfront.net
|
|
138
|
+
AURABASE_ANON_KEY=your-anon-key-here
|
|
38
139
|
`;
|
|
39
140
|
|
|
40
141
|
function findProjectRoot(): string {
|
|
@@ -48,28 +149,38 @@ function findProjectRoot(): string {
|
|
|
48
149
|
return process.cwd();
|
|
49
150
|
}
|
|
50
151
|
|
|
51
|
-
function
|
|
52
|
-
const projectRoot = findProjectRoot();
|
|
152
|
+
function createFile(projectRoot: string, filename: string): boolean {
|
|
53
153
|
const filePath = path.join(projectRoot, filename);
|
|
54
154
|
const dir = path.dirname(filePath);
|
|
55
155
|
|
|
56
|
-
// Create directory if it doesn't exist
|
|
57
156
|
if (!fs.existsSync(dir)) {
|
|
58
157
|
fs.mkdirSync(dir, { recursive: true });
|
|
59
158
|
}
|
|
60
159
|
|
|
61
|
-
// Check if file already exists
|
|
62
160
|
if (fs.existsSync(filePath)) {
|
|
63
|
-
console.log(`\x1b[33m⚠ ${filename} already exists. Skipping...\x1b[0m`);
|
|
64
|
-
return;
|
|
161
|
+
console.log(`\x1b[33m ⚠ ${filename} already exists. Skipping...\x1b[0m`);
|
|
162
|
+
return false;
|
|
65
163
|
}
|
|
66
164
|
|
|
67
|
-
|
|
68
|
-
|
|
165
|
+
const template = TEMPLATES[filename as keyof typeof TEMPLATES];
|
|
166
|
+
if (!template) {
|
|
167
|
+
console.log(`\x1b[31m ✗ Unknown template: ${filename}\x1b[0m`);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
69
170
|
|
|
70
|
-
// Write file
|
|
71
171
|
fs.writeFileSync(filePath, template.trim() + '\n');
|
|
72
|
-
console.log(`\x1b[32m✓ Created ${filename}\x1b[0m`);
|
|
172
|
+
console.log(`\x1b[32m ✓ Created ${filename}\x1b[0m`);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function init() {
|
|
177
|
+
const projectRoot = findProjectRoot();
|
|
178
|
+
|
|
179
|
+
console.log('\x1b[1m\n🚀 Initializing AuraBase...\x1b[0m\n');
|
|
180
|
+
|
|
181
|
+
// Create all files
|
|
182
|
+
createFile(projectRoot, 'lib/aurabase.ts');
|
|
183
|
+
createFile(projectRoot, 'lib/api-client.ts');
|
|
73
184
|
|
|
74
185
|
// Show env template
|
|
75
186
|
console.log('\x1b[36m%s\x1b[0m', ENV_TEMPLATE);
|
|
@@ -80,11 +191,10 @@ function showHelp() {
|
|
|
80
191
|
\x1b[1mAuraBase JS CLI\x1b[0m
|
|
81
192
|
|
|
82
193
|
\x1b[1mUsage:\x1b[0m
|
|
83
|
-
npx aurabase-js init
|
|
194
|
+
npx aurabase-js init
|
|
84
195
|
|
|
85
196
|
\x1b[1mCommands:\x1b[0m
|
|
86
|
-
init Create lib/aurabase.ts
|
|
87
|
-
init --supabase Create lib/supabase.ts file (alias name)
|
|
197
|
+
init Create lib/aurabase.ts and lib/api-client.ts
|
|
88
198
|
|
|
89
199
|
\x1b[1mOptions:\x1b[0m
|
|
90
200
|
-h, --help Show this help message
|
|
@@ -92,7 +202,6 @@ function showHelp() {
|
|
|
92
202
|
|
|
93
203
|
\x1b[1mExamples:\x1b[0m
|
|
94
204
|
npx aurabase-js init
|
|
95
|
-
npx aurabase-js init --supabase
|
|
96
205
|
`);
|
|
97
206
|
}
|
|
98
207
|
|
|
@@ -116,9 +225,7 @@ function main() {
|
|
|
116
225
|
}
|
|
117
226
|
|
|
118
227
|
if (args[0] === 'init') {
|
|
119
|
-
|
|
120
|
-
const filename = useSupabase ? 'lib/supabase.ts' : 'lib/aurabase.ts';
|
|
121
|
-
init(filename);
|
|
228
|
+
init();
|
|
122
229
|
return;
|
|
123
230
|
}
|
|
124
231
|
|