@odvi/create-dtt-framework 0.1.13 → 0.1.15

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.
@@ -106,7 +106,7 @@ export const createCommand = new Command('create')
106
106
  packageJson.name = projectName;
107
107
  packageJson.version = '0.1.0';
108
108
  packageJson.dtt = {
109
- version: '0.1.9' // Current framework version
109
+ version: '0.1.14' // Current framework version
110
110
  };
111
111
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
112
112
  spinner.succeed('Project configured');
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odvi/create-dtt-framework",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "CLI tool to scaffold new projects with DTT Framework",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,78 @@
1
+ # Reusable Integrations
2
+
3
+ The DTT Framework provides a unified interface to access all configured integrations through a single `framework` instance. This allows you to easily use third-party services in your application logic without manually managing connections or clients.
4
+
5
+ ## Usage
6
+
7
+ You can import the `framework` instance from `@/lib/framework`.
8
+
9
+ ```typescript
10
+ import { framework } from '@/lib/framework'
11
+
12
+ async function myFunction() {
13
+ // 1. Clerk Authentication
14
+ const user = await framework.clerk.users.getUser('user_id')
15
+
16
+ // 2. Supabase (Admin Access)
17
+ const { data } = await framework.supabase
18
+ .from('my_table')
19
+ .select('*')
20
+
21
+ // 3. Snowflake Query
22
+ const rows = await framework.snowflake.query('SELECT * FROM PUBLIC.USERS LIMIT 10')
23
+
24
+ // 4. NextBank API
25
+ const account = await framework.nextbank.get('/accounts/123')
26
+ await framework.nextbank.post('/transfers', { amount: 100 })
27
+
28
+ // 5. Synology File Operations
29
+ const files = await framework.synology.listFiles('/home/user')
30
+ const fileContent = await framework.synology.getFile('/home/user/doc.pdf')
31
+
32
+ // 6. AWS S3
33
+ await framework.s3.uploadFile('my-bucket', 'uploads/hello.txt', 'Hello World')
34
+ }
35
+ ```
36
+
37
+ ## Integration Details
38
+
39
+ ### Clerk (`framework.clerk`)
40
+ Exposes the `@clerk/nextjs/server` client. Use this for server-side user management, organization handling, and session verification.
41
+
42
+ ### Supabase (`framework.supabase`)
43
+ Exposes the Supabase Admin client (using `SUPABASE_SERVICE_ROLE_KEY`).
44
+ **Note:** This client has full admin privileges. Be careful when using it in client-facing code (it should only be used server-side).
45
+
46
+ ### Snowflake (`framework.snowflake`)
47
+ Provides a simplified `query` method that handles connection pooling, execution, and cleanup automatically.
48
+ - `query(sqlText, binds?)`: Executes a SQL query.
49
+
50
+ ### NextBank (`framework.nextbank`)
51
+ A wrapper around the NextBank API that automatically handles:
52
+ - Base URL injection
53
+ - Authentication headers
54
+ - JSON parsing
55
+ - Error handling
56
+
57
+ Methods:
58
+ - `get(endpoint)`
59
+ - `post(endpoint, body)`
60
+ - `put(endpoint, body)`
61
+ - `delete(endpoint)`
62
+
63
+ ### Synology (`framework.synology`)
64
+ Provides methods to interact with Synology File Station.
65
+ - `listFiles(folderPath)`
66
+ - `getFile(filePath)`
67
+ - `deleteFile(filePath)`
68
+
69
+ ### AWS S3 (`framework.s3`)
70
+ Wraps the AWS SDK S3 Client.
71
+ - `listBuckets()`
72
+ - `listFiles(bucket, prefix?)`
73
+ - `uploadFile(bucket, key, body, contentType?)`
74
+ - `getFile(bucket, key)`
75
+ - `deleteFile(bucket, key)`
76
+ - `getPresignedUrl(bucket, key, expiresIn?)`
77
+ - `getClient()`: Returns the raw AWS S3 Client for advanced operations.
78
+
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odvi/dtt-framework",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -64,6 +64,7 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@aws-sdk/client-s3": "^3.958.0",
67
+ "@aws-sdk/s3-request-presigner": "^3.958.0",
67
68
  "@clerk/nextjs": "^6.36.5",
68
69
  "@radix-ui/react-collapsible": "^1.1.12",
69
70
  "@radix-ui/react-dialog": "^1.1.15",
