@hasna/microservices 0.0.4 → 0.0.6
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/bin/index.js +9 -1
- package/bin/mcp.js +9 -1
- package/dist/index.js +9 -1
- package/microservices/microservice-ads/src/cli/index.ts +198 -0
- package/microservices/microservice-ads/src/db/campaigns.ts +304 -0
- package/microservices/microservice-ads/src/mcp/index.ts +160 -0
- package/microservices/microservice-company/package.json +27 -0
- package/microservices/microservice-company/src/cli/index.ts +1126 -0
- package/microservices/microservice-company/src/db/company.ts +854 -0
- package/microservices/microservice-company/src/db/database.ts +93 -0
- package/microservices/microservice-company/src/db/migrations.ts +214 -0
- package/microservices/microservice-company/src/db/workflow-migrations.ts +44 -0
- package/microservices/microservice-company/src/index.ts +60 -0
- package/microservices/microservice-company/src/lib/audit.ts +168 -0
- package/microservices/microservice-company/src/lib/finance.ts +299 -0
- package/microservices/microservice-company/src/lib/settings.ts +85 -0
- package/microservices/microservice-company/src/lib/workflows.ts +698 -0
- package/microservices/microservice-company/src/mcp/index.ts +991 -0
- package/microservices/microservice-contracts/src/cli/index.ts +410 -23
- package/microservices/microservice-contracts/src/db/contracts.ts +430 -1
- package/microservices/microservice-contracts/src/db/migrations.ts +83 -0
- package/microservices/microservice-contracts/src/mcp/index.ts +312 -3
- package/microservices/microservice-domains/src/cli/index.ts +673 -0
- package/microservices/microservice-domains/src/db/domains.ts +613 -0
- package/microservices/microservice-domains/src/index.ts +21 -0
- package/microservices/microservice-domains/src/lib/brandsight.ts +285 -0
- package/microservices/microservice-domains/src/lib/godaddy.ts +328 -0
- package/microservices/microservice-domains/src/lib/namecheap.ts +474 -0
- package/microservices/microservice-domains/src/lib/registrar.ts +355 -0
- package/microservices/microservice-domains/src/mcp/index.ts +413 -0
- package/microservices/microservice-hiring/src/cli/index.ts +318 -8
- package/microservices/microservice-hiring/src/db/hiring.ts +503 -0
- package/microservices/microservice-hiring/src/db/migrations.ts +21 -0
- package/microservices/microservice-hiring/src/index.ts +29 -0
- package/microservices/microservice-hiring/src/lib/scoring.ts +206 -0
- package/microservices/microservice-hiring/src/mcp/index.ts +245 -0
- package/microservices/microservice-payments/src/cli/index.ts +255 -3
- package/microservices/microservice-payments/src/db/migrations.ts +18 -0
- package/microservices/microservice-payments/src/db/payments.ts +552 -0
- package/microservices/microservice-payments/src/mcp/index.ts +223 -0
- package/microservices/microservice-payroll/src/cli/index.ts +269 -0
- package/microservices/microservice-payroll/src/db/migrations.ts +26 -0
- package/microservices/microservice-payroll/src/db/payroll.ts +636 -0
- package/microservices/microservice-payroll/src/mcp/index.ts +246 -0
- package/microservices/microservice-shipping/src/cli/index.ts +211 -3
- package/microservices/microservice-shipping/src/db/migrations.ts +8 -0
- package/microservices/microservice-shipping/src/db/shipping.ts +453 -3
- package/microservices/microservice-shipping/src/mcp/index.ts +149 -1
- package/microservices/microservice-social/src/cli/index.ts +244 -2
- package/microservices/microservice-social/src/db/migrations.ts +33 -0
- package/microservices/microservice-social/src/db/social.ts +378 -4
- package/microservices/microservice-social/src/mcp/index.ts +221 -1
- package/microservices/microservice-subscriptions/src/cli/index.ts +315 -0
- package/microservices/microservice-subscriptions/src/db/migrations.ts +68 -0
- package/microservices/microservice-subscriptions/src/db/subscriptions.ts +567 -3
- package/microservices/microservice-subscriptions/src/mcp/index.ts +267 -1
- package/package.json +1 -1
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified registrar provider system
|
|
3
|
+
*
|
|
4
|
+
* Wraps Namecheap, GoDaddy, and Brandsight into a common RegistrarProvider interface.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Domain, CreateDomainInput, UpdateDomainInput } from "../db/domains.js";
|
|
8
|
+
import * as namecheap from "./namecheap.js";
|
|
9
|
+
import * as godaddy from "./godaddy.js";
|
|
10
|
+
|
|
11
|
+
// ============================================================
|
|
12
|
+
// Types
|
|
13
|
+
// ============================================================
|
|
14
|
+
|
|
15
|
+
export interface ProviderDnsRecord {
|
|
16
|
+
type: string;
|
|
17
|
+
name: string;
|
|
18
|
+
value: string;
|
|
19
|
+
ttl: number;
|
|
20
|
+
priority?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ProviderDomainInfo {
|
|
24
|
+
domain: string;
|
|
25
|
+
registrar: string;
|
|
26
|
+
created: string;
|
|
27
|
+
expires: string;
|
|
28
|
+
nameservers: string[];
|
|
29
|
+
status: string;
|
|
30
|
+
auto_renew: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ProviderRenewResult {
|
|
34
|
+
domain: string;
|
|
35
|
+
success: boolean;
|
|
36
|
+
orderId?: string;
|
|
37
|
+
chargedAmount?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ProviderSyncResult {
|
|
41
|
+
synced: number;
|
|
42
|
+
created: number;
|
|
43
|
+
updated: number;
|
|
44
|
+
errors: string[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ProviderAvailability {
|
|
48
|
+
domain: string;
|
|
49
|
+
available: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type DbFunctions = {
|
|
53
|
+
getDomainByName: (name: string) => Domain | null;
|
|
54
|
+
createDomain: (input: CreateDomainInput) => Domain;
|
|
55
|
+
updateDomain: (id: string, input: UpdateDomainInput) => Domain | null;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export interface RegistrarProvider {
|
|
59
|
+
name: string;
|
|
60
|
+
listDomains(): Promise<ProviderDomainInfo[]>;
|
|
61
|
+
getDomainInfo(domain: string): Promise<ProviderDomainInfo>;
|
|
62
|
+
renewDomain(domain: string): Promise<ProviderRenewResult>;
|
|
63
|
+
getDnsRecords(domain: string): Promise<ProviderDnsRecord[]>;
|
|
64
|
+
setDnsRecords(domain: string, records: ProviderDnsRecord[]): Promise<boolean>;
|
|
65
|
+
checkAvailability(domain: string): Promise<ProviderAvailability>;
|
|
66
|
+
syncToLocalDb(dbFns: DbFunctions): Promise<ProviderSyncResult>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ProviderInfo {
|
|
70
|
+
name: string;
|
|
71
|
+
configured: boolean;
|
|
72
|
+
envVars: string[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface SyncAllResult {
|
|
76
|
+
providers: { name: string; result: ProviderSyncResult }[];
|
|
77
|
+
totalSynced: number;
|
|
78
|
+
totalErrors: string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ============================================================
|
|
82
|
+
// Namecheap Provider Adapter
|
|
83
|
+
// ============================================================
|
|
84
|
+
|
|
85
|
+
function createNamecheapProvider(): RegistrarProvider {
|
|
86
|
+
return {
|
|
87
|
+
name: "namecheap",
|
|
88
|
+
|
|
89
|
+
async listDomains(): Promise<ProviderDomainInfo[]> {
|
|
90
|
+
const config = namecheap.getConfig();
|
|
91
|
+
const domains = await namecheap.listNamecheapDomains(config);
|
|
92
|
+
return domains.map((d) => ({
|
|
93
|
+
domain: d.domain,
|
|
94
|
+
registrar: "Namecheap",
|
|
95
|
+
created: "",
|
|
96
|
+
expires: d.expiry,
|
|
97
|
+
nameservers: [],
|
|
98
|
+
status: "active",
|
|
99
|
+
auto_renew: d.autoRenew,
|
|
100
|
+
}));
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
async getDomainInfo(domain: string): Promise<ProviderDomainInfo> {
|
|
104
|
+
const config = namecheap.getConfig();
|
|
105
|
+
const info = await namecheap.getDomainInfo(domain, config);
|
|
106
|
+
return {
|
|
107
|
+
domain: info.domain,
|
|
108
|
+
registrar: info.registrar,
|
|
109
|
+
created: info.created,
|
|
110
|
+
expires: info.expires,
|
|
111
|
+
nameservers: info.nameservers,
|
|
112
|
+
status: "active",
|
|
113
|
+
auto_renew: true,
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
async renewDomain(domain: string): Promise<ProviderRenewResult> {
|
|
118
|
+
const config = namecheap.getConfig();
|
|
119
|
+
const result = await namecheap.renewDomain(domain, 1, config);
|
|
120
|
+
return {
|
|
121
|
+
domain: result.domain,
|
|
122
|
+
success: result.success,
|
|
123
|
+
orderId: result.orderId,
|
|
124
|
+
chargedAmount: result.chargedAmount,
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
async getDnsRecords(domain: string): Promise<ProviderDnsRecord[]> {
|
|
129
|
+
const config = namecheap.getConfig();
|
|
130
|
+
const { sld, tld } = namecheap.splitDomain(domain);
|
|
131
|
+
const records = await namecheap.getDnsRecords(domain, sld, tld, config);
|
|
132
|
+
return records.map((r) => ({
|
|
133
|
+
type: r.type,
|
|
134
|
+
name: r.name,
|
|
135
|
+
value: r.address,
|
|
136
|
+
ttl: r.ttl,
|
|
137
|
+
priority: r.mxPref,
|
|
138
|
+
}));
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
async setDnsRecords(domain: string, records: ProviderDnsRecord[]): Promise<boolean> {
|
|
142
|
+
const config = namecheap.getConfig();
|
|
143
|
+
const { sld, tld } = namecheap.splitDomain(domain);
|
|
144
|
+
const ncRecords = records.map((r) => ({
|
|
145
|
+
type: r.type,
|
|
146
|
+
name: r.name,
|
|
147
|
+
address: r.value,
|
|
148
|
+
ttl: r.ttl,
|
|
149
|
+
mxPref: r.priority,
|
|
150
|
+
}));
|
|
151
|
+
return namecheap.setDnsRecords(domain, sld, tld, ncRecords, config);
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
async checkAvailability(domain: string): Promise<ProviderAvailability> {
|
|
155
|
+
const config = namecheap.getConfig();
|
|
156
|
+
const result = await namecheap.checkAvailability(domain, config);
|
|
157
|
+
return { domain: result.domain, available: result.available };
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
async syncToLocalDb(dbFns: DbFunctions): Promise<ProviderSyncResult> {
|
|
161
|
+
const result = await namecheap.syncToLocalDb(dbFns);
|
|
162
|
+
return {
|
|
163
|
+
synced: result.synced,
|
|
164
|
+
created: 0,
|
|
165
|
+
updated: 0,
|
|
166
|
+
errors: result.errors,
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ============================================================
|
|
173
|
+
// GoDaddy Provider Adapter
|
|
174
|
+
// ============================================================
|
|
175
|
+
|
|
176
|
+
function createGoDaddyProvider(): RegistrarProvider {
|
|
177
|
+
return {
|
|
178
|
+
name: "godaddy",
|
|
179
|
+
|
|
180
|
+
async listDomains(): Promise<ProviderDomainInfo[]> {
|
|
181
|
+
const domains = await godaddy.listGoDaddyDomains();
|
|
182
|
+
return domains.map((d) => ({
|
|
183
|
+
domain: d.domain,
|
|
184
|
+
registrar: "GoDaddy",
|
|
185
|
+
created: "",
|
|
186
|
+
expires: d.expires,
|
|
187
|
+
nameservers: d.nameServers || [],
|
|
188
|
+
status: d.status.toLowerCase(),
|
|
189
|
+
auto_renew: d.renewAuto,
|
|
190
|
+
}));
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
async getDomainInfo(domain: string): Promise<ProviderDomainInfo> {
|
|
194
|
+
const detail = await godaddy.getDomainInfo(domain);
|
|
195
|
+
return {
|
|
196
|
+
domain: detail.domain,
|
|
197
|
+
registrar: "GoDaddy",
|
|
198
|
+
created: detail.createdAt || "",
|
|
199
|
+
expires: detail.expires,
|
|
200
|
+
nameservers: detail.nameServers || [],
|
|
201
|
+
status: detail.status.toLowerCase(),
|
|
202
|
+
auto_renew: detail.renewAuto,
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
async renewDomain(domain: string): Promise<ProviderRenewResult> {
|
|
207
|
+
const result = await godaddy.renewDomain(domain);
|
|
208
|
+
return {
|
|
209
|
+
domain,
|
|
210
|
+
success: true,
|
|
211
|
+
orderId: String(result.orderId),
|
|
212
|
+
chargedAmount: String(result.total),
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
async getDnsRecords(domain: string): Promise<ProviderDnsRecord[]> {
|
|
217
|
+
const records = await godaddy.getDnsRecords(domain);
|
|
218
|
+
return records.map((r) => ({
|
|
219
|
+
type: r.type,
|
|
220
|
+
name: r.name,
|
|
221
|
+
value: r.data,
|
|
222
|
+
ttl: r.ttl,
|
|
223
|
+
priority: r.priority,
|
|
224
|
+
}));
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
async setDnsRecords(domain: string, records: ProviderDnsRecord[]): Promise<boolean> {
|
|
228
|
+
const gdRecords = records.map((r) => ({
|
|
229
|
+
type: r.type,
|
|
230
|
+
name: r.name,
|
|
231
|
+
data: r.value,
|
|
232
|
+
ttl: r.ttl,
|
|
233
|
+
priority: r.priority,
|
|
234
|
+
}));
|
|
235
|
+
await godaddy.setDnsRecords(domain, gdRecords);
|
|
236
|
+
return true;
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
async checkAvailability(domain: string): Promise<ProviderAvailability> {
|
|
240
|
+
const result = await godaddy.checkAvailability(domain);
|
|
241
|
+
return { domain: result.domain, available: result.available };
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
async syncToLocalDb(dbFns: DbFunctions): Promise<ProviderSyncResult> {
|
|
245
|
+
const result = await godaddy.syncToLocalDb(dbFns);
|
|
246
|
+
return {
|
|
247
|
+
synced: result.synced,
|
|
248
|
+
created: result.created,
|
|
249
|
+
updated: result.updated,
|
|
250
|
+
errors: result.errors,
|
|
251
|
+
};
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ============================================================
|
|
257
|
+
// Provider Factory
|
|
258
|
+
// ============================================================
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Get a unified RegistrarProvider by name.
|
|
262
|
+
*/
|
|
263
|
+
export function getProvider(name: "namecheap" | "godaddy"): RegistrarProvider {
|
|
264
|
+
switch (name) {
|
|
265
|
+
case "namecheap":
|
|
266
|
+
return createNamecheapProvider();
|
|
267
|
+
case "godaddy":
|
|
268
|
+
return createGoDaddyProvider();
|
|
269
|
+
default:
|
|
270
|
+
throw new Error(`Unknown registrar provider: ${name}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Check which providers have their API keys configured.
|
|
276
|
+
*/
|
|
277
|
+
export function getAvailableProviders(): ProviderInfo[] {
|
|
278
|
+
const providers: ProviderInfo[] = [
|
|
279
|
+
{
|
|
280
|
+
name: "namecheap",
|
|
281
|
+
configured: !!(
|
|
282
|
+
process.env["NAMECHEAP_API_KEY"] &&
|
|
283
|
+
process.env["NAMECHEAP_USERNAME"] &&
|
|
284
|
+
process.env["NAMECHEAP_CLIENT_IP"]
|
|
285
|
+
),
|
|
286
|
+
envVars: ["NAMECHEAP_API_KEY", "NAMECHEAP_USERNAME", "NAMECHEAP_CLIENT_IP"],
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "godaddy",
|
|
290
|
+
configured: !!(
|
|
291
|
+
process.env["GODADDY_API_KEY"] &&
|
|
292
|
+
process.env["GODADDY_API_SECRET"]
|
|
293
|
+
),
|
|
294
|
+
envVars: ["GODADDY_API_KEY", "GODADDY_API_SECRET"],
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
name: "brandsight",
|
|
298
|
+
configured: !!process.env["BRANDSIGHT_API_KEY"],
|
|
299
|
+
envVars: ["BRANDSIGHT_API_KEY"],
|
|
300
|
+
},
|
|
301
|
+
];
|
|
302
|
+
|
|
303
|
+
return providers;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Sync domains from ALL configured registrar providers sequentially.
|
|
308
|
+
*/
|
|
309
|
+
export async function syncAll(dbFns: DbFunctions): Promise<SyncAllResult> {
|
|
310
|
+
const available = getAvailableProviders().filter(
|
|
311
|
+
(p) => p.configured && (p.name === "namecheap" || p.name === "godaddy")
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
const result: SyncAllResult = {
|
|
315
|
+
providers: [],
|
|
316
|
+
totalSynced: 0,
|
|
317
|
+
totalErrors: [],
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
for (const info of available) {
|
|
321
|
+
try {
|
|
322
|
+
const provider = getProvider(info.name as "namecheap" | "godaddy");
|
|
323
|
+
const syncResult = await provider.syncToLocalDb(dbFns);
|
|
324
|
+
result.providers.push({ name: info.name, result: syncResult });
|
|
325
|
+
result.totalSynced += syncResult.synced;
|
|
326
|
+
result.totalErrors.push(...syncResult.errors.map((e) => `[${info.name}] ${e}`));
|
|
327
|
+
} catch (error) {
|
|
328
|
+
const msg = `[${info.name}] Sync failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
329
|
+
result.totalErrors.push(msg);
|
|
330
|
+
result.providers.push({
|
|
331
|
+
name: info.name,
|
|
332
|
+
result: { synced: 0, created: 0, updated: 0, errors: [msg] },
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return result;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Auto-detect which registrar provider a domain uses based on its DB record.
|
|
342
|
+
* Returns the provider name or null if not determinable.
|
|
343
|
+
*/
|
|
344
|
+
export function autoDetectRegistrar(
|
|
345
|
+
domain: string,
|
|
346
|
+
getDomainByName: (name: string) => Domain | null
|
|
347
|
+
): "namecheap" | "godaddy" | null {
|
|
348
|
+
const dbDomain = getDomainByName(domain);
|
|
349
|
+
if (!dbDomain || !dbDomain.registrar) return null;
|
|
350
|
+
|
|
351
|
+
const registrar = dbDomain.registrar.toLowerCase();
|
|
352
|
+
if (registrar.includes("namecheap")) return "namecheap";
|
|
353
|
+
if (registrar.includes("godaddy")) return "godaddy";
|
|
354
|
+
return null;
|
|
355
|
+
}
|