twenty-client-sdk 2.41.0 → 2.43.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/dist/{application-BeF7traE.mjs → application-CGcz3HPn.mjs} +523 -491
- package/dist/application-KImgjhhl.js +20 -0
- package/dist/generate/twenty-client-template.d.ts +15 -7
- package/dist/generate.cjs +197 -95
- package/dist/generate.mjs +3 -3
- package/dist/metadata/generated/index.d.ts +15 -7
- package/dist/metadata/generated/schema.d.ts +690 -231
- package/dist/metadata/generated/types.d.ts +310 -102
- package/dist/metadata.cjs +5 -3
- package/dist/metadata.mjs +2511 -2224
- package/dist/rest.cjs +1 -1
- package/dist/rest.mjs +1 -1
- package/package.json +1 -1
- package/dist/application-DxQ8pkY6.js +0 -20
package/dist/generate.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./chunk-mLOUI7ql.js"),t=require("./application-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./chunk-mLOUI7ql.js"),t=require("./application-KImgjhhl.js");let n=require("node:fs/promises"),r=require("node:path"),i=require("esbuild"),a=require("graphql"),o=require("lodash/camelCase.js");o=e.r(o);let s=require("node:fs"),c=require("node:os"),l=require("prettier/standalone");l=e.r(l);let u=require("prettier/plugins/graphql");u=e.r(u);let d=require("prettier/plugins/typescript");d=e.r(d);let f=require("prettier/plugins/estree");f=e.r(f);let p=require("lodash/uniq.js");p=e.r(p);let ee=require("node:url");var te=`// __STRIPPED_DURING_INJECTION_START__`,ne=`// __STRIPPED_DURING_INJECTION_END__`,m=`// __UPLOAD_FILE_START__`,h=`// __UPLOAD_FILE_END__`,g=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),_=(e,t)=>{let n=e;return n=n.replace(RegExp(`${g(te)}[\\s\\S]*?${g(ne)}\\n?`),``),n=n.replace(`'__TWENTY_DEFAULT_URL__'`,t.defaultUrl),n=n.replace(/TwentyGeneratedClient/g,t.apiClientName),t.includeUploadFile?(n=n.replace(RegExp(`\\s*${g(m)}\\n`),`
|
|
2
2
|
`),n=n.replace(RegExp(`\\s*${g(h)}\\n`),`
|
|
3
3
|
`)):n=n.replace(RegExp(`\\s*${g(m)}[\\s\\S]*?${g(h)}\\n?`),`
|
|
4
4
|
`),`\n// ${t.apiClientName} (auto-injected by twenty-client-sdk)\n${n}`},v=e=>(0,n.mkdir)(e,{recursive:!0}),y=async e=>{let t;try{t=await(0,n.readdir)(e)}catch(t){if(t instanceof Error&&`code`in t&&t.code===`ENOENT`){await(0,n.mkdir)(e,{recursive:!0});return}throw t}await Promise.all(t.map(t=>(0,n.rm)((0,r.join)(e,t),{recursive:!0,force:!0})))},b=async(e,t)=>{try{await(0,n.rename)(e,t)}catch(r){if(r instanceof Error&&`code`in r&&r.code===`EXDEV`)await(0,n.cp)(e,t,{recursive:!0}),await(0,n.rm)(e,{recursive:!0,force:!0});else throw r}},x=e=>(0,n.rm)(e,{recursive:!0,force:!0}),re=e=>{let{root:t}=(0,r.parse)(e),n=e.slice(t.length).split(/[\\/]/).filter(Boolean).length,i=(0,r.resolve)((0,c.homedir)()),a=e===i||i.startsWith(`${e}/`);if(e===t||n<2||a)throw Error(`Refusing to recursively clear unsafe path: ${e}`)},S=async(e,t=!1)=>{let n=(0,r.resolve)(...e);t&&(re(n),await s.promises.rm(n,{recursive:!0,force:!0})),await s.promises.mkdir(n,{recursive:!0})},C=async(e,t)=>{let n=(0,r.resolve)(...e,`..`);await s.promises.mkdir(n,{recursive:!0}),await s.promises.writeFile((0,r.resolve)(...e),t)},w=`./runtime`,T=e=>e?`${e.name}GenqlSelection`:``,ie=e=>{let t=e.config?.endpoint?`"${e.config.endpoint}"`:`undefined`,n=e.config?.fetchImport;return`
|
|
@@ -1154,6 +1154,20 @@ type GraphqlResponse = {
|
|
|
1154
1154
|
rawBody: string;
|
|
1155
1155
|
};
|
|
1156
1156
|
|
|
1157
|
+
type FilesFieldUploadTarget = {
|
|
1158
|
+
fileId: string;
|
|
1159
|
+
uploadUrl: string;
|
|
1160
|
+
contentType: string;
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
type FilesFieldUploadedFile = {
|
|
1164
|
+
id: string;
|
|
1165
|
+
path: string;
|
|
1166
|
+
size: number;
|
|
1167
|
+
createdAt: string;
|
|
1168
|
+
url: string;
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1157
1171
|
const getProcessEnvironment = (): ProcessEnvironment => {
|
|
1158
1172
|
const processObject = (
|
|
1159
1173
|
globalThis as { process?: { env?: ProcessEnvironment } }
|
|
@@ -1303,60 +1317,91 @@ export class TwentyGeneratedClient {
|
|
|
1303
1317
|
}
|
|
1304
1318
|
|
|
1305
1319
|
// __UPLOAD_FILE_START__
|
|
1306
|
-
async uploadFile(
|
|
1307
|
-
fileBuffer
|
|
1308
|
-
filename
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
'operations',
|
|
1322
|
-
JSON.stringify({
|
|
1323
|
-
query: \`mutation UploadFilesFieldFileByUniversalIdentifier($file: Upload!, $fieldMetadataUniversalIdentifier: String!) {
|
|
1324
|
-
uploadFilesFieldFileByUniversalIdentifier(file: $file, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { id path size createdAt url }
|
|
1320
|
+
async uploadFile({
|
|
1321
|
+
fileBuffer,
|
|
1322
|
+
filename,
|
|
1323
|
+
fieldMetadataUniversalIdentifier,
|
|
1324
|
+
}: {
|
|
1325
|
+
fileBuffer: Buffer;
|
|
1326
|
+
filename: string;
|
|
1327
|
+
fieldMetadataUniversalIdentifier: string;
|
|
1328
|
+
}): Promise<FilesFieldUploadedFile> {
|
|
1329
|
+
const { createFileUpload: uploadTarget } =
|
|
1330
|
+
await this.executeMutationOrThrow<{
|
|
1331
|
+
createFileUpload: FilesFieldUploadTarget;
|
|
1332
|
+
}>({
|
|
1333
|
+
query: \`mutation CreateFilesFieldFileUpload($filename: String!, $size: Float!, $fieldMetadataUniversalIdentifier: String!) {
|
|
1334
|
+
createFileUpload(filename: $filename, size: $size, fileFolder: FilesField, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { fileId uploadUrl contentType }
|
|
1325
1335
|
}\`,
|
|
1326
1336
|
variables: {
|
|
1327
|
-
|
|
1337
|
+
filename,
|
|
1338
|
+
size: fileBuffer.byteLength,
|
|
1328
1339
|
fieldMetadataUniversalIdentifier,
|
|
1329
1340
|
},
|
|
1330
|
-
})
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1341
|
+
});
|
|
1342
|
+
|
|
1343
|
+
await this.putFileToUploadTargetOrThrow({ fileBuffer, uploadTarget });
|
|
1344
|
+
|
|
1345
|
+
const { completeFileUpload: uploadedFile } =
|
|
1346
|
+
await this.executeMutationOrThrow<{
|
|
1347
|
+
completeFileUpload: FilesFieldUploadedFile;
|
|
1348
|
+
}>({
|
|
1349
|
+
query: \`mutation CompleteFilesFieldFileUpload($fileId: String!) {
|
|
1350
|
+
completeFileUpload(fileId: $fileId) { id path size createdAt url }
|
|
1351
|
+
}\`,
|
|
1352
|
+
variables: { fileId: uploadTarget.fileId },
|
|
1353
|
+
});
|
|
1354
|
+
|
|
1355
|
+
return uploadedFile;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
private async putFileToUploadTargetOrThrow({
|
|
1359
|
+
fileBuffer,
|
|
1360
|
+
uploadTarget,
|
|
1361
|
+
}: {
|
|
1362
|
+
fileBuffer: Buffer;
|
|
1363
|
+
uploadTarget: FilesFieldUploadTarget;
|
|
1364
|
+
}): Promise<void> {
|
|
1365
|
+
const fetchImplementation = this.getFetchImplementationOrThrow();
|
|
1366
|
+
|
|
1367
|
+
const response = await fetchImplementation.call(
|
|
1368
|
+
globalThis,
|
|
1369
|
+
uploadTarget.uploadUrl,
|
|
1370
|
+
{
|
|
1371
|
+
method: 'PUT',
|
|
1372
|
+
headers: { 'Content-Type': uploadTarget.contentType },
|
|
1373
|
+
body: fileBuffer as BodyInit,
|
|
1374
|
+
credentials: 'omit',
|
|
1375
|
+
},
|
|
1337
1376
|
);
|
|
1338
1377
|
|
|
1378
|
+
if (!response.ok) {
|
|
1379
|
+
throw new Error(
|
|
1380
|
+
\`File upload failed (\${response.status} \${response.statusText}): \${await response.text()}\`,
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
private async executeMutationOrThrow<TData>({
|
|
1386
|
+
query,
|
|
1387
|
+
variables,
|
|
1388
|
+
}: {
|
|
1389
|
+
query: string;
|
|
1390
|
+
variables: Record<string, unknown>;
|
|
1391
|
+
}): Promise<TData> {
|
|
1339
1392
|
const result = await this.executeGraphqlRequestWithOptionalRefresh({
|
|
1340
|
-
operation:
|
|
1341
|
-
headers: {},
|
|
1342
|
-
requestInit: {
|
|
1343
|
-
method: 'POST',
|
|
1344
|
-
},
|
|
1393
|
+
operation: { query, variables },
|
|
1345
1394
|
});
|
|
1346
1395
|
|
|
1347
1396
|
if (result.errors) {
|
|
1348
1397
|
throw new GenqlError(result.errors, result.data);
|
|
1349
1398
|
}
|
|
1350
1399
|
|
|
1351
|
-
|
|
1400
|
+
if (!result.data) {
|
|
1401
|
+
throw new Error('Empty GraphQL response');
|
|
1402
|
+
}
|
|
1352
1403
|
|
|
1353
|
-
return data
|
|
1354
|
-
id: string;
|
|
1355
|
-
path: string;
|
|
1356
|
-
size: number;
|
|
1357
|
-
createdAt: string;
|
|
1358
|
-
url: string;
|
|
1359
|
-
};
|
|
1404
|
+
return result.data as TData;
|
|
1360
1405
|
}
|
|
1361
1406
|
// __UPLOAD_FILE_END__
|
|
1362
1407
|
|
|
@@ -1405,12 +1450,7 @@ export class TwentyGeneratedClient {
|
|
|
1405
1450
|
requestInit?: RequestInit;
|
|
1406
1451
|
token: string | null;
|
|
1407
1452
|
}): Promise<GraphqlResponse> {
|
|
1408
|
-
|
|
1409
|
-
throw new Error(
|
|
1410
|
-
'Global \`fetch\` function is not available, ' +
|
|
1411
|
-
'pass a fetch implementation to the Twenty client',
|
|
1412
|
-
);
|
|
1413
|
-
}
|
|
1453
|
+
const fetchImplementation = this.getFetchImplementationOrThrow();
|
|
1414
1454
|
|
|
1415
1455
|
const resolvedHeaders = await this.resolveHeaders();
|
|
1416
1456
|
const requestHeaders = new Headers(resolvedHeaders);
|
|
@@ -1433,7 +1473,7 @@ export class TwentyGeneratedClient {
|
|
|
1433
1473
|
requestHeaders.delete('Authorization');
|
|
1434
1474
|
}
|
|
1435
1475
|
|
|
1436
|
-
const response = await
|
|
1476
|
+
const response = await fetchImplementation.call(globalThis, this.url, {
|
|
1437
1477
|
...this.requestOptions,
|
|
1438
1478
|
...requestInit,
|
|
1439
1479
|
method: requestInit?.method ?? 'POST',
|
|
@@ -1461,6 +1501,17 @@ export class TwentyGeneratedClient {
|
|
|
1461
1501
|
};
|
|
1462
1502
|
}
|
|
1463
1503
|
|
|
1504
|
+
private getFetchImplementationOrThrow(): typeof globalThis.fetch {
|
|
1505
|
+
if (!this.fetchImplementation) {
|
|
1506
|
+
throw new Error(
|
|
1507
|
+
'Global \`fetch\` function is not available, ' +
|
|
1508
|
+
'pass a fetch implementation to the Twenty client',
|
|
1509
|
+
);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
return this.fetchImplementation;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1464
1515
|
private async resolveHeaders(): Promise<HeadersInit> {
|
|
1465
1516
|
if (typeof this.headers === 'function') {
|
|
1466
1517
|
return (await this.headers()) ?? {};
|
|
@@ -1600,6 +1651,20 @@ type GraphqlResponse = {
|
|
|
1600
1651
|
rawBody: string;
|
|
1601
1652
|
};
|
|
1602
1653
|
|
|
1654
|
+
type FilesFieldUploadTarget = {
|
|
1655
|
+
fileId: string;
|
|
1656
|
+
uploadUrl: string;
|
|
1657
|
+
contentType: string;
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1660
|
+
type FilesFieldUploadedFile = {
|
|
1661
|
+
id: string;
|
|
1662
|
+
path: string;
|
|
1663
|
+
size: number;
|
|
1664
|
+
createdAt: string;
|
|
1665
|
+
url: string;
|
|
1666
|
+
};
|
|
1667
|
+
|
|
1603
1668
|
const getProcessEnvironment = (): ProcessEnvironment => {
|
|
1604
1669
|
const processObject = (
|
|
1605
1670
|
globalThis as { process?: { env?: ProcessEnvironment } }
|
|
@@ -1749,60 +1814,91 @@ export class TwentyGeneratedClient {
|
|
|
1749
1814
|
}
|
|
1750
1815
|
|
|
1751
1816
|
// __UPLOAD_FILE_START__
|
|
1752
|
-
async uploadFile(
|
|
1753
|
-
fileBuffer
|
|
1754
|
-
filename
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
'operations',
|
|
1768
|
-
JSON.stringify({
|
|
1769
|
-
query: \`mutation UploadFilesFieldFileByUniversalIdentifier($file: Upload!, $fieldMetadataUniversalIdentifier: String!) {
|
|
1770
|
-
uploadFilesFieldFileByUniversalIdentifier(file: $file, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { id path size createdAt url }
|
|
1817
|
+
async uploadFile({
|
|
1818
|
+
fileBuffer,
|
|
1819
|
+
filename,
|
|
1820
|
+
fieldMetadataUniversalIdentifier,
|
|
1821
|
+
}: {
|
|
1822
|
+
fileBuffer: Buffer;
|
|
1823
|
+
filename: string;
|
|
1824
|
+
fieldMetadataUniversalIdentifier: string;
|
|
1825
|
+
}): Promise<FilesFieldUploadedFile> {
|
|
1826
|
+
const { createFileUpload: uploadTarget } =
|
|
1827
|
+
await this.executeMutationOrThrow<{
|
|
1828
|
+
createFileUpload: FilesFieldUploadTarget;
|
|
1829
|
+
}>({
|
|
1830
|
+
query: \`mutation CreateFilesFieldFileUpload($filename: String!, $size: Float!, $fieldMetadataUniversalIdentifier: String!) {
|
|
1831
|
+
createFileUpload(filename: $filename, size: $size, fileFolder: FilesField, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { fileId uploadUrl contentType }
|
|
1771
1832
|
}\`,
|
|
1772
1833
|
variables: {
|
|
1773
|
-
|
|
1834
|
+
filename,
|
|
1835
|
+
size: fileBuffer.byteLength,
|
|
1774
1836
|
fieldMetadataUniversalIdentifier,
|
|
1775
1837
|
},
|
|
1776
|
-
})
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1838
|
+
});
|
|
1839
|
+
|
|
1840
|
+
await this.putFileToUploadTargetOrThrow({ fileBuffer, uploadTarget });
|
|
1841
|
+
|
|
1842
|
+
const { completeFileUpload: uploadedFile } =
|
|
1843
|
+
await this.executeMutationOrThrow<{
|
|
1844
|
+
completeFileUpload: FilesFieldUploadedFile;
|
|
1845
|
+
}>({
|
|
1846
|
+
query: \`mutation CompleteFilesFieldFileUpload($fileId: String!) {
|
|
1847
|
+
completeFileUpload(fileId: $fileId) { id path size createdAt url }
|
|
1848
|
+
}\`,
|
|
1849
|
+
variables: { fileId: uploadTarget.fileId },
|
|
1850
|
+
});
|
|
1851
|
+
|
|
1852
|
+
return uploadedFile;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
private async putFileToUploadTargetOrThrow({
|
|
1856
|
+
fileBuffer,
|
|
1857
|
+
uploadTarget,
|
|
1858
|
+
}: {
|
|
1859
|
+
fileBuffer: Buffer;
|
|
1860
|
+
uploadTarget: FilesFieldUploadTarget;
|
|
1861
|
+
}): Promise<void> {
|
|
1862
|
+
const fetchImplementation = this.getFetchImplementationOrThrow();
|
|
1863
|
+
|
|
1864
|
+
const response = await fetchImplementation.call(
|
|
1865
|
+
globalThis,
|
|
1866
|
+
uploadTarget.uploadUrl,
|
|
1867
|
+
{
|
|
1868
|
+
method: 'PUT',
|
|
1869
|
+
headers: { 'Content-Type': uploadTarget.contentType },
|
|
1870
|
+
body: fileBuffer as BodyInit,
|
|
1871
|
+
credentials: 'omit',
|
|
1872
|
+
},
|
|
1783
1873
|
);
|
|
1784
1874
|
|
|
1875
|
+
if (!response.ok) {
|
|
1876
|
+
throw new Error(
|
|
1877
|
+
\`File upload failed (\${response.status} \${response.statusText}): \${await response.text()}\`,
|
|
1878
|
+
);
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
private async executeMutationOrThrow<TData>({
|
|
1883
|
+
query,
|
|
1884
|
+
variables,
|
|
1885
|
+
}: {
|
|
1886
|
+
query: string;
|
|
1887
|
+
variables: Record<string, unknown>;
|
|
1888
|
+
}): Promise<TData> {
|
|
1785
1889
|
const result = await this.executeGraphqlRequestWithOptionalRefresh({
|
|
1786
|
-
operation:
|
|
1787
|
-
headers: {},
|
|
1788
|
-
requestInit: {
|
|
1789
|
-
method: 'POST',
|
|
1790
|
-
},
|
|
1890
|
+
operation: { query, variables },
|
|
1791
1891
|
});
|
|
1792
1892
|
|
|
1793
1893
|
if (result.errors) {
|
|
1794
1894
|
throw new GenqlError(result.errors, result.data);
|
|
1795
1895
|
}
|
|
1796
1896
|
|
|
1797
|
-
|
|
1897
|
+
if (!result.data) {
|
|
1898
|
+
throw new Error('Empty GraphQL response');
|
|
1899
|
+
}
|
|
1798
1900
|
|
|
1799
|
-
return data
|
|
1800
|
-
id: string;
|
|
1801
|
-
path: string;
|
|
1802
|
-
size: number;
|
|
1803
|
-
createdAt: string;
|
|
1804
|
-
url: string;
|
|
1805
|
-
};
|
|
1901
|
+
return result.data as TData;
|
|
1806
1902
|
}
|
|
1807
1903
|
// __UPLOAD_FILE_END__
|
|
1808
1904
|
|
|
@@ -1851,12 +1947,7 @@ export class TwentyGeneratedClient {
|
|
|
1851
1947
|
requestInit?: RequestInit;
|
|
1852
1948
|
token: string | null;
|
|
1853
1949
|
}): Promise<GraphqlResponse> {
|
|
1854
|
-
|
|
1855
|
-
throw new Error(
|
|
1856
|
-
'Global \`fetch\` function is not available, ' +
|
|
1857
|
-
'pass a fetch implementation to the Twenty client',
|
|
1858
|
-
);
|
|
1859
|
-
}
|
|
1950
|
+
const fetchImplementation = this.getFetchImplementationOrThrow();
|
|
1860
1951
|
|
|
1861
1952
|
const resolvedHeaders = await this.resolveHeaders();
|
|
1862
1953
|
const requestHeaders = new Headers(resolvedHeaders);
|
|
@@ -1879,7 +1970,7 @@ export class TwentyGeneratedClient {
|
|
|
1879
1970
|
requestHeaders.delete('Authorization');
|
|
1880
1971
|
}
|
|
1881
1972
|
|
|
1882
|
-
const response = await
|
|
1973
|
+
const response = await fetchImplementation.call(globalThis, this.url, {
|
|
1883
1974
|
...this.requestOptions,
|
|
1884
1975
|
...requestInit,
|
|
1885
1976
|
method: requestInit?.method ?? 'POST',
|
|
@@ -1907,6 +1998,17 @@ export class TwentyGeneratedClient {
|
|
|
1907
1998
|
};
|
|
1908
1999
|
}
|
|
1909
2000
|
|
|
2001
|
+
private getFetchImplementationOrThrow(): typeof globalThis.fetch {
|
|
2002
|
+
if (!this.fetchImplementation) {
|
|
2003
|
+
throw new Error(
|
|
2004
|
+
'Global \`fetch\` function is not available, ' +
|
|
2005
|
+
'pass a fetch implementation to the Twenty client',
|
|
2006
|
+
);
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
return this.fetchImplementation;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
1910
2012
|
private async resolveHeaders(): Promise<HeadersInit> {
|
|
1911
2013
|
if (typeof this.headers === 'function') {
|
|
1912
2014
|
return (await this.headers()) ?? {};
|
package/dist/generate.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e } from "./application-
|
|
1
|
+
import { a as e } from "./application-CGcz3HPn.mjs";
|
|
2
2
|
import { appendFile as t, copyFile as n, cp as r, mkdir as i, readdir as a, rename as o, rm as s, writeFile as c } from "node:fs/promises";
|
|
3
3
|
import { dirname as l, join as u, parse as ee, relative as d, resolve as f } from "node:path";
|
|
4
4
|
import { build as p } from "esbuild";
|
|
@@ -522,7 +522,7 @@ var ot = async (e) => {
|
|
|
522
522
|
JSON: "Record<string, unknown>",
|
|
523
523
|
UUID: "string"
|
|
524
524
|
}, Q = "core/generated", $ = async ({ schema: n, outputPath: r, clientWrapperTemplateSource: i }) => {
|
|
525
|
-
let a = i ?? "import type { TwentyClientRunAs } from '../shared/twenty-client-run-as.type';\n\n// Ambient type stubs for the genql-generated code this template gets\n// injected into. They enable full typecheck/lint on this file.\n// __STRIPPED_DURING_INJECTION_START__\ntype QueryGenqlSelection = Record<string, unknown>;\ntype MutationGenqlSelection = Record<string, unknown>;\ntype GraphqlOperation = Record<string, unknown>;\n\ntype ClientOptions = Omit<RequestInit, 'body' | 'headers'> & {\n url?: string;\n headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n fetcher?: (\n operation: GraphqlOperation | GraphqlOperation[],\n ) => Promise<unknown>;\n fetch?: typeof globalThis.fetch;\n batch?: unknown;\n};\n\ntype Client = {\n query: (\n request: QueryGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n mutation: (\n request: MutationGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n};\n\ndeclare function createClient(options: ClientOptions): Client;\n\ndeclare class GenqlError extends Error {\n constructor(errors: unknown, data: unknown);\n}\n// __STRIPPED_DURING_INJECTION_END__\n\nconst APP_ACCESS_TOKEN_ENV_KEY = 'TWENTY_APP_ACCESS_TOKEN';\nconst APP_APPLICATION_ACCESS_TOKEN_ENV_KEY =\n 'TWENTY_APP_APPLICATION_ACCESS_TOKEN';\nconst API_KEY_ENV_KEY = 'TWENTY_API_KEY';\n\nexport type TwentyGeneratedClientOptions = ClientOptions & {\n runAs?: TwentyClientRunAs;\n};\n\ntype ProcessEnvironment = Record<string, string | undefined>;\n\ntype GraphqlErrorPayloadEntry = {\n message?: string;\n extensions?: { code?: string };\n};\n\ntype GraphqlResponsePayload = {\n data?: Record<string, unknown>;\n errors?: GraphqlErrorPayloadEntry[];\n};\n\ntype GraphqlResponse = {\n status: number;\n statusText: string;\n payload: GraphqlResponsePayload | null;\n rawBody: string;\n};\n\nconst getProcessEnvironment = (): ProcessEnvironment => {\n const processObject = (\n globalThis as { process?: { env?: ProcessEnvironment } }\n ).process;\n\n return processObject?.env ?? {};\n};\n\nconst getTokenFromAuthorizationHeader = (\n authorizationHeader: string | undefined,\n): string | null => {\n if (typeof authorizationHeader !== 'string') {\n return null;\n }\n\n const trimmedAuthorizationHeader = authorizationHeader.trim();\n\n if (trimmedAuthorizationHeader.length === 0) {\n return null;\n }\n\n if (trimmedAuthorizationHeader === 'Bearer') {\n return null;\n }\n\n if (trimmedAuthorizationHeader.startsWith('Bearer ')) {\n return trimmedAuthorizationHeader.slice('Bearer '.length).trim();\n }\n\n return trimmedAuthorizationHeader;\n};\n\nconst getTokenFromHeaders = (\n headers: HeadersInit | undefined,\n): string | null => {\n if (!headers) {\n return null;\n }\n\n if (headers instanceof Headers) {\n return getTokenFromAuthorizationHeader(\n headers.get('Authorization') ?? undefined,\n );\n }\n\n if (Array.isArray(headers)) {\n const matchedAuthorizationHeader = headers.find(\n ([headerName]) => headerName.toLowerCase() === 'authorization',\n );\n\n return getTokenFromAuthorizationHeader(matchedAuthorizationHeader?.[1]);\n }\n\n const headersRecord = headers as Record<string, string | undefined>;\n\n return getTokenFromAuthorizationHeader(\n headersRecord.Authorization ?? headersRecord.authorization,\n );\n};\n\nconst hasAuthenticationErrorInGraphqlPayload = (\n payload: GraphqlResponsePayload | null,\n): boolean => {\n if (!payload?.errors) {\n return false;\n }\n\n return payload.errors.some((graphqlError) => {\n return (\n graphqlError.extensions?.code === 'UNAUTHENTICATED' ||\n graphqlError.message?.toLowerCase() === 'unauthorized'\n );\n });\n};\n\nconst defaultOptions: TwentyGeneratedClientOptions = {\n url: '__TWENTY_DEFAULT_URL__',\n headers: {\n 'Content-Type': 'application/json',\n },\n};\n\nexport class TwentyGeneratedClient {\n private client: Client;\n private url: string;\n private requestOptions: RequestInit;\n private headers: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n private fetchImplementation: typeof globalThis.fetch | null;\n private authorizationToken: string | null;\n private refreshAccessTokenPromise: Promise<string | null> | null = null;\n\n constructor(options?: TwentyGeneratedClientOptions) {\n const merged: TwentyGeneratedClientOptions = {\n ...defaultOptions,\n ...options,\n };\n\n const {\n url,\n headers,\n fetch: customFetchImplementation,\n fetcher: _fetcher,\n batch: _batch,\n runAs,\n ...requestOptions\n } = merged;\n\n this.url = url ?? '';\n this.requestOptions = requestOptions;\n this.headers = headers ?? {};\n this.fetchImplementation =\n customFetchImplementation ?? globalThis.fetch ?? null;\n\n const processEnvironment = getProcessEnvironment();\n const tokenFromHeaders = getTokenFromHeaders(\n typeof headers === 'function' ? undefined : headers,\n );\n\n // Priority: explicit header > the token for the requested access > api key\n // (legacy).\n this.authorizationToken =\n tokenFromHeaders ??\n processEnvironment[\n runAs === 'application'\n ? APP_APPLICATION_ACCESS_TOKEN_ENV_KEY\n : APP_ACCESS_TOKEN_ENV_KEY\n ] ??\n processEnvironment[API_KEY_ENV_KEY] ??\n null;\n\n this.client = createClient({\n ...merged,\n headers: undefined,\n fetcher: async (operation) =>\n this.executeGraphqlRequestWithOptionalRefresh({\n operation,\n }),\n });\n }\n\n query<R extends QueryGenqlSelection>(request: R & { __name?: string }) {\n return this.client.query(request);\n }\n\n mutation<R extends MutationGenqlSelection>(request: R & { __name?: string }) {\n return this.client.mutation(request);\n }\n\n // __UPLOAD_FILE_START__\n async uploadFile(\n fileBuffer: Buffer,\n filename: string,\n contentType: string = 'application/octet-stream',\n fieldMetadataUniversalIdentifier: string,\n ): Promise<{\n id: string;\n path: string;\n size: number;\n createdAt: string;\n url: string;\n }> {\n const form = new FormData();\n\n form.append(\n 'operations',\n JSON.stringify({\n query: `mutation UploadFilesFieldFileByUniversalIdentifier($file: Upload!, $fieldMetadataUniversalIdentifier: String!) {\n uploadFilesFieldFileByUniversalIdentifier(file: $file, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { id path size createdAt url }\n }`,\n variables: {\n file: null,\n fieldMetadataUniversalIdentifier,\n },\n }),\n );\n form.append('map', JSON.stringify({ '0': ['variables.file'] }));\n form.append(\n '0',\n new Blob([fileBuffer as BlobPart], { type: contentType }),\n filename,\n );\n\n const result = await this.executeGraphqlRequestWithOptionalRefresh({\n operation: form,\n headers: {},\n requestInit: {\n method: 'POST',\n },\n });\n\n if (result.errors) {\n throw new GenqlError(result.errors, result.data);\n }\n\n const data = result.data as Record<string, unknown>;\n\n return data.uploadFilesFieldFileByUniversalIdentifier as {\n id: string;\n path: string;\n size: number;\n createdAt: string;\n url: string;\n };\n }\n // __UPLOAD_FILE_END__\n\n private async executeGraphqlRequestWithOptionalRefresh({\n operation,\n headers,\n requestInit,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n }) {\n const firstResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: this.authorizationToken,\n });\n\n if (this.shouldRefreshToken(firstResponse)) {\n const refreshedAccessToken = await this.requestRefreshedAccessToken();\n\n if (refreshedAccessToken) {\n const retryResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: refreshedAccessToken,\n });\n\n return this.assertResponseIsSuccessful(retryResponse);\n }\n }\n\n return this.assertResponseIsSuccessful(firstResponse);\n }\n\n private async executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n token: string | null;\n }): Promise<GraphqlResponse> {\n if (!this.fetchImplementation) {\n throw new Error(\n 'Global `fetch` function is not available, ' +\n 'pass a fetch implementation to the Twenty client',\n );\n }\n\n const resolvedHeaders = await this.resolveHeaders();\n const requestHeaders = new Headers(resolvedHeaders);\n\n if (headers) {\n new Headers(headers).forEach((value, key) =>\n requestHeaders.set(key, value),\n );\n }\n\n if (operation instanceof FormData) {\n requestHeaders.delete('Content-Type');\n } else {\n requestHeaders.set('Content-Type', 'application/json');\n }\n\n if (token) {\n requestHeaders.set('Authorization', `Bearer ${token}`);\n } else {\n requestHeaders.delete('Authorization');\n }\n\n const response = await this.fetchImplementation.call(globalThis, this.url, {\n ...this.requestOptions,\n ...requestInit,\n method: requestInit?.method ?? 'POST',\n headers: requestHeaders,\n body:\n operation instanceof FormData ? operation : JSON.stringify(operation),\n });\n\n const rawBody = await response.text();\n let payload: GraphqlResponsePayload | null = null;\n\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as GraphqlResponsePayload;\n } catch {\n payload = null;\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n payload,\n rawBody,\n };\n }\n\n private async resolveHeaders(): Promise<HeadersInit> {\n if (typeof this.headers === 'function') {\n return (await this.headers()) ?? {};\n }\n\n return this.headers ?? {};\n }\n\n private shouldRefreshToken(response: GraphqlResponse): boolean {\n if (response.status === 401) {\n return true;\n }\n\n return hasAuthenticationErrorInGraphqlPayload(response.payload);\n }\n\n private assertResponseIsSuccessful(response: GraphqlResponse) {\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`${response.statusText}: ${response.rawBody}`);\n }\n\n if (response.payload === null) {\n throw new Error('Invalid JSON response');\n }\n\n return response.payload;\n }\n\n private async requestRefreshedAccessToken(): Promise<string | null> {\n const refreshAccessTokenFunction = (\n globalThis as {\n frontComponentHostCommunicationApi?: {\n requestAccessTokenRefresh?: () => Promise<string>;\n };\n }\n ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;\n\n if (typeof refreshAccessTokenFunction !== 'function') {\n return null;\n }\n\n if (!this.refreshAccessTokenPromise) {\n this.refreshAccessTokenPromise = refreshAccessTokenFunction()\n .then((refreshedAccessToken) => {\n if (\n typeof refreshedAccessToken !== 'string' ||\n refreshedAccessToken.length === 0\n ) {\n return null;\n }\n\n this.setAuthorizationToken(refreshedAccessToken);\n\n return refreshedAccessToken;\n })\n .catch((refreshError: unknown) => {\n console.error('Twenty client: token refresh failed', refreshError);\n\n return null;\n })\n .finally(() => {\n this.refreshAccessTokenPromise = null;\n });\n }\n\n return this.refreshAccessTokenPromise;\n }\n\n private setAuthorizationToken(token: string) {\n this.authorizationToken = token;\n\n const processEnvironment = getProcessEnvironment();\n\n processEnvironment[APP_ACCESS_TOKEN_ENV_KEY] = token;\n }\n}\n", o = `${r}.tmp`;
|
|
525
|
+
let a = i ?? "import type { TwentyClientRunAs } from '../shared/twenty-client-run-as.type';\n\n// Ambient type stubs for the genql-generated code this template gets\n// injected into. They enable full typecheck/lint on this file.\n// __STRIPPED_DURING_INJECTION_START__\ntype QueryGenqlSelection = Record<string, unknown>;\ntype MutationGenqlSelection = Record<string, unknown>;\ntype GraphqlOperation = Record<string, unknown>;\n\ntype ClientOptions = Omit<RequestInit, 'body' | 'headers'> & {\n url?: string;\n headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n fetcher?: (\n operation: GraphqlOperation | GraphqlOperation[],\n ) => Promise<unknown>;\n fetch?: typeof globalThis.fetch;\n batch?: unknown;\n};\n\ntype Client = {\n query: (\n request: QueryGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n mutation: (\n request: MutationGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n};\n\ndeclare function createClient(options: ClientOptions): Client;\n\ndeclare class GenqlError extends Error {\n constructor(errors: unknown, data: unknown);\n}\n// __STRIPPED_DURING_INJECTION_END__\n\nconst APP_ACCESS_TOKEN_ENV_KEY = 'TWENTY_APP_ACCESS_TOKEN';\nconst APP_APPLICATION_ACCESS_TOKEN_ENV_KEY =\n 'TWENTY_APP_APPLICATION_ACCESS_TOKEN';\nconst API_KEY_ENV_KEY = 'TWENTY_API_KEY';\n\nexport type TwentyGeneratedClientOptions = ClientOptions & {\n runAs?: TwentyClientRunAs;\n};\n\ntype ProcessEnvironment = Record<string, string | undefined>;\n\ntype GraphqlErrorPayloadEntry = {\n message?: string;\n extensions?: { code?: string };\n};\n\ntype GraphqlResponsePayload = {\n data?: Record<string, unknown>;\n errors?: GraphqlErrorPayloadEntry[];\n};\n\ntype GraphqlResponse = {\n status: number;\n statusText: string;\n payload: GraphqlResponsePayload | null;\n rawBody: string;\n};\n\ntype FilesFieldUploadTarget = {\n fileId: string;\n uploadUrl: string;\n contentType: string;\n};\n\ntype FilesFieldUploadedFile = {\n id: string;\n path: string;\n size: number;\n createdAt: string;\n url: string;\n};\n\nconst getProcessEnvironment = (): ProcessEnvironment => {\n const processObject = (\n globalThis as { process?: { env?: ProcessEnvironment } }\n ).process;\n\n return processObject?.env ?? {};\n};\n\nconst getTokenFromAuthorizationHeader = (\n authorizationHeader: string | undefined,\n): string | null => {\n if (typeof authorizationHeader !== 'string') {\n return null;\n }\n\n const trimmedAuthorizationHeader = authorizationHeader.trim();\n\n if (trimmedAuthorizationHeader.length === 0) {\n return null;\n }\n\n if (trimmedAuthorizationHeader === 'Bearer') {\n return null;\n }\n\n if (trimmedAuthorizationHeader.startsWith('Bearer ')) {\n return trimmedAuthorizationHeader.slice('Bearer '.length).trim();\n }\n\n return trimmedAuthorizationHeader;\n};\n\nconst getTokenFromHeaders = (\n headers: HeadersInit | undefined,\n): string | null => {\n if (!headers) {\n return null;\n }\n\n if (headers instanceof Headers) {\n return getTokenFromAuthorizationHeader(\n headers.get('Authorization') ?? undefined,\n );\n }\n\n if (Array.isArray(headers)) {\n const matchedAuthorizationHeader = headers.find(\n ([headerName]) => headerName.toLowerCase() === 'authorization',\n );\n\n return getTokenFromAuthorizationHeader(matchedAuthorizationHeader?.[1]);\n }\n\n const headersRecord = headers as Record<string, string | undefined>;\n\n return getTokenFromAuthorizationHeader(\n headersRecord.Authorization ?? headersRecord.authorization,\n );\n};\n\nconst hasAuthenticationErrorInGraphqlPayload = (\n payload: GraphqlResponsePayload | null,\n): boolean => {\n if (!payload?.errors) {\n return false;\n }\n\n return payload.errors.some((graphqlError) => {\n return (\n graphqlError.extensions?.code === 'UNAUTHENTICATED' ||\n graphqlError.message?.toLowerCase() === 'unauthorized'\n );\n });\n};\n\nconst defaultOptions: TwentyGeneratedClientOptions = {\n url: '__TWENTY_DEFAULT_URL__',\n headers: {\n 'Content-Type': 'application/json',\n },\n};\n\nexport class TwentyGeneratedClient {\n private client: Client;\n private url: string;\n private requestOptions: RequestInit;\n private headers: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n private fetchImplementation: typeof globalThis.fetch | null;\n private authorizationToken: string | null;\n private refreshAccessTokenPromise: Promise<string | null> | null = null;\n\n constructor(options?: TwentyGeneratedClientOptions) {\n const merged: TwentyGeneratedClientOptions = {\n ...defaultOptions,\n ...options,\n };\n\n const {\n url,\n headers,\n fetch: customFetchImplementation,\n fetcher: _fetcher,\n batch: _batch,\n runAs,\n ...requestOptions\n } = merged;\n\n this.url = url ?? '';\n this.requestOptions = requestOptions;\n this.headers = headers ?? {};\n this.fetchImplementation =\n customFetchImplementation ?? globalThis.fetch ?? null;\n\n const processEnvironment = getProcessEnvironment();\n const tokenFromHeaders = getTokenFromHeaders(\n typeof headers === 'function' ? undefined : headers,\n );\n\n // Priority: explicit header > the token for the requested access > api key\n // (legacy).\n this.authorizationToken =\n tokenFromHeaders ??\n processEnvironment[\n runAs === 'application'\n ? APP_APPLICATION_ACCESS_TOKEN_ENV_KEY\n : APP_ACCESS_TOKEN_ENV_KEY\n ] ??\n processEnvironment[API_KEY_ENV_KEY] ??\n null;\n\n this.client = createClient({\n ...merged,\n headers: undefined,\n fetcher: async (operation) =>\n this.executeGraphqlRequestWithOptionalRefresh({\n operation,\n }),\n });\n }\n\n query<R extends QueryGenqlSelection>(request: R & { __name?: string }) {\n return this.client.query(request);\n }\n\n mutation<R extends MutationGenqlSelection>(request: R & { __name?: string }) {\n return this.client.mutation(request);\n }\n\n // __UPLOAD_FILE_START__\n async uploadFile({\n fileBuffer,\n filename,\n fieldMetadataUniversalIdentifier,\n }: {\n fileBuffer: Buffer;\n filename: string;\n fieldMetadataUniversalIdentifier: string;\n }): Promise<FilesFieldUploadedFile> {\n const { createFileUpload: uploadTarget } =\n await this.executeMutationOrThrow<{\n createFileUpload: FilesFieldUploadTarget;\n }>({\n query: `mutation CreateFilesFieldFileUpload($filename: String!, $size: Float!, $fieldMetadataUniversalIdentifier: String!) {\n createFileUpload(filename: $filename, size: $size, fileFolder: FilesField, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { fileId uploadUrl contentType }\n }`,\n variables: {\n filename,\n size: fileBuffer.byteLength,\n fieldMetadataUniversalIdentifier,\n },\n });\n\n await this.putFileToUploadTargetOrThrow({ fileBuffer, uploadTarget });\n\n const { completeFileUpload: uploadedFile } =\n await this.executeMutationOrThrow<{\n completeFileUpload: FilesFieldUploadedFile;\n }>({\n query: `mutation CompleteFilesFieldFileUpload($fileId: String!) {\n completeFileUpload(fileId: $fileId) { id path size createdAt url }\n }`,\n variables: { fileId: uploadTarget.fileId },\n });\n\n return uploadedFile;\n }\n\n private async putFileToUploadTargetOrThrow({\n fileBuffer,\n uploadTarget,\n }: {\n fileBuffer: Buffer;\n uploadTarget: FilesFieldUploadTarget;\n }): Promise<void> {\n const fetchImplementation = this.getFetchImplementationOrThrow();\n\n const response = await fetchImplementation.call(\n globalThis,\n uploadTarget.uploadUrl,\n {\n method: 'PUT',\n headers: { 'Content-Type': uploadTarget.contentType },\n body: fileBuffer as BodyInit,\n credentials: 'omit',\n },\n );\n\n if (!response.ok) {\n throw new Error(\n `File upload failed (${response.status} ${response.statusText}): ${await response.text()}`,\n );\n }\n }\n\n private async executeMutationOrThrow<TData>({\n query,\n variables,\n }: {\n query: string;\n variables: Record<string, unknown>;\n }): Promise<TData> {\n const result = await this.executeGraphqlRequestWithOptionalRefresh({\n operation: { query, variables },\n });\n\n if (result.errors) {\n throw new GenqlError(result.errors, result.data);\n }\n\n if (!result.data) {\n throw new Error('Empty GraphQL response');\n }\n\n return result.data as TData;\n }\n // __UPLOAD_FILE_END__\n\n private async executeGraphqlRequestWithOptionalRefresh({\n operation,\n headers,\n requestInit,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n }) {\n const firstResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: this.authorizationToken,\n });\n\n if (this.shouldRefreshToken(firstResponse)) {\n const refreshedAccessToken = await this.requestRefreshedAccessToken();\n\n if (refreshedAccessToken) {\n const retryResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: refreshedAccessToken,\n });\n\n return this.assertResponseIsSuccessful(retryResponse);\n }\n }\n\n return this.assertResponseIsSuccessful(firstResponse);\n }\n\n private async executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n token: string | null;\n }): Promise<GraphqlResponse> {\n const fetchImplementation = this.getFetchImplementationOrThrow();\n\n const resolvedHeaders = await this.resolveHeaders();\n const requestHeaders = new Headers(resolvedHeaders);\n\n if (headers) {\n new Headers(headers).forEach((value, key) =>\n requestHeaders.set(key, value),\n );\n }\n\n if (operation instanceof FormData) {\n requestHeaders.delete('Content-Type');\n } else {\n requestHeaders.set('Content-Type', 'application/json');\n }\n\n if (token) {\n requestHeaders.set('Authorization', `Bearer ${token}`);\n } else {\n requestHeaders.delete('Authorization');\n }\n\n const response = await fetchImplementation.call(globalThis, this.url, {\n ...this.requestOptions,\n ...requestInit,\n method: requestInit?.method ?? 'POST',\n headers: requestHeaders,\n body:\n operation instanceof FormData ? operation : JSON.stringify(operation),\n });\n\n const rawBody = await response.text();\n let payload: GraphqlResponsePayload | null = null;\n\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as GraphqlResponsePayload;\n } catch {\n payload = null;\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n payload,\n rawBody,\n };\n }\n\n private getFetchImplementationOrThrow(): typeof globalThis.fetch {\n if (!this.fetchImplementation) {\n throw new Error(\n 'Global `fetch` function is not available, ' +\n 'pass a fetch implementation to the Twenty client',\n );\n }\n\n return this.fetchImplementation;\n }\n\n private async resolveHeaders(): Promise<HeadersInit> {\n if (typeof this.headers === 'function') {\n return (await this.headers()) ?? {};\n }\n\n return this.headers ?? {};\n }\n\n private shouldRefreshToken(response: GraphqlResponse): boolean {\n if (response.status === 401) {\n return true;\n }\n\n return hasAuthenticationErrorInGraphqlPayload(response.payload);\n }\n\n private assertResponseIsSuccessful(response: GraphqlResponse) {\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`${response.statusText}: ${response.rawBody}`);\n }\n\n if (response.payload === null) {\n throw new Error('Invalid JSON response');\n }\n\n return response.payload;\n }\n\n private async requestRefreshedAccessToken(): Promise<string | null> {\n const refreshAccessTokenFunction = (\n globalThis as {\n frontComponentHostCommunicationApi?: {\n requestAccessTokenRefresh?: () => Promise<string>;\n };\n }\n ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;\n\n if (typeof refreshAccessTokenFunction !== 'function') {\n return null;\n }\n\n if (!this.refreshAccessTokenPromise) {\n this.refreshAccessTokenPromise = refreshAccessTokenFunction()\n .then((refreshedAccessToken) => {\n if (\n typeof refreshedAccessToken !== 'string' ||\n refreshedAccessToken.length === 0\n ) {\n return null;\n }\n\n this.setAuthorizationToken(refreshedAccessToken);\n\n return refreshedAccessToken;\n })\n .catch((refreshError: unknown) => {\n console.error('Twenty client: token refresh failed', refreshError);\n\n return null;\n })\n .finally(() => {\n this.refreshAccessTokenPromise = null;\n });\n }\n\n return this.refreshAccessTokenPromise;\n }\n\n private setAuthorizationToken(token: string) {\n this.authorizationToken = token;\n\n const processEnvironment = getProcessEnvironment();\n\n processEnvironment[APP_ACCESS_TOKEN_ENV_KEY] = token;\n }\n}\n", o = `${r}.tmp`;
|
|
526
526
|
await O(o), await k(o);
|
|
527
527
|
try {
|
|
528
528
|
await Z({
|
|
@@ -575,7 +575,7 @@ var ot = async (e) => {
|
|
|
575
575
|
JSON: "Record<string, unknown>",
|
|
576
576
|
UUID: "string"
|
|
577
577
|
}, dt = async ({ schema: n, outputPath: r, clientWrapperTemplateSource: i }) => {
|
|
578
|
-
let a = i ?? "import type { TwentyClientRunAs } from '../shared/twenty-client-run-as.type';\n\n// Ambient type stubs for the genql-generated code this template gets\n// injected into. They enable full typecheck/lint on this file.\n// __STRIPPED_DURING_INJECTION_START__\ntype QueryGenqlSelection = Record<string, unknown>;\ntype MutationGenqlSelection = Record<string, unknown>;\ntype GraphqlOperation = Record<string, unknown>;\n\ntype ClientOptions = Omit<RequestInit, 'body' | 'headers'> & {\n url?: string;\n headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n fetcher?: (\n operation: GraphqlOperation | GraphqlOperation[],\n ) => Promise<unknown>;\n fetch?: typeof globalThis.fetch;\n batch?: unknown;\n};\n\ntype Client = {\n query: (\n request: QueryGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n mutation: (\n request: MutationGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n};\n\ndeclare function createClient(options: ClientOptions): Client;\n\ndeclare class GenqlError extends Error {\n constructor(errors: unknown, data: unknown);\n}\n// __STRIPPED_DURING_INJECTION_END__\n\nconst APP_ACCESS_TOKEN_ENV_KEY = 'TWENTY_APP_ACCESS_TOKEN';\nconst APP_APPLICATION_ACCESS_TOKEN_ENV_KEY =\n 'TWENTY_APP_APPLICATION_ACCESS_TOKEN';\nconst API_KEY_ENV_KEY = 'TWENTY_API_KEY';\n\nexport type TwentyGeneratedClientOptions = ClientOptions & {\n runAs?: TwentyClientRunAs;\n};\n\ntype ProcessEnvironment = Record<string, string | undefined>;\n\ntype GraphqlErrorPayloadEntry = {\n message?: string;\n extensions?: { code?: string };\n};\n\ntype GraphqlResponsePayload = {\n data?: Record<string, unknown>;\n errors?: GraphqlErrorPayloadEntry[];\n};\n\ntype GraphqlResponse = {\n status: number;\n statusText: string;\n payload: GraphqlResponsePayload | null;\n rawBody: string;\n};\n\nconst getProcessEnvironment = (): ProcessEnvironment => {\n const processObject = (\n globalThis as { process?: { env?: ProcessEnvironment } }\n ).process;\n\n return processObject?.env ?? {};\n};\n\nconst getTokenFromAuthorizationHeader = (\n authorizationHeader: string | undefined,\n): string | null => {\n if (typeof authorizationHeader !== 'string') {\n return null;\n }\n\n const trimmedAuthorizationHeader = authorizationHeader.trim();\n\n if (trimmedAuthorizationHeader.length === 0) {\n return null;\n }\n\n if (trimmedAuthorizationHeader === 'Bearer') {\n return null;\n }\n\n if (trimmedAuthorizationHeader.startsWith('Bearer ')) {\n return trimmedAuthorizationHeader.slice('Bearer '.length).trim();\n }\n\n return trimmedAuthorizationHeader;\n};\n\nconst getTokenFromHeaders = (\n headers: HeadersInit | undefined,\n): string | null => {\n if (!headers) {\n return null;\n }\n\n if (headers instanceof Headers) {\n return getTokenFromAuthorizationHeader(\n headers.get('Authorization') ?? undefined,\n );\n }\n\n if (Array.isArray(headers)) {\n const matchedAuthorizationHeader = headers.find(\n ([headerName]) => headerName.toLowerCase() === 'authorization',\n );\n\n return getTokenFromAuthorizationHeader(matchedAuthorizationHeader?.[1]);\n }\n\n const headersRecord = headers as Record<string, string | undefined>;\n\n return getTokenFromAuthorizationHeader(\n headersRecord.Authorization ?? headersRecord.authorization,\n );\n};\n\nconst hasAuthenticationErrorInGraphqlPayload = (\n payload: GraphqlResponsePayload | null,\n): boolean => {\n if (!payload?.errors) {\n return false;\n }\n\n return payload.errors.some((graphqlError) => {\n return (\n graphqlError.extensions?.code === 'UNAUTHENTICATED' ||\n graphqlError.message?.toLowerCase() === 'unauthorized'\n );\n });\n};\n\nconst defaultOptions: TwentyGeneratedClientOptions = {\n url: '__TWENTY_DEFAULT_URL__',\n headers: {\n 'Content-Type': 'application/json',\n },\n};\n\nexport class TwentyGeneratedClient {\n private client: Client;\n private url: string;\n private requestOptions: RequestInit;\n private headers: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n private fetchImplementation: typeof globalThis.fetch | null;\n private authorizationToken: string | null;\n private refreshAccessTokenPromise: Promise<string | null> | null = null;\n\n constructor(options?: TwentyGeneratedClientOptions) {\n const merged: TwentyGeneratedClientOptions = {\n ...defaultOptions,\n ...options,\n };\n\n const {\n url,\n headers,\n fetch: customFetchImplementation,\n fetcher: _fetcher,\n batch: _batch,\n runAs,\n ...requestOptions\n } = merged;\n\n this.url = url ?? '';\n this.requestOptions = requestOptions;\n this.headers = headers ?? {};\n this.fetchImplementation =\n customFetchImplementation ?? globalThis.fetch ?? null;\n\n const processEnvironment = getProcessEnvironment();\n const tokenFromHeaders = getTokenFromHeaders(\n typeof headers === 'function' ? undefined : headers,\n );\n\n // Priority: explicit header > the token for the requested access > api key\n // (legacy).\n this.authorizationToken =\n tokenFromHeaders ??\n processEnvironment[\n runAs === 'application'\n ? APP_APPLICATION_ACCESS_TOKEN_ENV_KEY\n : APP_ACCESS_TOKEN_ENV_KEY\n ] ??\n processEnvironment[API_KEY_ENV_KEY] ??\n null;\n\n this.client = createClient({\n ...merged,\n headers: undefined,\n fetcher: async (operation) =>\n this.executeGraphqlRequestWithOptionalRefresh({\n operation,\n }),\n });\n }\n\n query<R extends QueryGenqlSelection>(request: R & { __name?: string }) {\n return this.client.query(request);\n }\n\n mutation<R extends MutationGenqlSelection>(request: R & { __name?: string }) {\n return this.client.mutation(request);\n }\n\n // __UPLOAD_FILE_START__\n async uploadFile(\n fileBuffer: Buffer,\n filename: string,\n contentType: string = 'application/octet-stream',\n fieldMetadataUniversalIdentifier: string,\n ): Promise<{\n id: string;\n path: string;\n size: number;\n createdAt: string;\n url: string;\n }> {\n const form = new FormData();\n\n form.append(\n 'operations',\n JSON.stringify({\n query: `mutation UploadFilesFieldFileByUniversalIdentifier($file: Upload!, $fieldMetadataUniversalIdentifier: String!) {\n uploadFilesFieldFileByUniversalIdentifier(file: $file, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { id path size createdAt url }\n }`,\n variables: {\n file: null,\n fieldMetadataUniversalIdentifier,\n },\n }),\n );\n form.append('map', JSON.stringify({ '0': ['variables.file'] }));\n form.append(\n '0',\n new Blob([fileBuffer as BlobPart], { type: contentType }),\n filename,\n );\n\n const result = await this.executeGraphqlRequestWithOptionalRefresh({\n operation: form,\n headers: {},\n requestInit: {\n method: 'POST',\n },\n });\n\n if (result.errors) {\n throw new GenqlError(result.errors, result.data);\n }\n\n const data = result.data as Record<string, unknown>;\n\n return data.uploadFilesFieldFileByUniversalIdentifier as {\n id: string;\n path: string;\n size: number;\n createdAt: string;\n url: string;\n };\n }\n // __UPLOAD_FILE_END__\n\n private async executeGraphqlRequestWithOptionalRefresh({\n operation,\n headers,\n requestInit,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n }) {\n const firstResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: this.authorizationToken,\n });\n\n if (this.shouldRefreshToken(firstResponse)) {\n const refreshedAccessToken = await this.requestRefreshedAccessToken();\n\n if (refreshedAccessToken) {\n const retryResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: refreshedAccessToken,\n });\n\n return this.assertResponseIsSuccessful(retryResponse);\n }\n }\n\n return this.assertResponseIsSuccessful(firstResponse);\n }\n\n private async executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n token: string | null;\n }): Promise<GraphqlResponse> {\n if (!this.fetchImplementation) {\n throw new Error(\n 'Global `fetch` function is not available, ' +\n 'pass a fetch implementation to the Twenty client',\n );\n }\n\n const resolvedHeaders = await this.resolveHeaders();\n const requestHeaders = new Headers(resolvedHeaders);\n\n if (headers) {\n new Headers(headers).forEach((value, key) =>\n requestHeaders.set(key, value),\n );\n }\n\n if (operation instanceof FormData) {\n requestHeaders.delete('Content-Type');\n } else {\n requestHeaders.set('Content-Type', 'application/json');\n }\n\n if (token) {\n requestHeaders.set('Authorization', `Bearer ${token}`);\n } else {\n requestHeaders.delete('Authorization');\n }\n\n const response = await this.fetchImplementation.call(globalThis, this.url, {\n ...this.requestOptions,\n ...requestInit,\n method: requestInit?.method ?? 'POST',\n headers: requestHeaders,\n body:\n operation instanceof FormData ? operation : JSON.stringify(operation),\n });\n\n const rawBody = await response.text();\n let payload: GraphqlResponsePayload | null = null;\n\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as GraphqlResponsePayload;\n } catch {\n payload = null;\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n payload,\n rawBody,\n };\n }\n\n private async resolveHeaders(): Promise<HeadersInit> {\n if (typeof this.headers === 'function') {\n return (await this.headers()) ?? {};\n }\n\n return this.headers ?? {};\n }\n\n private shouldRefreshToken(response: GraphqlResponse): boolean {\n if (response.status === 401) {\n return true;\n }\n\n return hasAuthenticationErrorInGraphqlPayload(response.payload);\n }\n\n private assertResponseIsSuccessful(response: GraphqlResponse) {\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`${response.statusText}: ${response.rawBody}`);\n }\n\n if (response.payload === null) {\n throw new Error('Invalid JSON response');\n }\n\n return response.payload;\n }\n\n private async requestRefreshedAccessToken(): Promise<string | null> {\n const refreshAccessTokenFunction = (\n globalThis as {\n frontComponentHostCommunicationApi?: {\n requestAccessTokenRefresh?: () => Promise<string>;\n };\n }\n ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;\n\n if (typeof refreshAccessTokenFunction !== 'function') {\n return null;\n }\n\n if (!this.refreshAccessTokenPromise) {\n this.refreshAccessTokenPromise = refreshAccessTokenFunction()\n .then((refreshedAccessToken) => {\n if (\n typeof refreshedAccessToken !== 'string' ||\n refreshedAccessToken.length === 0\n ) {\n return null;\n }\n\n this.setAuthorizationToken(refreshedAccessToken);\n\n return refreshedAccessToken;\n })\n .catch((refreshError: unknown) => {\n console.error('Twenty client: token refresh failed', refreshError);\n\n return null;\n })\n .finally(() => {\n this.refreshAccessTokenPromise = null;\n });\n }\n\n return this.refreshAccessTokenPromise;\n }\n\n private setAuthorizationToken(token: string) {\n this.authorizationToken = token;\n\n const processEnvironment = getProcessEnvironment();\n\n processEnvironment[APP_ACCESS_TOKEN_ENV_KEY] = token;\n }\n}\n";
|
|
578
|
+
let a = i ?? "import type { TwentyClientRunAs } from '../shared/twenty-client-run-as.type';\n\n// Ambient type stubs for the genql-generated code this template gets\n// injected into. They enable full typecheck/lint on this file.\n// __STRIPPED_DURING_INJECTION_START__\ntype QueryGenqlSelection = Record<string, unknown>;\ntype MutationGenqlSelection = Record<string, unknown>;\ntype GraphqlOperation = Record<string, unknown>;\n\ntype ClientOptions = Omit<RequestInit, 'body' | 'headers'> & {\n url?: string;\n headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n fetcher?: (\n operation: GraphqlOperation | GraphqlOperation[],\n ) => Promise<unknown>;\n fetch?: typeof globalThis.fetch;\n batch?: unknown;\n};\n\ntype Client = {\n query: (\n request: QueryGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n mutation: (\n request: MutationGenqlSelection & { __name?: string },\n ) => Promise<unknown>;\n};\n\ndeclare function createClient(options: ClientOptions): Client;\n\ndeclare class GenqlError extends Error {\n constructor(errors: unknown, data: unknown);\n}\n// __STRIPPED_DURING_INJECTION_END__\n\nconst APP_ACCESS_TOKEN_ENV_KEY = 'TWENTY_APP_ACCESS_TOKEN';\nconst APP_APPLICATION_ACCESS_TOKEN_ENV_KEY =\n 'TWENTY_APP_APPLICATION_ACCESS_TOKEN';\nconst API_KEY_ENV_KEY = 'TWENTY_API_KEY';\n\nexport type TwentyGeneratedClientOptions = ClientOptions & {\n runAs?: TwentyClientRunAs;\n};\n\ntype ProcessEnvironment = Record<string, string | undefined>;\n\ntype GraphqlErrorPayloadEntry = {\n message?: string;\n extensions?: { code?: string };\n};\n\ntype GraphqlResponsePayload = {\n data?: Record<string, unknown>;\n errors?: GraphqlErrorPayloadEntry[];\n};\n\ntype GraphqlResponse = {\n status: number;\n statusText: string;\n payload: GraphqlResponsePayload | null;\n rawBody: string;\n};\n\ntype FilesFieldUploadTarget = {\n fileId: string;\n uploadUrl: string;\n contentType: string;\n};\n\ntype FilesFieldUploadedFile = {\n id: string;\n path: string;\n size: number;\n createdAt: string;\n url: string;\n};\n\nconst getProcessEnvironment = (): ProcessEnvironment => {\n const processObject = (\n globalThis as { process?: { env?: ProcessEnvironment } }\n ).process;\n\n return processObject?.env ?? {};\n};\n\nconst getTokenFromAuthorizationHeader = (\n authorizationHeader: string | undefined,\n): string | null => {\n if (typeof authorizationHeader !== 'string') {\n return null;\n }\n\n const trimmedAuthorizationHeader = authorizationHeader.trim();\n\n if (trimmedAuthorizationHeader.length === 0) {\n return null;\n }\n\n if (trimmedAuthorizationHeader === 'Bearer') {\n return null;\n }\n\n if (trimmedAuthorizationHeader.startsWith('Bearer ')) {\n return trimmedAuthorizationHeader.slice('Bearer '.length).trim();\n }\n\n return trimmedAuthorizationHeader;\n};\n\nconst getTokenFromHeaders = (\n headers: HeadersInit | undefined,\n): string | null => {\n if (!headers) {\n return null;\n }\n\n if (headers instanceof Headers) {\n return getTokenFromAuthorizationHeader(\n headers.get('Authorization') ?? undefined,\n );\n }\n\n if (Array.isArray(headers)) {\n const matchedAuthorizationHeader = headers.find(\n ([headerName]) => headerName.toLowerCase() === 'authorization',\n );\n\n return getTokenFromAuthorizationHeader(matchedAuthorizationHeader?.[1]);\n }\n\n const headersRecord = headers as Record<string, string | undefined>;\n\n return getTokenFromAuthorizationHeader(\n headersRecord.Authorization ?? headersRecord.authorization,\n );\n};\n\nconst hasAuthenticationErrorInGraphqlPayload = (\n payload: GraphqlResponsePayload | null,\n): boolean => {\n if (!payload?.errors) {\n return false;\n }\n\n return payload.errors.some((graphqlError) => {\n return (\n graphqlError.extensions?.code === 'UNAUTHENTICATED' ||\n graphqlError.message?.toLowerCase() === 'unauthorized'\n );\n });\n};\n\nconst defaultOptions: TwentyGeneratedClientOptions = {\n url: '__TWENTY_DEFAULT_URL__',\n headers: {\n 'Content-Type': 'application/json',\n },\n};\n\nexport class TwentyGeneratedClient {\n private client: Client;\n private url: string;\n private requestOptions: RequestInit;\n private headers: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);\n private fetchImplementation: typeof globalThis.fetch | null;\n private authorizationToken: string | null;\n private refreshAccessTokenPromise: Promise<string | null> | null = null;\n\n constructor(options?: TwentyGeneratedClientOptions) {\n const merged: TwentyGeneratedClientOptions = {\n ...defaultOptions,\n ...options,\n };\n\n const {\n url,\n headers,\n fetch: customFetchImplementation,\n fetcher: _fetcher,\n batch: _batch,\n runAs,\n ...requestOptions\n } = merged;\n\n this.url = url ?? '';\n this.requestOptions = requestOptions;\n this.headers = headers ?? {};\n this.fetchImplementation =\n customFetchImplementation ?? globalThis.fetch ?? null;\n\n const processEnvironment = getProcessEnvironment();\n const tokenFromHeaders = getTokenFromHeaders(\n typeof headers === 'function' ? undefined : headers,\n );\n\n // Priority: explicit header > the token for the requested access > api key\n // (legacy).\n this.authorizationToken =\n tokenFromHeaders ??\n processEnvironment[\n runAs === 'application'\n ? APP_APPLICATION_ACCESS_TOKEN_ENV_KEY\n : APP_ACCESS_TOKEN_ENV_KEY\n ] ??\n processEnvironment[API_KEY_ENV_KEY] ??\n null;\n\n this.client = createClient({\n ...merged,\n headers: undefined,\n fetcher: async (operation) =>\n this.executeGraphqlRequestWithOptionalRefresh({\n operation,\n }),\n });\n }\n\n query<R extends QueryGenqlSelection>(request: R & { __name?: string }) {\n return this.client.query(request);\n }\n\n mutation<R extends MutationGenqlSelection>(request: R & { __name?: string }) {\n return this.client.mutation(request);\n }\n\n // __UPLOAD_FILE_START__\n async uploadFile({\n fileBuffer,\n filename,\n fieldMetadataUniversalIdentifier,\n }: {\n fileBuffer: Buffer;\n filename: string;\n fieldMetadataUniversalIdentifier: string;\n }): Promise<FilesFieldUploadedFile> {\n const { createFileUpload: uploadTarget } =\n await this.executeMutationOrThrow<{\n createFileUpload: FilesFieldUploadTarget;\n }>({\n query: `mutation CreateFilesFieldFileUpload($filename: String!, $size: Float!, $fieldMetadataUniversalIdentifier: String!) {\n createFileUpload(filename: $filename, size: $size, fileFolder: FilesField, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { fileId uploadUrl contentType }\n }`,\n variables: {\n filename,\n size: fileBuffer.byteLength,\n fieldMetadataUniversalIdentifier,\n },\n });\n\n await this.putFileToUploadTargetOrThrow({ fileBuffer, uploadTarget });\n\n const { completeFileUpload: uploadedFile } =\n await this.executeMutationOrThrow<{\n completeFileUpload: FilesFieldUploadedFile;\n }>({\n query: `mutation CompleteFilesFieldFileUpload($fileId: String!) {\n completeFileUpload(fileId: $fileId) { id path size createdAt url }\n }`,\n variables: { fileId: uploadTarget.fileId },\n });\n\n return uploadedFile;\n }\n\n private async putFileToUploadTargetOrThrow({\n fileBuffer,\n uploadTarget,\n }: {\n fileBuffer: Buffer;\n uploadTarget: FilesFieldUploadTarget;\n }): Promise<void> {\n const fetchImplementation = this.getFetchImplementationOrThrow();\n\n const response = await fetchImplementation.call(\n globalThis,\n uploadTarget.uploadUrl,\n {\n method: 'PUT',\n headers: { 'Content-Type': uploadTarget.contentType },\n body: fileBuffer as BodyInit,\n credentials: 'omit',\n },\n );\n\n if (!response.ok) {\n throw new Error(\n `File upload failed (${response.status} ${response.statusText}): ${await response.text()}`,\n );\n }\n }\n\n private async executeMutationOrThrow<TData>({\n query,\n variables,\n }: {\n query: string;\n variables: Record<string, unknown>;\n }): Promise<TData> {\n const result = await this.executeGraphqlRequestWithOptionalRefresh({\n operation: { query, variables },\n });\n\n if (result.errors) {\n throw new GenqlError(result.errors, result.data);\n }\n\n if (!result.data) {\n throw new Error('Empty GraphQL response');\n }\n\n return result.data as TData;\n }\n // __UPLOAD_FILE_END__\n\n private async executeGraphqlRequestWithOptionalRefresh({\n operation,\n headers,\n requestInit,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n }) {\n const firstResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: this.authorizationToken,\n });\n\n if (this.shouldRefreshToken(firstResponse)) {\n const refreshedAccessToken = await this.requestRefreshedAccessToken();\n\n if (refreshedAccessToken) {\n const retryResponse = await this.executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token: refreshedAccessToken,\n });\n\n return this.assertResponseIsSuccessful(retryResponse);\n }\n }\n\n return this.assertResponseIsSuccessful(firstResponse);\n }\n\n private async executeGraphqlRequest({\n operation,\n headers,\n requestInit,\n token,\n }: {\n operation: GraphqlOperation | GraphqlOperation[] | FormData;\n headers?: HeadersInit;\n requestInit?: RequestInit;\n token: string | null;\n }): Promise<GraphqlResponse> {\n const fetchImplementation = this.getFetchImplementationOrThrow();\n\n const resolvedHeaders = await this.resolveHeaders();\n const requestHeaders = new Headers(resolvedHeaders);\n\n if (headers) {\n new Headers(headers).forEach((value, key) =>\n requestHeaders.set(key, value),\n );\n }\n\n if (operation instanceof FormData) {\n requestHeaders.delete('Content-Type');\n } else {\n requestHeaders.set('Content-Type', 'application/json');\n }\n\n if (token) {\n requestHeaders.set('Authorization', `Bearer ${token}`);\n } else {\n requestHeaders.delete('Authorization');\n }\n\n const response = await fetchImplementation.call(globalThis, this.url, {\n ...this.requestOptions,\n ...requestInit,\n method: requestInit?.method ?? 'POST',\n headers: requestHeaders,\n body:\n operation instanceof FormData ? operation : JSON.stringify(operation),\n });\n\n const rawBody = await response.text();\n let payload: GraphqlResponsePayload | null = null;\n\n if (rawBody.trim().length > 0) {\n try {\n payload = JSON.parse(rawBody) as GraphqlResponsePayload;\n } catch {\n payload = null;\n }\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n payload,\n rawBody,\n };\n }\n\n private getFetchImplementationOrThrow(): typeof globalThis.fetch {\n if (!this.fetchImplementation) {\n throw new Error(\n 'Global `fetch` function is not available, ' +\n 'pass a fetch implementation to the Twenty client',\n );\n }\n\n return this.fetchImplementation;\n }\n\n private async resolveHeaders(): Promise<HeadersInit> {\n if (typeof this.headers === 'function') {\n return (await this.headers()) ?? {};\n }\n\n return this.headers ?? {};\n }\n\n private shouldRefreshToken(response: GraphqlResponse): boolean {\n if (response.status === 401) {\n return true;\n }\n\n return hasAuthenticationErrorInGraphqlPayload(response.payload);\n }\n\n private assertResponseIsSuccessful(response: GraphqlResponse) {\n if (response.status < 200 || response.status >= 300) {\n throw new Error(`${response.statusText}: ${response.rawBody}`);\n }\n\n if (response.payload === null) {\n throw new Error('Invalid JSON response');\n }\n\n return response.payload;\n }\n\n private async requestRefreshedAccessToken(): Promise<string | null> {\n const refreshAccessTokenFunction = (\n globalThis as {\n frontComponentHostCommunicationApi?: {\n requestAccessTokenRefresh?: () => Promise<string>;\n };\n }\n ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;\n\n if (typeof refreshAccessTokenFunction !== 'function') {\n return null;\n }\n\n if (!this.refreshAccessTokenPromise) {\n this.refreshAccessTokenPromise = refreshAccessTokenFunction()\n .then((refreshedAccessToken) => {\n if (\n typeof refreshedAccessToken !== 'string' ||\n refreshedAccessToken.length === 0\n ) {\n return null;\n }\n\n this.setAuthorizationToken(refreshedAccessToken);\n\n return refreshedAccessToken;\n })\n .catch((refreshError: unknown) => {\n console.error('Twenty client: token refresh failed', refreshError);\n\n return null;\n })\n .finally(() => {\n this.refreshAccessTokenPromise = null;\n });\n }\n\n return this.refreshAccessTokenPromise;\n }\n\n private setAuthorizationToken(token: string) {\n this.authorizationToken = token;\n\n const processEnvironment = getProcessEnvironment();\n\n processEnvironment[APP_ACCESS_TOKEN_ENV_KEY] = token;\n }\n}\n";
|
|
579
579
|
await O(r), await k(r), await Z({
|
|
580
580
|
schema: n,
|
|
581
581
|
output: r,
|
|
@@ -31,6 +31,13 @@ import type { TwentyClientRunAs } from '../shared/twenty-client-run-as.type';
|
|
|
31
31
|
export type MetadataApiClientOptions = ClientOptions & {
|
|
32
32
|
runAs?: TwentyClientRunAs;
|
|
33
33
|
};
|
|
34
|
+
type FilesFieldUploadedFile = {
|
|
35
|
+
id: string;
|
|
36
|
+
path: string;
|
|
37
|
+
size: number;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
url: string;
|
|
40
|
+
};
|
|
34
41
|
export declare class MetadataApiClient {
|
|
35
42
|
private client;
|
|
36
43
|
private url;
|
|
@@ -46,15 +53,16 @@ export declare class MetadataApiClient {
|
|
|
46
53
|
mutation<R extends MutationGenqlSelection>(request: R & {
|
|
47
54
|
__name?: string;
|
|
48
55
|
}): Promise<FieldsSelection<Mutation, R>>;
|
|
49
|
-
uploadFile(fileBuffer
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
uploadFile({ fileBuffer, filename, fieldMetadataUniversalIdentifier }: {
|
|
57
|
+
fileBuffer: Buffer;
|
|
58
|
+
filename: string;
|
|
59
|
+
fieldMetadataUniversalIdentifier: string;
|
|
60
|
+
}): Promise<FilesFieldUploadedFile>;
|
|
61
|
+
private putFileToUploadTargetOrThrow;
|
|
62
|
+
private executeMutationOrThrow;
|
|
56
63
|
private executeGraphqlRequestWithOptionalRefresh;
|
|
57
64
|
private executeGraphqlRequest;
|
|
65
|
+
private getFetchImplementationOrThrow;
|
|
58
66
|
private resolveHeaders;
|
|
59
67
|
private shouldRefreshToken;
|
|
60
68
|
private assertResponseIsSuccessful;
|