@@ -0,0 +1,103 @@
1
+ import {
2
+ S3Client,
3
+ ListBucketsCommand,
4
+ PutObjectCommand,
5
+ GetObjectCommand,
6
+ DeleteObjectCommand,
7
+ ListObjectsV2Command
8
+ } from '@aws-sdk/client-s3'
9
+ import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
10
+ import { env } from '@/config/env'
11
+
12
+ export class S3IntegrationClient {
13
+ private client: S3Client
14
+ private region: string
15
+
16
+ constructor() {
17
+ this.region = env.AWS_REGION ?? 'us-east-1'
18
+
19
+ // Initialize with credentials from env
20
+ this.client = new S3Client({
21
+ region: this.region,
22
+ credentials: {
23
+ accessKeyId: env.AWS_ACCESS_KEY_ID ?? '',
24
+ secretAccessKey: env.AWS_ACCESS_SECRET_KEY ?? '',
25
+ },
26
+ })
27
+ }
28
+
29
+ /**
30
+ * Get the underlying S3 Client
31
+ */
32
+ getClient(): S3Client {
33
+ return this.client
34
+ }
35
+
36
+ /**
37
+ * List all buckets
38
+ */
39
+ async listBuckets() {
40
+ const command = new ListBucketsCommand({})
41
+ return this.client.send(command)
42
+ }
43
+
44
+ /**
45
+ * List files in a bucket
46
+ */
47
+ async listFiles(bucket: string, prefix?: string) {
48
+ const command = new ListObjectsV2Command({
49
+ Bucket: bucket,
50
+ Prefix: prefix,
51
+ })
52
+ return this.client.send(command)
53
+ }
54
+
55
+ /**
56
+ * Upload a file to S3
57
+ */
58
+ async uploadFile(bucket: string, key: string, body: Buffer | Uint8Array | Blob | string, contentType?: string) {
59
+ const command = new PutObjectCommand({
60
+ Bucket: bucket,
61
+ Key: key,
62
+ Body: body,
63
+ ContentType: contentType,
64
+ })
65
+ return this.client.send(command)
66
+ }
67
+
68
+ /**
69
+ * Get a file from S3 (returns the raw output)
70
+ */
71
+ async getFile(bucket: string, key: string) {
72
+ const command = new GetObjectCommand({
73
+ Bucket: bucket,
74
+ Key: key,
75
+ })
76
+ return this.client.send(command)
77
+ }
78
+
79
+ /**
80
+ * Generate a presigned URL for a file
81
+ */
82
+ async getPresignedUrl(bucket: string, key: string, expiresIn = 3600) {
83
+ const command = new GetObjectCommand({
84
+ Bucket: bucket,
85
+ Key: key,
86
+ })
87
+ return getSignedUrl(this.client, command, { expiresIn })
88
+ }
89
+
90
+ /**
91
+ * Delete a file from S3
92
+ */
93
+ async deleteFile(bucket: string, key: string) {
94
+ const command = new DeleteObjectCommand({
95
+ Bucket: bucket,
96
+ Key: key,
97
+ })
98
+ return this.client.send(command)
99
+ }
100
+ }
101
+
102
+ export const s3Client = new S3IntegrationClient()
103
+
@@ -0,0 +1,47 @@
1
+ import { clerkClient } from '@clerk/nextjs/server'
2
+ import { supabaseAdmin } from './supabase/admin'
3
+ import { nextbankClient } from './nextbank/client'
4
+ import { synologyClient } from './synology/client'
5
+ import { snowflakeClient } from './snowflake/client'
6
+ import { s3Client } from './aws-s3/client'
7
+
8
+ export class Framework {
9
+ /**
10
+ * Clerk Authentication SDK
11
+ * Use this to manage users, sessions, and organizations.
12
+ */
13
+ public clerk = clerkClient
14
+
15
+ /**
16
+ * Supabase Admin Client (Service Role)
17
+ * Use this for database and storage operations with full privileges.
18
+ */
19
+ public supabase = supabaseAdmin
20
+
21
+ /**
22
+ * Snowflake Client
23
+ * Use this to execute SQL queries against your Snowflake data warehouse.
24
+ */
25
+ public snowflake = snowflakeClient
26
+
27
+ /**
28
+ * AWS S3 Client
29
+ * Use this to manage files in AWS S3 buckets.
30
+ */
31
+ public s3 = s3Client
32
+
33
+ /**
34
+ * NextBank Integration
35
+ * Use this to interact with the NextBank API.
36
+ */
37
+ public nextbank = nextbankClient
38
+
39
+ /**
40
+ * Synology Integration
41
+ * Use this to manage files on a Synology NAS.
42
+ */
43
+ public synology = synologyClient
44
+ }
45
+
46
+ export const framework = new Framework()
47
+
@@ -17,22 +17,21 @@ class NextBankClient {
17
17
  return { Authorization: `Basic ${token}` }
18
18
  }
