twenty-import-csv 1.0.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/.env.example +16 -0
- package/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/browser-automation.d.ts +24 -0
- package/dist/browser-automation.d.ts.map +1 -0
- package/dist/browser-automation.js +295 -0
- package/dist/browser-automation.js.map +1 -0
- package/dist/cli-browser.d.ts +3 -0
- package/dist/cli-browser.d.ts.map +1 -0
- package/dist/cli-browser.js +134 -0
- package/dist/cli-browser.js.map +1 -0
- package/dist/cli-fixed.d.ts +3 -0
- package/dist/cli-fixed.d.ts.map +1 -0
- package/dist/cli-fixed.js +112 -0
- package/dist/cli-fixed.js.map +1 -0
- package/dist/cli-simple.d.ts +3 -0
- package/dist/cli-simple.d.ts.map +1 -0
- package/dist/cli-simple.js +167 -0
- package/dist/cli-simple.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +167 -0
- package/dist/cli.js.map +1 -0
- package/dist/load-graphql.d.ts +23 -0
- package/dist/load-graphql.d.ts.map +1 -0
- package/dist/load-graphql.js +239 -0
- package/dist/load-graphql.js.map +1 -0
- package/dist/load-old.d.ts +24 -0
- package/dist/load-old.d.ts.map +1 -0
- package/dist/load-old.js +183 -0
- package/dist/load-old.js.map +1 -0
- package/dist/load-real.d.ts +23 -0
- package/dist/load-real.d.ts.map +1 -0
- package/dist/load-real.js +202 -0
- package/dist/load-real.js.map +1 -0
- package/dist/load.d.ts +24 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +195 -0
- package/dist/load.js.map +1 -0
- package/dist/mapper.d.ts +16 -0
- package/dist/mapper.d.ts.map +1 -0
- package/dist/mapper.js +181 -0
- package/dist/mapper.js.map +1 -0
- package/dist/parser-broken.d.ts +11 -0
- package/dist/parser-broken.d.ts.map +1 -0
- package/dist/parser-broken.js +88 -0
- package/dist/parser-broken.js.map +1 -0
- package/dist/parser-old.d.ts +11 -0
- package/dist/parser-old.d.ts.map +1 -0
- package/dist/parser-old.js +90 -0
- package/dist/parser-old.js.map +1 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +83 -0
- package/dist/parser.js.map +1 -0
- package/dist/reporter.d.ts +15 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +144 -0
- package/dist/reporter.js.map +1 -0
- package/examples/contacts-mapping.txt +8 -0
- package/examples/contacts.csv +6 -0
- package/package.json +50 -0
- package/src/browser-automation.ts +350 -0
- package/src/cli-browser.ts +134 -0
- package/src/cli-simple.ts +158 -0
- package/src/cli.ts +159 -0
- package/src/load-graphql.ts +238 -0
- package/src/load-old.ts +177 -0
- package/src/load-real.ts +199 -0
- package/src/load.ts +197 -0
- package/src/mapper.ts +183 -0
- package/src/parser.ts +55 -0
- package/src/reporter.ts +131 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.TwentyRealAPIClient = void 0;
|
|
40
|
+
exports.loadToTwenty = loadToTwenty;
|
|
41
|
+
exports.saveErrorLog = saveErrorLog;
|
|
42
|
+
const axios_1 = __importDefault(require("axios"));
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
class TwentyRealAPIClient {
|
|
45
|
+
constructor(baseUrl, apiKey) {
|
|
46
|
+
this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
47
|
+
this.apiKey = apiKey;
|
|
48
|
+
this.client = axios_1.default.create({
|
|
49
|
+
baseURL: `${this.baseUrl}`,
|
|
50
|
+
headers: {
|
|
51
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
52
|
+
'Content-Type': 'application/json'
|
|
53
|
+
},
|
|
54
|
+
timeout: 30000
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async testConnection() {
|
|
58
|
+
try {
|
|
59
|
+
// ŠŃовеŃŃŠµŠ¼ health endpoint
|
|
60
|
+
const response = await this.client.get('/api/ping');
|
|
61
|
+
return response.status === 200;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('ā Connection test failed:', error.response?.data || error.message);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async createRecords(objectType, records) {
|
|
69
|
+
try {
|
|
70
|
+
// ŠŃŠ¾Š±ŃŠµŠ¼ ŃŠ°Š·Š½Ńе ŃŠµŠ°Š»ŃŠ½ŃŠµ endpoints Twenty CRM
|
|
71
|
+
const endpoints = [
|
|
72
|
+
`/api/${objectType}`,
|
|
73
|
+
`/api/v1/${objectType}`,
|
|
74
|
+
`/api/rest/${objectType}`,
|
|
75
|
+
`/v1/${objectType}`,
|
|
76
|
+
`/${objectType}`
|
|
77
|
+
];
|
|
78
|
+
for (const endpoint of endpoints) {
|
|
79
|
+
try {
|
|
80
|
+
console.log(`š ŠŃŠ¾Š±ŃŠµŠ¼ endpoint: ${endpoint}`);
|
|
81
|
+
// Š¤Š¾ŃŠ¼Š°Ń payload Š“Š»Ń Twenty CRM
|
|
82
|
+
const payload = records.map(record => {
|
|
83
|
+
const transformed = {};
|
|
84
|
+
if (objectType === 'people') {
|
|
85
|
+
// ŠŃŠ¾Š±ŃŠµŠ¼ ŃŠ°Š·Š½Ńе ŃŠ¾ŃмаŃŃ name
|
|
86
|
+
if (record['name.firstName'] || record['name.lastName']) {
|
|
87
|
+
transformed.name = {
|
|
88
|
+
firstName: record['name.firstName'] || '',
|
|
89
|
+
lastName: record['name.lastName'] || ''
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (record.email)
|
|
93
|
+
transformed.email = record.email;
|
|
94
|
+
if (record.phone)
|
|
95
|
+
transformed.phone = record.phone;
|
|
96
|
+
if (record.jobTitle)
|
|
97
|
+
transformed.jobTitle = record.jobTitle;
|
|
98
|
+
if (record.city)
|
|
99
|
+
transformed.city = record.city;
|
|
100
|
+
if (record.country)
|
|
101
|
+
transformed.country = record.country;
|
|
102
|
+
}
|
|
103
|
+
return transformed;
|
|
104
|
+
});
|
|
105
|
+
const response = await this.client.post(endpoint, payload);
|
|
106
|
+
console.log(`ā
Endpoint ${endpoint} ŃŠ°Š±Š¾ŃаеŃ!`);
|
|
107
|
+
return {
|
|
108
|
+
success: true,
|
|
109
|
+
count: records.length
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.log(`ā Endpoint ${endpoint} не ŃŠ°Š±Š¾ŃаеŃ:`, error.response?.status);
|
|
114
|
+
if (error.response?.status !== 404) {
|
|
115
|
+
// ŠŃли ŃŃŠ¾ не 404, ŠæŃŠ¾Š±Ńем ŃŠ»ŠµŠ“ŃŃŃŠøŠ¹ endpoint
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw new Error(`ŠŠµ найГен ŃŠ°Š±Š¾Ńий endpoint Š“Š»Ń ${objectType}`);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
return {
|
|
124
|
+
success: false,
|
|
125
|
+
count: 0,
|
|
126
|
+
error: error.response?.data?.message || error.message
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
getObjectEndpoint(objectType) {
|
|
131
|
+
const endpoints = {
|
|
132
|
+
'people': 'people',
|
|
133
|
+
'persons': 'people',
|
|
134
|
+
'contacts': 'people',
|
|
135
|
+
'companies': 'companies',
|
|
136
|
+
'organization': 'companies',
|
|
137
|
+
'opportunities': 'opportunities',
|
|
138
|
+
'deals': 'opportunities',
|
|
139
|
+
'tasks': 'tasks',
|
|
140
|
+
'notes': 'notes'
|
|
141
|
+
};
|
|
142
|
+
return endpoints[objectType.toLowerCase()] || objectType;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.TwentyRealAPIClient = TwentyRealAPIClient;
|
|
146
|
+
async function loadToTwenty(data, objectType, twentyUrl, twentyKey, batchSize, progressBar) {
|
|
147
|
+
const client = new TwentyRealAPIClient(twentyUrl, twentyKey);
|
|
148
|
+
const errorLog = [];
|
|
149
|
+
let successCount = 0;
|
|
150
|
+
let errorCount = 0;
|
|
151
|
+
// Test connection first
|
|
152
|
+
console.log('š Testing Twenty CRM connection...');
|
|
153
|
+
const isConnected = await client.testConnection();
|
|
154
|
+
if (!isConnected) {
|
|
155
|
+
throw new Error('Failed to connect to Twenty CRM. Check URL and API key.');
|
|
156
|
+
}
|
|
157
|
+
console.log('ā
Connection successful');
|
|
158
|
+
console.log(`š¤ Loading ${data.length} records to Twenty CRM...`);
|
|
159
|
+
// Process in batches
|
|
160
|
+
for (let i = 0; i < data.length; i += batchSize) {
|
|
161
|
+
const batch = data.slice(i, i + batchSize);
|
|
162
|
+
const batchNumber = Math.floor(i / batchSize) + 1;
|
|
163
|
+
const totalBatches = Math.ceil(data.length / batchSize);
|
|
164
|
+
try {
|
|
165
|
+
progressBar.update((i / data.length) * 100, {
|
|
166
|
+
batch: `${batchNumber}/${totalBatches}`,
|
|
167
|
+
records: `${i + 1}-${Math.min(i + batchSize, data.length)}`
|
|
168
|
+
});
|
|
169
|
+
const batchResult = await client.createRecords(objectType, batch);
|
|
170
|
+
if (batchResult.success) {
|
|
171
|
+
successCount += batchResult.count;
|
|
172
|
+
console.log(`ā
Batch ${batchNumber} imported successfully`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
errorCount += batch.length;
|
|
176
|
+
const errorMsg = `Batch ${batchNumber}: ${batchResult.error}`;
|
|
177
|
+
errorLog.push(errorMsg);
|
|
178
|
+
console.error(`ā ${errorMsg}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
const errorMsg = `Batch ${batchNumber}: ${error.message}`;
|
|
183
|
+
errorLog.push(errorMsg);
|
|
184
|
+
errorCount += batch.length;
|
|
185
|
+
}
|
|
186
|
+
// Small delay to avoid rate limiting
|
|
187
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
success: successCount,
|
|
191
|
+
errors: errorCount,
|
|
192
|
+
errorLog
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function saveErrorLog(errorLog, filename) {
|
|
196
|
+
if (errorLog.length === 0)
|
|
197
|
+
return;
|
|
198
|
+
const logContent = errorLog.join('\n');
|
|
199
|
+
fs.writeFileSync(filename, logContent, 'utf8');
|
|
200
|
+
console.log(`š Error log saved to ${filename}`);
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=load-real.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-real.js","sourceRoot":"","sources":["../src/load-real.ts"],"names":[],"mappings":"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"}
|
package/dist/load.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ParsedRecord } from './parser';
|
|
2
|
+
export interface LoadResult {
|
|
3
|
+
success: number;
|
|
4
|
+
errors: number;
|
|
5
|
+
errorLog: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface BatchResult {
|
|
8
|
+
success: boolean;
|
|
9
|
+
count: number;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class TwentyAPIClient {
|
|
13
|
+
private client;
|
|
14
|
+
private baseUrl;
|
|
15
|
+
private apiKey;
|
|
16
|
+
constructor(baseUrl: string, apiKey: string);
|
|
17
|
+
testConnection(): Promise<boolean>;
|
|
18
|
+
createRecords(objectType: string, records: ParsedRecord[]): Promise<BatchResult>;
|
|
19
|
+
createRecord(objectType: string, record: ParsedRecord): Promise<BatchResult>;
|
|
20
|
+
getObjectEndpoint(objectType: string): string;
|
|
21
|
+
}
|
|
22
|
+
export declare function loadToTwenty(data: ParsedRecord[], objectType: string, twentyUrl: string, twentyKey: string, batchSize: number, progressBar: any): Promise<LoadResult>;
|
|
23
|
+
export declare function saveErrorLog(errorLog: string[], filename: string): void;
|
|
24
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAcrC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAUlC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAmChF,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBlF,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;CAe9C;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,YAAY,EAAE,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,GAAG,GACf,OAAO,CAAC,UAAU,CAAC,CAgErB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMvE"}
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.TwentyAPIClient = void 0;
|
|
40
|
+
exports.loadToTwenty = loadToTwenty;
|
|
41
|
+
exports.saveErrorLog = saveErrorLog;
|
|
42
|
+
const axios_1 = __importDefault(require("axios"));
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
class TwentyAPIClient {
|
|
45
|
+
constructor(baseUrl, apiKey) {
|
|
46
|
+
this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
47
|
+
this.apiKey = apiKey;
|
|
48
|
+
this.client = axios_1.default.create({
|
|
49
|
+
baseURL: `${this.baseUrl}/rest`,
|
|
50
|
+
headers: {
|
|
51
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
52
|
+
'Content-Type': 'application/json'
|
|
53
|
+
},
|
|
54
|
+
timeout: 30000
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async testConnection() {
|
|
58
|
+
try {
|
|
59
|
+
const response = await this.client.get('/people', { params: { limit: 1 } });
|
|
60
|
+
return response.status === 200;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error('ā Connection test failed:', error.response?.data || error.message);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async createRecords(objectType, records) {
|
|
68
|
+
try {
|
|
69
|
+
// Try different payload formats
|
|
70
|
+
let payload;
|
|
71
|
+
// Format 1: { data: records }
|
|
72
|
+
payload = { data: records };
|
|
73
|
+
// Format 2: records directly
|
|
74
|
+
// payload = records;
|
|
75
|
+
// Format 3: { records: records }
|
|
76
|
+
// payload = { records: records };
|
|
77
|
+
console.log('š Debug - Payload format:', JSON.stringify(payload, null, 2));
|
|
78
|
+
console.log('š Debug - Payload length:', JSON.stringify(payload).length);
|
|
79
|
+
const response = await this.client.post(`/${objectType}`, payload);
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
count: records.length
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('š Debug - Error response:', error.response?.data);
|
|
87
|
+
console.error('š Debug - Error status:', error.response?.status);
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
count: 0,
|
|
91
|
+
error: error.response?.data?.message || error.message
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async createRecord(objectType, record) {
|
|
96
|
+
try {
|
|
97
|
+
console.log('š Debug - Single record:', JSON.stringify(record, null, 2));
|
|
98
|
+
const response = await this.client.post(`/${objectType}`, record);
|
|
99
|
+
return {
|
|
100
|
+
success: true,
|
|
101
|
+
count: 1
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
console.error('š Debug - Single record error:', error.response?.data);
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
count: 0,
|
|
109
|
+
error: error.response?.data?.message || error.message
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
getObjectEndpoint(objectType) {
|
|
114
|
+
const endpoints = {
|
|
115
|
+
'people': 'people',
|
|
116
|
+
'persons': 'people',
|
|
117
|
+
'contacts': 'people',
|
|
118
|
+
'companies': 'companies',
|
|
119
|
+
'organization': 'companies',
|
|
120
|
+
'opportunities': 'opportunities',
|
|
121
|
+
'deals': 'opportunities',
|
|
122
|
+
'tasks': 'tasks',
|
|
123
|
+
'notes': 'notes'
|
|
124
|
+
};
|
|
125
|
+
return endpoints[objectType.toLowerCase()] || objectType;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.TwentyAPIClient = TwentyAPIClient;
|
|
129
|
+
async function loadToTwenty(data, objectType, twentyUrl, twentyKey, batchSize, progressBar) {
|
|
130
|
+
const client = new TwentyAPIClient(twentyUrl, twentyKey);
|
|
131
|
+
const errorLog = [];
|
|
132
|
+
let successCount = 0;
|
|
133
|
+
let errorCount = 0;
|
|
134
|
+
// Test connection first
|
|
135
|
+
console.log('š Testing Twenty CRM connection...');
|
|
136
|
+
const isConnected = await client.testConnection();
|
|
137
|
+
if (!isConnected) {
|
|
138
|
+
throw new Error('Failed to connect to Twenty CRM. Check URL and API key.');
|
|
139
|
+
}
|
|
140
|
+
console.log('ā
Connection successful');
|
|
141
|
+
const endpoint = client.getObjectEndpoint(objectType);
|
|
142
|
+
console.log(`š¤ Loading ${data.length} records to ${endpoint}...`);
|
|
143
|
+
// Process in batches
|
|
144
|
+
for (let i = 0; i < data.length; i += batchSize) {
|
|
145
|
+
const batch = data.slice(i, i + batchSize);
|
|
146
|
+
const batchNumber = Math.floor(i / batchSize) + 1;
|
|
147
|
+
const totalBatches = Math.ceil(data.length / batchSize);
|
|
148
|
+
try {
|
|
149
|
+
progressBar.update((i / data.length) * 100, {
|
|
150
|
+
batch: `${batchNumber}/${totalBatches}`,
|
|
151
|
+
records: `${i + 1}-${Math.min(i + batchSize, data.length)}`
|
|
152
|
+
});
|
|
153
|
+
// Try batch create first
|
|
154
|
+
const batchResult = await client.createRecords(endpoint, batch);
|
|
155
|
+
if (batchResult.success) {
|
|
156
|
+
successCount += batchResult.count;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Fallback to individual records
|
|
160
|
+
console.warn(`ā ļø Batch create failed, trying individual records...`);
|
|
161
|
+
for (const record of batch) {
|
|
162
|
+
const result = await client.createRecord(endpoint, record);
|
|
163
|
+
if (result.success) {
|
|
164
|
+
successCount++;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
errorCount++;
|
|
168
|
+
const errorMsg = `Record ${JSON.stringify(record)}: ${result.error}`;
|
|
169
|
+
errorLog.push(errorMsg);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
const errorMsg = `Batch ${batchNumber}: ${error.message}`;
|
|
176
|
+
errorLog.push(errorMsg);
|
|
177
|
+
errorCount += batch.length;
|
|
178
|
+
}
|
|
179
|
+
// Small delay to avoid rate limiting
|
|
180
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
success: successCount,
|
|
184
|
+
errors: errorCount,
|
|
185
|
+
errorLog
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function saveErrorLog(errorLog, filename) {
|
|
189
|
+
if (errorLog.length === 0)
|
|
190
|
+
return;
|
|
191
|
+
const logContent = errorLog.join('\n');
|
|
192
|
+
fs.writeFileSync(filename, logContent, 'utf8');
|
|
193
|
+
console.log(`š Error log saved to ${filename}`);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=load.js.map
|
package/dist/load.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"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"}
|
package/dist/mapper.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ParsedRecord } from './parser';
|
|
2
|
+
export interface FieldMapping {
|
|
3
|
+
[csvField: string]: string;
|
|
4
|
+
}
|
|
5
|
+
export interface TwentyObjectFields {
|
|
6
|
+
people: string[];
|
|
7
|
+
companies: string[];
|
|
8
|
+
opportunities: string[];
|
|
9
|
+
tasks: string[];
|
|
10
|
+
notes: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function loadMapping(mappingFile: string): Promise<FieldMapping>;
|
|
13
|
+
export declare function mapFields(data: ParsedRecord[], objectType: string, mapping?: FieldMapping): Promise<ParsedRecord[]>;
|
|
14
|
+
export declare function interactiveMapping(data: ParsedRecord[], objectType: string): Promise<FieldMapping>;
|
|
15
|
+
export declare function saveMapping(mapping: FieldMapping, outputFile: string): void;
|
|
16
|
+
//# sourceMappingURL=mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../src/mapper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAyBD,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA6B5E;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,YAAY,EAAE,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC,CAwBzB;AA4CD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,YAAY,EAAE,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC,CA+BvB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAI3E"}
|
package/dist/mapper.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadMapping = loadMapping;
|
|
37
|
+
exports.mapFields = mapFields;
|
|
38
|
+
exports.interactiveMapping = interactiveMapping;
|
|
39
|
+
exports.saveMapping = saveMapping;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const readline = __importStar(require("readline"));
|
|
42
|
+
// Twenty CRM API field mappings
|
|
43
|
+
const TWENTY_FIELDS = {
|
|
44
|
+
people: [
|
|
45
|
+
'name.firstName', 'name.lastName', 'email', 'phone', 'jobTitle',
|
|
46
|
+
'city', 'country', 'linkedinUrl', 'avatarUrl', 'note'
|
|
47
|
+
],
|
|
48
|
+
companies: [
|
|
49
|
+
'name', 'domainName', 'employees', 'annualRevenue', 'industry',
|
|
50
|
+
'linkedinUrl', 'phone', 'address', 'city', 'country'
|
|
51
|
+
],
|
|
52
|
+
opportunities: [
|
|
53
|
+
'name', 'amount', 'currency', 'stage', 'probability',
|
|
54
|
+
'closeDate', 'description', 'companyId', 'personId'
|
|
55
|
+
],
|
|
56
|
+
tasks: [
|
|
57
|
+
'title', 'description', 'status', 'dueDate', 'assigneeId',
|
|
58
|
+
'companyId', 'personId', 'priority'
|
|
59
|
+
],
|
|
60
|
+
notes: [
|
|
61
|
+
'body', 'authorId', 'companyId', 'personId', 'opportunityId'
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
async function loadMapping(mappingFile) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const mapping = {};
|
|
67
|
+
if (!fs.existsSync(mappingFile)) {
|
|
68
|
+
reject(new Error(`Mapping file ${mappingFile} not found`));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const rl = readline.createInterface({
|
|
72
|
+
input: fs.createReadStream(mappingFile),
|
|
73
|
+
crlfDelay: Infinity
|
|
74
|
+
});
|
|
75
|
+
rl.on('line', (line) => {
|
|
76
|
+
const [csvField, twentyField] = line.split('=').map(s => s.trim());
|
|
77
|
+
if (csvField && twentyField) {
|
|
78
|
+
mapping[csvField] = twentyField;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
rl.on('close', () => {
|
|
82
|
+
resolve(mapping);
|
|
83
|
+
});
|
|
84
|
+
rl.on('error', (error) => {
|
|
85
|
+
reject(error);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function mapFields(data, objectType, mapping) {
|
|
90
|
+
const validFields = TWENTY_FIELDS[objectType];
|
|
91
|
+
if (!validFields) {
|
|
92
|
+
throw new Error(`Unknown object type: ${objectType}`);
|
|
93
|
+
}
|
|
94
|
+
return data.map(record => {
|
|
95
|
+
const mapped = {};
|
|
96
|
+
Object.keys(record).forEach(csvField => {
|
|
97
|
+
const twentyField = mapping ? mapping[csvField] : csvField;
|
|
98
|
+
// Auto-map common field names
|
|
99
|
+
const autoMappedField = autoMapField(csvField, objectType);
|
|
100
|
+
const finalField = twentyField || autoMappedField;
|
|
101
|
+
if (finalField && validFields.includes(finalField)) {
|
|
102
|
+
mapped[finalField] = record[csvField];
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return mapped;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function autoMapField(csvField, objectType) {
|
|
109
|
+
const field = csvField.toLowerCase();
|
|
110
|
+
const commonMappings = {
|
|
111
|
+
people: {
|
|
112
|
+
'first_name': 'name.firstName',
|
|
113
|
+
'last_name': 'name.lastName',
|
|
114
|
+
'firstname': 'name.firstName',
|
|
115
|
+
'lastname': 'name.lastName',
|
|
116
|
+
'full_name': 'name.firstName',
|
|
117
|
+
'email_address': 'email',
|
|
118
|
+
'phone_number': 'phone',
|
|
119
|
+
'job_title': 'jobTitle',
|
|
120
|
+
'company': 'company',
|
|
121
|
+
'linkedin': 'linkedinUrl',
|
|
122
|
+
'avatar': 'avatarUrl'
|
|
123
|
+
},
|
|
124
|
+
companies: {
|
|
125
|
+
'company_name': 'name',
|
|
126
|
+
'company': 'name',
|
|
127
|
+
'website': 'domainName',
|
|
128
|
+
'domain': 'domainName',
|
|
129
|
+
'employee_count': 'employees',
|
|
130
|
+
'revenue': 'annualRevenue',
|
|
131
|
+
'address_line': 'address',
|
|
132
|
+
'zip_code': 'zipCode'
|
|
133
|
+
},
|
|
134
|
+
opportunities: {
|
|
135
|
+
'deal_name': 'name',
|
|
136
|
+
'deal': 'name',
|
|
137
|
+
'amount': 'amount',
|
|
138
|
+
'value': 'amount',
|
|
139
|
+
'stage': 'stage',
|
|
140
|
+
'probability': 'probability',
|
|
141
|
+
'close_date': 'closeDate',
|
|
142
|
+
'description': 'description'
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
return commonMappings[objectType]?.[field] || null;
|
|
146
|
+
}
|
|
147
|
+
async function interactiveMapping(data, objectType) {
|
|
148
|
+
const mapping = {};
|
|
149
|
+
const validFields = TWENTY_FIELDS[objectType];
|
|
150
|
+
const detectedFields = Object.keys(data[0] || {});
|
|
151
|
+
console.log(`\nšŗ Interactive Field Mapping for ${objectType}`);
|
|
152
|
+
console.log(`š Available Twenty fields: ${validFields.join(', ')}`);
|
|
153
|
+
console.log(`š Detected CSV fields: ${detectedFields.join(', ')}\n`);
|
|
154
|
+
const rl = readline.createInterface({
|
|
155
|
+
input: process.stdin,
|
|
156
|
+
output: process.stdout
|
|
157
|
+
});
|
|
158
|
+
for (const csvField of detectedFields) {
|
|
159
|
+
const answer = await new Promise((resolve) => {
|
|
160
|
+
rl.question(`Map "${csvField}" -> (field name or skip): `, resolve);
|
|
161
|
+
});
|
|
162
|
+
if (answer && answer !== 'skip' && validFields.includes(answer)) {
|
|
163
|
+
mapping[csvField] = answer;
|
|
164
|
+
console.log(`ā
${csvField} ā ${answer}`);
|
|
165
|
+
}
|
|
166
|
+
else if (answer === 'skip') {
|
|
167
|
+
console.log(`āļø Skipping ${csvField}`);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log(`ā Invalid field. Skipping ${csvField}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
rl.close();
|
|
174
|
+
return mapping;
|
|
175
|
+
}
|
|
176
|
+
function saveMapping(mapping, outputFile) {
|
|
177
|
+
const lines = Object.entries(mapping).map(([csv, twenty]) => `${csv}=${twenty}`);
|
|
178
|
+
fs.writeFileSync(outputFile, lines.join('\n'), 'utf8');
|
|
179
|
+
console.log(`š¾ Mapping saved to ${outputFile}`);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.js","sourceRoot":"","sources":["../src/mapper.ts"],"names":[],"mappings":"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"}
|