@hasna/connectors 0.5.7 → 0.5.9
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 +48 -9
- package/bin/index.js +57 -1
- package/bin/mcp.js +57 -1
- package/bin/serve.js +56 -0
- package/connectors/connect-chargebee/.env.example +11 -0
- package/connectors/connect-chargebee/CLAUDE.md +272 -0
- package/connectors/connect-chargebee/README.md +193 -0
- package/connectors/connect-chargebee/package.json +51 -0
- package/connectors/connect-chargebee/scripts/release.ts +179 -0
- package/connectors/connect-chargebee/src/api/client.ts +213 -0
- package/connectors/connect-chargebee/src/api/example.ts +48 -0
- package/connectors/connect-chargebee/src/api/index.ts +51 -0
- package/connectors/connect-chargebee/src/cli/index.ts +254 -0
- package/connectors/connect-chargebee/src/index.ts +103 -0
- package/connectors/connect-chargebee/src/types/index.ts +237 -0
- package/connectors/connect-chargebee/src/utils/auth.ts +274 -0
- package/connectors/connect-chargebee/src/utils/bulk.ts +212 -0
- package/connectors/connect-chargebee/src/utils/config.ts +326 -0
- package/connectors/connect-chargebee/src/utils/output.ts +175 -0
- package/connectors/connect-chargebee/src/utils/settings.ts +114 -0
- package/connectors/connect-chargebee/src/utils/storage.ts +198 -0
- package/connectors/connect-chargebee/tsconfig.json +16 -0
- package/connectors/connect-databricks/.env.example +11 -0
- package/connectors/connect-databricks/CLAUDE.md +272 -0
- package/connectors/connect-databricks/README.md +193 -0
- package/connectors/connect-databricks/package.json +51 -0
- package/connectors/connect-databricks/scripts/release.ts +179 -0
- package/connectors/connect-databricks/src/api/client.ts +213 -0
- package/connectors/connect-databricks/src/api/example.ts +48 -0
- package/connectors/connect-databricks/src/api/index.ts +51 -0
- package/connectors/connect-databricks/src/cli/index.ts +254 -0
- package/connectors/connect-databricks/src/index.ts +103 -0
- package/connectors/connect-databricks/src/types/index.ts +237 -0
- package/connectors/connect-databricks/src/utils/auth.ts +274 -0
- package/connectors/connect-databricks/src/utils/bulk.ts +212 -0
- package/connectors/connect-databricks/src/utils/config.ts +326 -0
- package/connectors/connect-databricks/src/utils/output.ts +175 -0
- package/connectors/connect-databricks/src/utils/settings.ts +114 -0
- package/connectors/connect-databricks/src/utils/storage.ts +198 -0
- package/connectors/connect-databricks/tsconfig.json +16 -0
- package/connectors/connect-datadog/.env.example +11 -0
- package/connectors/connect-datadog/CLAUDE.md +170 -0
- package/connectors/connect-datadog/README.md +193 -0
- package/connectors/connect-datadog/package.json +53 -0
- package/connectors/connect-datadog/src/api/client.ts +150 -0
- package/connectors/connect-datadog/src/api/index.ts +537 -0
- package/connectors/connect-datadog/src/cli/index.ts +958 -0
- package/connectors/connect-datadog/src/index.ts +26 -0
- package/connectors/connect-datadog/src/types/index.ts +654 -0
- package/connectors/connect-datadog/src/utils/config.ts +219 -0
- package/connectors/connect-datadog/src/utils/output.ts +119 -0
- package/connectors/connect-datadog/tsconfig.json +16 -0
- package/connectors/connect-fathom/.env.example +11 -0
- package/connectors/connect-fathom/CLAUDE.md +272 -0
- package/connectors/connect-fathom/README.md +193 -0
- package/connectors/connect-fathom/package.json +51 -0
- package/connectors/connect-fathom/scripts/release.ts +179 -0
- package/connectors/connect-fathom/src/api/client.ts +213 -0
- package/connectors/connect-fathom/src/api/example.ts +48 -0
- package/connectors/connect-fathom/src/api/index.ts +51 -0
- package/connectors/connect-fathom/src/cli/index.ts +254 -0
- package/connectors/connect-fathom/src/index.ts +103 -0
- package/connectors/connect-fathom/src/types/index.ts +237 -0
- package/connectors/connect-fathom/src/utils/auth.ts +274 -0
- package/connectors/connect-fathom/src/utils/bulk.ts +212 -0
- package/connectors/connect-fathom/src/utils/config.ts +326 -0
- package/connectors/connect-fathom/src/utils/output.ts +175 -0
- package/connectors/connect-fathom/src/utils/settings.ts +114 -0
- package/connectors/connect-fathom/src/utils/storage.ts +198 -0
- package/connectors/connect-fathom/tsconfig.json +16 -0
- package/connectors/connect-grafana/.env.example +11 -0
- package/connectors/connect-grafana/CLAUDE.md +272 -0
- package/connectors/connect-grafana/README.md +193 -0
- package/connectors/connect-grafana/package.json +51 -0
- package/connectors/connect-grafana/scripts/release.ts +179 -0
- package/connectors/connect-grafana/src/api/client.ts +213 -0
- package/connectors/connect-grafana/src/api/example.ts +48 -0
- package/connectors/connect-grafana/src/api/index.ts +51 -0
- package/connectors/connect-grafana/src/cli/index.ts +254 -0
- package/connectors/connect-grafana/src/index.ts +103 -0
- package/connectors/connect-grafana/src/types/index.ts +237 -0
- package/connectors/connect-grafana/src/utils/auth.ts +274 -0
- package/connectors/connect-grafana/src/utils/bulk.ts +212 -0
- package/connectors/connect-grafana/src/utils/config.ts +326 -0
- package/connectors/connect-grafana/src/utils/output.ts +175 -0
- package/connectors/connect-grafana/src/utils/settings.ts +114 -0
- package/connectors/connect-grafana/src/utils/storage.ts +198 -0
- package/connectors/connect-grafana/tsconfig.json +16 -0
- package/connectors/connect-paddle/.env.example +11 -0
- package/connectors/connect-paddle/CLAUDE.md +272 -0
- package/connectors/connect-paddle/README.md +193 -0
- package/connectors/connect-paddle/package.json +51 -0
- package/connectors/connect-paddle/scripts/release.ts +179 -0
- package/connectors/connect-paddle/src/api/client.ts +213 -0
- package/connectors/connect-paddle/src/api/example.ts +48 -0
- package/connectors/connect-paddle/src/api/index.ts +51 -0
- package/connectors/connect-paddle/src/cli/index.ts +254 -0
- package/connectors/connect-paddle/src/index.ts +103 -0
- package/connectors/connect-paddle/src/types/index.ts +237 -0
- package/connectors/connect-paddle/src/utils/auth.ts +274 -0
- package/connectors/connect-paddle/src/utils/bulk.ts +212 -0
- package/connectors/connect-paddle/src/utils/config.ts +326 -0
- package/connectors/connect-paddle/src/utils/output.ts +175 -0
- package/connectors/connect-paddle/src/utils/settings.ts +114 -0
- package/connectors/connect-paddle/src/utils/storage.ts +198 -0
- package/connectors/connect-paddle/tsconfig.json +16 -0
- package/connectors/connect-snowflake/.env.example +11 -0
- package/connectors/connect-snowflake/CLAUDE.md +272 -0
- package/connectors/connect-snowflake/README.md +193 -0
- package/connectors/connect-snowflake/package.json +51 -0
- package/connectors/connect-snowflake/scripts/release.ts +179 -0
- package/connectors/connect-snowflake/src/api/client.ts +213 -0
- package/connectors/connect-snowflake/src/api/example.ts +48 -0
- package/connectors/connect-snowflake/src/api/index.ts +51 -0
- package/connectors/connect-snowflake/src/cli/index.ts +254 -0
- package/connectors/connect-snowflake/src/index.ts +103 -0
- package/connectors/connect-snowflake/src/types/index.ts +237 -0
- package/connectors/connect-snowflake/src/utils/auth.ts +274 -0
- package/connectors/connect-snowflake/src/utils/bulk.ts +212 -0
- package/connectors/connect-snowflake/src/utils/config.ts +326 -0
- package/connectors/connect-snowflake/src/utils/output.ts +175 -0
- package/connectors/connect-snowflake/src/utils/settings.ts +114 -0
- package/connectors/connect-snowflake/src/utils/storage.ts +198 -0
- package/connectors/connect-snowflake/tsconfig.json +16 -0
- package/connectors/connect-square/.env.example +11 -0
- package/connectors/connect-square/CLAUDE.md +128 -0
- package/connectors/connect-square/README.md +193 -0
- package/connectors/connect-square/package.json +52 -0
- package/connectors/connect-square/src/api/client.ts +152 -0
- package/connectors/connect-square/src/api/index.ts +343 -0
- package/connectors/connect-square/src/cli/index.ts +579 -0
- package/connectors/connect-square/src/index.ts +21 -0
- package/connectors/connect-square/src/types/index.ts +809 -0
- package/connectors/connect-square/src/utils/config.ts +209 -0
- package/connectors/connect-square/src/utils/output.ts +119 -0
- package/connectors/connect-square/tsconfig.json +16 -0
- package/dist/index.js +56 -0
- package/package.json +1 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { getConfigDir } from './config';
|
|
4
|
+
|
|
5
|
+
// ============================================
|
|
6
|
+
// Generic Data Storage Utility
|
|
7
|
+
// ============================================
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Base interface for storable entities
|
|
11
|
+
* All stored entities should have an id field
|
|
12
|
+
*/
|
|
13
|
+
export interface Storable {
|
|
14
|
+
id: string;
|
|
15
|
+
createdAt?: string;
|
|
16
|
+
updatedAt?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the storage directory for an entity type
|
|
21
|
+
*/
|
|
22
|
+
function getStorageDir(entityType: string): string {
|
|
23
|
+
const dir = join(getConfigDir(), 'data', entityType);
|
|
24
|
+
if (!existsSync(dir)) {
|
|
25
|
+
mkdirSync(dir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
return dir;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Convert an ID to a safe filename
|
|
32
|
+
*/
|
|
33
|
+
function idToFilename(id: string): string {
|
|
34
|
+
return id.toLowerCase().replace(/[^a-z0-9]/g, '_') + '.json';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get the file path for an entity
|
|
39
|
+
*/
|
|
40
|
+
function getEntityPath(entityType: string, id: string): string {
|
|
41
|
+
return join(getStorageDir(entityType), idToFilename(id));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Save an entity to storage
|
|
46
|
+
*/
|
|
47
|
+
export function saveEntity<T extends Storable>(entityType: string, entity: T): void {
|
|
48
|
+
const filepath = getEntityPath(entityType, entity.id);
|
|
49
|
+
const now = new Date().toISOString();
|
|
50
|
+
|
|
51
|
+
const existing = getEntity<T>(entityType, entity.id);
|
|
52
|
+
|
|
53
|
+
const data: T = {
|
|
54
|
+
...entity,
|
|
55
|
+
createdAt: existing?.createdAt || now,
|
|
56
|
+
updatedAt: now,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
writeFileSync(filepath, JSON.stringify(data, null, 2));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get an entity by ID
|
|
64
|
+
*/
|
|
65
|
+
export function getEntity<T extends Storable>(entityType: string, id: string): T | null {
|
|
66
|
+
const filepath = getEntityPath(entityType, id);
|
|
67
|
+
|
|
68
|
+
if (!existsSync(filepath)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
74
|
+
return JSON.parse(content) as T;
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if an entity exists
|
|
82
|
+
*/
|
|
83
|
+
export function entityExists(entityType: string, id: string): boolean {
|
|
84
|
+
return existsSync(getEntityPath(entityType, id));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get all entities of a type
|
|
89
|
+
*/
|
|
90
|
+
export function getAllEntities<T extends Storable>(entityType: string): T[] {
|
|
91
|
+
const storageDir = getStorageDir(entityType);
|
|
92
|
+
const files = readdirSync(storageDir).filter(f => f.endsWith('.json'));
|
|
93
|
+
|
|
94
|
+
const entities: T[] = [];
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
try {
|
|
97
|
+
const content = readFileSync(join(storageDir, file), 'utf-8');
|
|
98
|
+
entities.push(JSON.parse(content) as T);
|
|
99
|
+
} catch {
|
|
100
|
+
// Skip invalid files
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return entities.sort((a, b) => a.id.localeCompare(b.id));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Delete an entity
|
|
109
|
+
*/
|
|
110
|
+
export function deleteEntity(entityType: string, id: string): boolean {
|
|
111
|
+
const filepath = getEntityPath(entityType, id);
|
|
112
|
+
|
|
113
|
+
if (existsSync(filepath)) {
|
|
114
|
+
unlinkSync(filepath);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Search entities by a predicate function
|
|
122
|
+
*/
|
|
123
|
+
export function searchEntities<T extends Storable>(
|
|
124
|
+
entityType: string,
|
|
125
|
+
predicate: (entity: T) => boolean
|
|
126
|
+
): T[] {
|
|
127
|
+
const all = getAllEntities<T>(entityType);
|
|
128
|
+
return all.filter(predicate);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Search entities by text match across all string fields
|
|
133
|
+
*/
|
|
134
|
+
export function searchEntitiesByText<T extends Storable>(
|
|
135
|
+
entityType: string,
|
|
136
|
+
query: string,
|
|
137
|
+
fields?: (keyof T)[]
|
|
138
|
+
): T[] {
|
|
139
|
+
const all = getAllEntities<T>(entityType);
|
|
140
|
+
const q = query.toLowerCase();
|
|
141
|
+
|
|
142
|
+
return all.filter(entity => {
|
|
143
|
+
const searchFields = fields || (Object.keys(entity) as (keyof T)[]);
|
|
144
|
+
return searchFields.some(field => {
|
|
145
|
+
const value = entity[field];
|
|
146
|
+
if (typeof value === 'string') {
|
|
147
|
+
return value.toLowerCase().includes(q);
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Count entities of a type
|
|
156
|
+
*/
|
|
157
|
+
export function countEntities(entityType: string): number {
|
|
158
|
+
const storageDir = getStorageDir(entityType);
|
|
159
|
+
if (!existsSync(storageDir)) {
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
return readdirSync(storageDir).filter(f => f.endsWith('.json')).length;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Clear all entities of a type
|
|
167
|
+
*/
|
|
168
|
+
export function clearEntities(entityType: string): number {
|
|
169
|
+
const storageDir = getStorageDir(entityType);
|
|
170
|
+
if (!existsSync(storageDir)) {
|
|
171
|
+
return 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const files = readdirSync(storageDir).filter(f => f.endsWith('.json'));
|
|
175
|
+
for (const file of files) {
|
|
176
|
+
unlinkSync(join(storageDir, file));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return files.length;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Create a typed storage helper for a specific entity type
|
|
184
|
+
* This provides a cleaner API for working with a single entity type
|
|
185
|
+
*/
|
|
186
|
+
export function createStorage<T extends Storable>(entityType: string) {
|
|
187
|
+
return {
|
|
188
|
+
save: (entity: T) => saveEntity<T>(entityType, entity),
|
|
189
|
+
get: (id: string) => getEntity<T>(entityType, id),
|
|
190
|
+
exists: (id: string) => entityExists(entityType, id),
|
|
191
|
+
getAll: () => getAllEntities<T>(entityType),
|
|
192
|
+
delete: (id: string) => deleteEntity(entityType, id),
|
|
193
|
+
search: (predicate: (entity: T) => boolean) => searchEntities<T>(entityType, predicate),
|
|
194
|
+
searchByText: (query: string, fields?: (keyof T)[]) => searchEntitiesByText<T>(entityType, query, fields),
|
|
195
|
+
count: () => countEntities(entityType),
|
|
196
|
+
clear: () => clearEntities(entityType),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"rootDir": "./src",
|
|
12
|
+
"types": ["bun-types"]
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"],
|
|
15
|
+
"exclude": ["node_modules", "dist", "bin"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# API Credentials
|
|
2
|
+
# TODO: Update variable names and instructions for your API
|
|
3
|
+
# Example: PERPLEXITY_API_KEY, OPENAI_API_KEY, etc.
|
|
4
|
+
|
|
5
|
+
CONNECTOR_API_KEY=your-api-key-here
|
|
6
|
+
|
|
7
|
+
# Optional: API secret (if your API requires it)
|
|
8
|
+
# CONNECTOR_API_SECRET=your-api-secret-here
|
|
9
|
+
|
|
10
|
+
# Optional: Custom base URL (if needed)
|
|
11
|
+
# CONNECTOR_BASE_URL=https://api.example.com
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
connect-datadog is a TypeScript connector for Datadog's REST API. It provides a CLI and programmatic interface for managing metrics, monitors, dashboards, SLOs, events, hosts, downtimes, synthetics, and users.
|
|
8
|
+
|
|
9
|
+
## Build & Run Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun install # Install dependencies
|
|
13
|
+
bun run dev # Run CLI in development
|
|
14
|
+
bun run build # Build for distribution
|
|
15
|
+
bun run typecheck # Type check
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## CLI Commands
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Authentication
|
|
22
|
+
connect-datadog config set-api-key <key> # Set API key
|
|
23
|
+
connect-datadog config set-app-key <key> # Set Application key
|
|
24
|
+
connect-datadog config set-site <site> # Set Datadog site
|
|
25
|
+
connect-datadog config show # Show current config
|
|
26
|
+
connect-datadog config clear # Clear config
|
|
27
|
+
|
|
28
|
+
# Profile management
|
|
29
|
+
connect-datadog profile list # List profiles
|
|
30
|
+
connect-datadog profile use <name> # Switch profile
|
|
31
|
+
connect-datadog profile create <name> # Create profile
|
|
32
|
+
connect-datadog profile delete <name> # Delete profile
|
|
33
|
+
|
|
34
|
+
# Validation
|
|
35
|
+
connect-datadog validate # Validate credentials
|
|
36
|
+
|
|
37
|
+
# Organization
|
|
38
|
+
connect-datadog org # Get organization info
|
|
39
|
+
|
|
40
|
+
# Metrics
|
|
41
|
+
connect-datadog metrics query -q <query> # Query metrics
|
|
42
|
+
connect-datadog metrics list --from <ts> # List active metrics
|
|
43
|
+
connect-datadog metrics metadata <name> # Get metric metadata
|
|
44
|
+
|
|
45
|
+
# Events
|
|
46
|
+
connect-datadog events list --start <ts> --end <ts> # List events
|
|
47
|
+
connect-datadog events get <id> # Get an event
|
|
48
|
+
connect-datadog events create --title <t> --text <t> # Create event
|
|
49
|
+
|
|
50
|
+
# Monitors
|
|
51
|
+
connect-datadog monitors list # List monitors
|
|
52
|
+
connect-datadog monitors get <id> # Get a monitor
|
|
53
|
+
connect-datadog monitors delete <id> # Delete a monitor
|
|
54
|
+
connect-datadog monitors mute <id> # Mute a monitor
|
|
55
|
+
connect-datadog monitors unmute <id> # Unmute a monitor
|
|
56
|
+
|
|
57
|
+
# Dashboards
|
|
58
|
+
connect-datadog dashboards list # List dashboards
|
|
59
|
+
connect-datadog dashboards get <id> # Get a dashboard
|
|
60
|
+
connect-datadog dashboards delete <id> # Delete a dashboard
|
|
61
|
+
|
|
62
|
+
# SLOs
|
|
63
|
+
connect-datadog slos list # List SLOs
|
|
64
|
+
connect-datadog slos get <id> # Get an SLO
|
|
65
|
+
connect-datadog slos delete <id> # Delete an SLO
|
|
66
|
+
connect-datadog slos history <id> --from <ts> --to <ts> # Get SLO history
|
|
67
|
+
|
|
68
|
+
# Hosts
|
|
69
|
+
connect-datadog hosts list # List hosts
|
|
70
|
+
connect-datadog hosts totals # Get host totals
|
|
71
|
+
connect-datadog hosts mute <hostname> # Mute a host
|
|
72
|
+
connect-datadog hosts unmute <hostname> # Unmute a host
|
|
73
|
+
|
|
74
|
+
# Downtimes
|
|
75
|
+
connect-datadog downtimes list # List downtimes
|
|
76
|
+
connect-datadog downtimes get <id> # Get a downtime
|
|
77
|
+
connect-datadog downtimes create --scope <s> # Create downtime
|
|
78
|
+
connect-datadog downtimes delete <id> # Delete a downtime
|
|
79
|
+
connect-datadog downtimes cancel-by-scope --scope <s> # Cancel by scope
|
|
80
|
+
|
|
81
|
+
# Synthetics
|
|
82
|
+
connect-datadog synthetics list # List synthetic tests
|
|
83
|
+
connect-datadog synthetics get <publicId> # Get a test
|
|
84
|
+
connect-datadog synthetics delete <ids> # Delete tests
|
|
85
|
+
connect-datadog synthetics trigger <ids> # Trigger tests
|
|
86
|
+
connect-datadog synthetics results <publicId> # Get test results
|
|
87
|
+
|
|
88
|
+
# Users
|
|
89
|
+
connect-datadog users list # List users
|
|
90
|
+
connect-datadog users get <id> # Get a user
|
|
91
|
+
connect-datadog users me # Get current user
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Environment Variables
|
|
95
|
+
|
|
96
|
+
| Variable | Description |
|
|
97
|
+
|----------|-------------|
|
|
98
|
+
| `DATADOG_API_KEY` | API key (overrides profile) |
|
|
99
|
+
| `DATADOG_APP_KEY` | Application key (overrides profile) |
|
|
100
|
+
| `DATADOG_SITE` | Datadog site (e.g., datadoghq.com, datadoghq.eu) |
|
|
101
|
+
|
|
102
|
+
## Authentication
|
|
103
|
+
|
|
104
|
+
Uses DD-API-KEY and DD-APPLICATION-KEY headers. Get your keys from:
|
|
105
|
+
https://app.datadoghq.com/organization-settings/api-keys
|
|
106
|
+
|
|
107
|
+
Supported sites:
|
|
108
|
+
- datadoghq.com (US1 - default)
|
|
109
|
+
- us3.datadoghq.com (US3)
|
|
110
|
+
- us5.datadoghq.com (US5)
|
|
111
|
+
- datadoghq.eu (EU)
|
|
112
|
+
- ap1.datadoghq.com (AP1)
|
|
113
|
+
- ddog-gov.com (US1-FED)
|
|
114
|
+
|
|
115
|
+
## Data Storage
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
~/.connect/connect-datadog/
|
|
119
|
+
├── current_profile # Active profile name
|
|
120
|
+
└── profiles/
|
|
121
|
+
├── default.json # Default profile
|
|
122
|
+
└── {name}.json # Named profiles
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Profile JSON structure:
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"apiKey": "xxx",
|
|
129
|
+
"appKey": "xxx",
|
|
130
|
+
"site": "datadoghq.com"
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Code Style
|
|
135
|
+
|
|
136
|
+
- TypeScript with strict mode
|
|
137
|
+
- ESM modules (type: module)
|
|
138
|
+
- Use async/await for all async operations
|
|
139
|
+
- Type annotations required everywhere
|
|
140
|
+
|
|
141
|
+
## Project Structure
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
src/
|
|
145
|
+
├── api/
|
|
146
|
+
│ ├── client.ts # HTTP client with DD-API-KEY/DD-APPLICATION-KEY auth
|
|
147
|
+
│ └── index.ts # Datadog API wrapper
|
|
148
|
+
├── cli/
|
|
149
|
+
│ └── index.ts # CLI commands
|
|
150
|
+
├── types/
|
|
151
|
+
│ └── index.ts # Type definitions
|
|
152
|
+
├── utils/
|
|
153
|
+
│ ├── config.ts # Multi-profile configuration
|
|
154
|
+
│ └── output.ts # CLI output formatting
|
|
155
|
+
└── index.ts # Library exports
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API Coverage
|
|
159
|
+
|
|
160
|
+
- Metrics: Query, list active, get/update metadata, submit
|
|
161
|
+
- Events: List, get, create
|
|
162
|
+
- Monitors: List, get, create, update, delete, mute, unmute
|
|
163
|
+
- Dashboards: List, get, create, update, delete
|
|
164
|
+
- SLOs: List, get, create, update, delete, history
|
|
165
|
+
- Hosts: List, totals, mute, unmute
|
|
166
|
+
- Downtimes: List, get, create, update, delete, cancel by scope
|
|
167
|
+
- Synthetics: List, get, create, update, delete, trigger, results
|
|
168
|
+
- Users: List, get, current user (v2 API)
|
|
169
|
+
- Organization: Get info
|
|
170
|
+
- Validate: Validate credentials
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# scaffold-connector
|
|
2
|
+
|
|
3
|
+
A TypeScript scaffold for building API connector CLIs with multi-profile support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Multi-profile configuration (switch between different API keys/accounts)
|
|
8
|
+
- Bearer token authentication (easily customizable)
|
|
9
|
+
- Clean CLI structure with Commander.js
|
|
10
|
+
- Pretty and JSON output formats
|
|
11
|
+
- TypeScript with strict mode
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Clone and Rename
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Clone for your connector
|
|
19
|
+
git clone https://github.com/hasna/scaffold-connector.git connect-yourapi
|
|
20
|
+
cd connect-yourapi
|
|
21
|
+
|
|
22
|
+
# Update package.json name
|
|
23
|
+
# Change "@hasna/scaffold-connector" to "@hasna/connect-yourapi"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. Update Configuration
|
|
27
|
+
|
|
28
|
+
Search for `TODO` comments throughout the codebase and update:
|
|
29
|
+
|
|
30
|
+
- `src/cli/index.ts` - Update `CONNECTOR_NAME` and description
|
|
31
|
+
- `src/utils/config.ts` - Update `CONNECTOR_NAME` and env var names
|
|
32
|
+
- `src/api/client.ts` - Update `DEFAULT_BASE_URL` and authentication method
|
|
33
|
+
- `src/api/index.ts` - Rename `Connector` class to your API name
|
|
34
|
+
- `src/types/index.ts` - Add your API's type definitions
|
|
35
|
+
- `package.json` - Update name, description, bin command
|
|
36
|
+
- `.env.example` - Update environment variable names
|
|
37
|
+
|
|
38
|
+
### 3. Install and Test
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Install dependencies
|
|
42
|
+
bun install
|
|
43
|
+
|
|
44
|
+
# Run CLI
|
|
45
|
+
bun run dev
|
|
46
|
+
|
|
47
|
+
# Or run specific commands
|
|
48
|
+
bun run dev profile list
|
|
49
|
+
bun run dev config show
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## CLI Structure
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
connector [options] [command]
|
|
56
|
+
|
|
57
|
+
Options:
|
|
58
|
+
-k, --api-key <key> API key (overrides config)
|
|
59
|
+
-f, --format <format> Output format (json, pretty)
|
|
60
|
+
-p, --profile <profile> Use a specific profile
|
|
61
|
+
|
|
62
|
+
Commands:
|
|
63
|
+
profile list List all profiles
|
|
64
|
+
profile use <name> Switch to a profile
|
|
65
|
+
profile create <name> Create a new profile
|
|
66
|
+
profile delete <name> Delete a profile
|
|
67
|
+
profile show [name] Show profile configuration
|
|
68
|
+
|
|
69
|
+
config set-key <key> Set API key for active profile
|
|
70
|
+
config show Show current configuration
|
|
71
|
+
config clear Clear configuration
|
|
72
|
+
|
|
73
|
+
example list Example API command (replace)
|
|
74
|
+
example get <id> Example API command (replace)
|
|
75
|
+
example create Example API command (replace)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Project Structure
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
src/
|
|
82
|
+
├── api/
|
|
83
|
+
│ ├── client.ts # HTTP client with authentication
|
|
84
|
+
│ ├── example.ts # Example API module (replace with your API)
|
|
85
|
+
│ └── index.ts # Main connector class
|
|
86
|
+
├── cli/
|
|
87
|
+
│ └── index.ts # CLI commands
|
|
88
|
+
├── types/
|
|
89
|
+
│ └── index.ts # Type definitions
|
|
90
|
+
├── utils/
|
|
91
|
+
│ ├── config.ts # Multi-profile configuration
|
|
92
|
+
│ └── output.ts # CLI output formatting
|
|
93
|
+
└── index.ts # Library exports
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Multi-Profile Configuration
|
|
97
|
+
|
|
98
|
+
Profiles are stored in `~/.connect/{connector-name}/profiles/`:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
~/.connect/connector/
|
|
102
|
+
├── current_profile # Name of active profile
|
|
103
|
+
└── profiles/
|
|
104
|
+
├── default.json # Default profile
|
|
105
|
+
├── work.json # Named profile
|
|
106
|
+
└── personal.json # Named profile
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Profile Commands
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Create profiles
|
|
113
|
+
connector profile create work --api-key sk-xxx --use
|
|
114
|
+
connector profile create personal --api-key sk-yyy
|
|
115
|
+
|
|
116
|
+
# Switch profiles
|
|
117
|
+
connector profile use work
|
|
118
|
+
|
|
119
|
+
# Use profile for single command
|
|
120
|
+
connector -p personal example list
|
|
121
|
+
|
|
122
|
+
# List profiles
|
|
123
|
+
connector profile list
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Customizing Authentication
|
|
127
|
+
|
|
128
|
+
Edit `src/api/client.ts` to change authentication:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Bearer token (default)
|
|
132
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
133
|
+
|
|
134
|
+
// API Key header
|
|
135
|
+
'X-API-Key': this.apiKey,
|
|
136
|
+
|
|
137
|
+
// Basic auth
|
|
138
|
+
'Authorization': `Basic ${Buffer.from(`${this.apiKey}:${this.apiSecret}`).toString('base64')}`,
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Adding API Endpoints
|
|
142
|
+
|
|
143
|
+
1. Create a new file in `src/api/` (e.g., `users.ts`)
|
|
144
|
+
2. Export it from `src/api/index.ts`
|
|
145
|
+
3. Add types in `src/types/index.ts`
|
|
146
|
+
4. Add CLI commands in `src/cli/index.ts`
|
|
147
|
+
|
|
148
|
+
Example API module:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// src/api/users.ts
|
|
152
|
+
import type { ConnectorClient } from './client';
|
|
153
|
+
|
|
154
|
+
export class UsersApi {
|
|
155
|
+
constructor(private readonly client: ConnectorClient) {}
|
|
156
|
+
|
|
157
|
+
async list(options?: { limit?: number }) {
|
|
158
|
+
return this.client.get('/users', { limit: options?.limit });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async get(id: string) {
|
|
162
|
+
return this.client.get(`/users/${id}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Environment Variables
|
|
168
|
+
|
|
169
|
+
| Variable | Description |
|
|
170
|
+
|----------|-------------|
|
|
171
|
+
| `CONNECTOR_API_KEY` | API key (overrides profile config) |
|
|
172
|
+
| `CONNECTOR_API_SECRET` | API secret (optional) |
|
|
173
|
+
| `CONNECTOR_BASE_URL` | Override base URL (optional) |
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Install dependencies
|
|
179
|
+
bun install
|
|
180
|
+
|
|
181
|
+
# Run CLI in development
|
|
182
|
+
bun run dev
|
|
183
|
+
|
|
184
|
+
# Build for distribution
|
|
185
|
+
bun run build
|
|
186
|
+
|
|
187
|
+
# Type check
|
|
188
|
+
bun run typecheck
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hasna/connect-datadog",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Datadog connector - Manage metrics, monitors, dashboards, logs, and more",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"connect-datadog": "./bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/cli/index.ts --outdir ./bin --target bun",
|
|
19
|
+
"dev": "bun run ./src/cli/index.ts",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"prepublishOnly": "bun run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"datadog",
|
|
25
|
+
"monitoring",
|
|
26
|
+
"metrics",
|
|
27
|
+
"logs",
|
|
28
|
+
"apm",
|
|
29
|
+
"observability",
|
|
30
|
+
"dashboards",
|
|
31
|
+
"connector",
|
|
32
|
+
"cli",
|
|
33
|
+
"typescript",
|
|
34
|
+
"bun"
|
|
35
|
+
],
|
|
36
|
+
"author": "Hasna",
|
|
37
|
+
"license": "Apache-2.0",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/bun": "latest",
|
|
40
|
+
"typescript": "^5"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"commander": "^12.1.0",
|
|
44
|
+
"chalk": "^5.3.0"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"bun": ">=1.0.0"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/hasna/open-connectors.git"
|
|
52
|
+
}
|
|
53
|
+
}
|