19
19
 
20
- async ping(fingerprint: string): Promise<{ status: string; timestamp: string }> {
21
- const url = `${this.apiUrl}/management/status`
22
- console.log(`[NextBank] Pinging ${url}`)
20
+ private async request<T = any>(endpoint: string, options: RequestInit = {}): Promise<T> {
21
+ const url = `${this.apiUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`
23
22
 
23
+ const headers = {
24
+ ...this.getAuthHeader(),
25
+ 'Content-Type': 'application/json',
26
+ 'Accept': 'application/json',
27
+ 'User-Agent': 'dtt-framework-client',
28
+ ...options.headers,
29
+ }
30
+
24
31
  try {
25
32
  const response = await fetch(url, {
26
- method: 'POST',
27
- headers: {
28
- ...this.getAuthHeader(),
29
- 'Content-Type': 'application/json',
30
- 'Accept': 'application/json',
31
- 'User-Agent': 'dtt-framework-health-check',
32
- },
33
- body: JSON.stringify({
34
- fingerprint: fingerprint,
35
- }),
33
+ ...options,
34
+ headers,
36
35
  })
37
36
 
38
37
  const contentType = response.headers.get('content-type')
@@ -40,28 +39,54 @@ class NextBankClient {
40
39
  if (!response.ok) {
41
40
  if (contentType && contentType.includes('text/html')) {
42
41
  const text = await response.text()
43
- console.error('[NextBank] Received HTML error response. Possible causes:')
44
- console.error('1. NEXTBANK_API is pointing to the wrong server (e.g. Next.js app instead of NextBank API)')
45
- console.error('2. The endpoint /management/status does not exist or does not support POST')
46
- console.error(`[NextBank] Response preview: ${text.substring(0, 150)}...`)
47
- throw new Error(`NextBank API error: ${response.status} (HTML response)`)
42
+ throw new Error(`NextBank API error: ${response.status} (HTML response): ${text.substring(0, 100)}...`)
48
43
  }
49
44
  throw new Error(`NextBank API error: ${response.status} ${response.statusText}`)
50
45
  }
51
46
 
52
47
  if (contentType && contentType.includes('application/json')) {
53
48
  return await response.json()
54
- } else {
55
- const text = await response.text()
56
- console.error('[NextBank] Invalid response content type:', contentType)
57
- console.error('[NextBank] Response preview:', text.substring(0, 200))
58
- throw new Error(`Invalid response format. Expected JSON, got ${contentType}`)
49
+ }
50
+
51
+ // If not JSON, return text if generic T is string, or try to return as is?
52
+ // For now, assume JSON or void.
53
+ const text = await response.text()
54
+ try {
55
+ return JSON.parse(text)
56
+ } catch {
57
+ return text as unknown as T
59
58
  }
60
59
  } catch (error) {
61
- console.error('[NextBank] Ping failed:', error)
60
+ console.error(`[NextBank] Request to ${endpoint} failed:`, error)
62
61
  throw error
63
62
  }
64
63
  }
64
+
65
+ async get<T = any>(endpoint: string): Promise<T> {
66
+ return this.request<T>(endpoint, { method: 'GET' })
67
+ }
68
+
69
+ async post<T = any>(endpoint: string, body: any): Promise<T> {
70
+ return this.request<T>(endpoint, {
71
+ method: 'POST',
72
+ body: JSON.stringify(body)
73
+ })
74
+ }
75
+
76
+ async put<T = any>(endpoint: string, body: any): Promise<T> {
77
+ return this.request<T>(endpoint, {
78
+ method: 'PUT',
79
+ body: JSON.stringify(body)
80
+ })
81
+ }
82
+
83
+ async delete<T = any>(endpoint: string): Promise<T> {
84
+ return this.request<T>(endpoint, { method: 'DELETE' })
85
+ }
86
+
87
+ async ping(fingerprint: string): Promise<{ status: string; timestamp: string }> {
88
+ return this.post('/management/status', { fingerprint })
89
+ }
65
90
  }
66
91
 
67
92
  export const nextbankClient = new NextBankClient()
@@ -100,3 +100,40 @@ export async function destroyConnection(connection: Connection): Promise<void> {
100
100
  })
101
101
  })
102
102
  }
103
+
104
+ export class SnowflakeClient {
105
+ async query<T = unknown>(sqlText: string, binds?: Bind[]): Promise<T[]> {
106
+ let connection: Connection | undefined
107
+ try {
108
+ connection = await createSnowflakeConnection()
109
+
110
+ // Connect
111
+ await new Promise<void>((resolve, reject) => {
112
+ connection!.connect((err) => {
113
+ if (err) reject(err)
114
+ else resolve()
115
+ })
116
+ })
117
+
118
+ // Execute
119
+ return await new Promise<T[]>((resolve, reject) => {
120
+ connection!.execute({
121
+ sqlText,
122
+ binds: binds as any,
123
+ complete: (err, stmt, rows) => {
124
+ if (err) reject(err)
125
+ else resolve((rows || []) as T[])
126
+ },
127
+ })
128
+ })
129
+ } finally {
130
+ if (connection) {
131
+ connection.destroy((err) => {
132
+ if (err) console.error('Error destroying Snowflake connection:', err)
133
+ })
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ export const snowflakeClient = new SnowflakeClient()
@@ -74,6 +74,79 @@ class SynologyClient {
74
74
  }
75
75
  }
76
76
 
77
+ async listFiles(folderPath: string) {
78
+ if (!this.sessionID) await this.login()
79
+
80
+ const params = new URLSearchParams({
81
+ api: 'SYNO.FileStation.List',
82
+ version: '2',
83
+ method: 'list',
84
+ folder_path: folderPath,
85
+ _sid: this.sessionID!
86
+ })
87
+
88
+ const url = `${this.host}/webapi/entry.cgi?${params.toString()}`
89
+ const response = await this.fetchWithAgent(url)
90
+
91
+ if (!response.ok) {
92
+ throw new Error(`Synology ListFiles error: ${response.status}`)
93
+ }
94
+
95
+ const data = await response.json()
96
+ if (!data.success) {
97
+ throw new Error(`Synology ListFiles failed: ${JSON.stringify(data)}`)
98
+ }
99
+ return data.data.files
100
+ }
101
+
102
+ async getFile(filePath: string) {
103
+ if (!this.sessionID) await this.login()
104
+
105
+ const params = new URLSearchParams({
106
+ api: 'SYNO.FileStation.Download',
107
+ version: '2',
108
+ method: 'download',
109
+ path: filePath,
110
+ mode: 'open',
111
+ _sid: this.sessionID!
112
+ })
113
+
114
+ const url = `${this.host}/webapi/entry.cgi?${params.toString()}`
115
+ const response = await this.fetchWithAgent(url)
116
+
117
+ if (!response.ok) {
118
+ throw new Error(`Synology GetFile error: ${response.status}`)
119
+ }
120
+
121
+ // Return array buffer or blob?
122
+ return response.arrayBuffer()
123
+ }
124
+
125
+ async deleteFile(filePath: string) {
126
+ if (!this.sessionID) await this.login()
127
+
128
+ const params = new URLSearchParams({
129
+ api: 'SYNO.FileStation.Delete',
130
+ version: '2',
131
+ method: 'delete',
132
+ path: filePath,
133
+ _sid: this.sessionID!
134
+ })
135
+
136
+ const url = `${this.host}/webapi/entry.cgi?${params.toString()}`
137
+ const response = await this.fetchWithAgent(url)
138
+
139
+ if (!response.ok) {
140
+ throw new Error(`Synology DeleteFile error: ${response.status}`)
141
+ }
142
+
143
+ const data = await response.json()
144
+ if (!data.success) {
145
+ throw new Error(`Synology DeleteFile failed: ${JSON.stringify(data)}`)
146
+ }
147
+ return data
148
+ }
149
+
77
150
  async ping(): Promise<{ status: string; timestamp: string; version?: string; sid?: string }> {
78
151
  if (!this.host) {
79
152
  throw new Error('Synology host not configured')