postgresdk 0.15.5 → 0.15.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/dist/cli.js +67 -67
- package/dist/index.js +33 -39
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -284,7 +284,6 @@ const sdk = new SDK({
|
|
|
284
284
|
export default {
|
|
285
285
|
connectionString: "...",
|
|
286
286
|
auth: {
|
|
287
|
-
strategy: "jwt-hs256",
|
|
288
287
|
jwt: {
|
|
289
288
|
services: [
|
|
290
289
|
{ issuer: "my-app", secret: "env:JWT_SECRET" } // Use "env:" prefix!
|
|
@@ -298,7 +297,6 @@ export default {
|
|
|
298
297
|
export default {
|
|
299
298
|
connectionString: "...",
|
|
300
299
|
auth: {
|
|
301
|
-
strategy: "jwt-hs256",
|
|
302
300
|
jwt: {
|
|
303
301
|
services: [
|
|
304
302
|
{ issuer: "web-app", secret: "env:WEB_APP_SECRET" },
|
|
@@ -340,7 +338,6 @@ const token = sign({
|
|
|
340
338
|
export default {
|
|
341
339
|
connectionString: process.env.DATABASE_URL,
|
|
342
340
|
auth: {
|
|
343
|
-
strategy: "jwt-hs256",
|
|
344
341
|
jwt: {
|
|
345
342
|
services: [
|
|
346
343
|
{ issuer: "web-app", secret: "env:WEB_SECRET" },
|
package/dist/cli.js
CHANGED
|
@@ -649,6 +649,31 @@ var init_emit_include_methods = __esm(() => {
|
|
|
649
649
|
init_utils();
|
|
650
650
|
});
|
|
651
651
|
|
|
652
|
+
// src/types.ts
|
|
653
|
+
function getAuthStrategy(auth) {
|
|
654
|
+
if (!auth)
|
|
655
|
+
return "none";
|
|
656
|
+
if (auth.jwt)
|
|
657
|
+
return "jwt-hs256";
|
|
658
|
+
if (auth.apiKeys && auth.apiKeys.length > 0)
|
|
659
|
+
return "api-key";
|
|
660
|
+
return "none";
|
|
661
|
+
}
|
|
662
|
+
function normalizeAuthConfig(input) {
|
|
663
|
+
if (!input)
|
|
664
|
+
return;
|
|
665
|
+
if ("jwt" in input || "apiKeys" in input) {
|
|
666
|
+
return input;
|
|
667
|
+
}
|
|
668
|
+
if ("apiKey" in input && input.apiKey) {
|
|
669
|
+
return {
|
|
670
|
+
apiKeyHeader: input.apiKeyHeader,
|
|
671
|
+
apiKeys: [input.apiKey, ...input.apiKeys || []]
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
652
677
|
// src/emit-sdk-contract.ts
|
|
653
678
|
var exports_emit_sdk_contract = {};
|
|
654
679
|
__export(exports_emit_sdk_contract, {
|
|
@@ -722,7 +747,8 @@ const sdk = new SDK({
|
|
|
722
747
|
}
|
|
723
748
|
function generateSDKAuthExamples(auth) {
|
|
724
749
|
const examples = [];
|
|
725
|
-
|
|
750
|
+
const strategy = getAuthStrategy(auth);
|
|
751
|
+
if (strategy === "none") {
|
|
726
752
|
examples.push({
|
|
727
753
|
strategy: "none",
|
|
728
754
|
description: "No authentication required",
|
|
@@ -731,7 +757,7 @@ function generateSDKAuthExamples(auth) {
|
|
|
731
757
|
});`
|
|
732
758
|
});
|
|
733
759
|
}
|
|
734
|
-
if (
|
|
760
|
+
if (strategy === "api-key") {
|
|
735
761
|
examples.push({
|
|
736
762
|
strategy: "apiKey",
|
|
737
763
|
description: "API Key authentication",
|
|
@@ -744,7 +770,7 @@ function generateSDKAuthExamples(auth) {
|
|
|
744
770
|
});`
|
|
745
771
|
});
|
|
746
772
|
}
|
|
747
|
-
if (
|
|
773
|
+
if (strategy === "jwt-hs256") {
|
|
748
774
|
examples.push({
|
|
749
775
|
strategy: "jwt",
|
|
750
776
|
description: "JWT Bearer token authentication",
|
|
@@ -1637,22 +1663,27 @@ function extractConfigFields(configContent) {
|
|
|
1637
1663
|
isCommented: !!schemaMatch[1]
|
|
1638
1664
|
});
|
|
1639
1665
|
}
|
|
1666
|
+
const outDirMatch = configContent.match(/^\s*(\/\/)?\s*outDir:\s*(.+)/m);
|
|
1640
1667
|
const outServerMatch = configContent.match(/^\s*(\/\/)?\s*outServer:\s*"(.+)"/m);
|
|
1641
|
-
|
|
1668
|
+
const outClientMatch = configContent.match(/^\s*(\/\/)?\s*outClient:\s*"(.+)"/m);
|
|
1669
|
+
if (outDirMatch) {
|
|
1670
|
+
let value = outDirMatch[2]?.trim() || "";
|
|
1671
|
+
value = value.replace(/,\s*$/, "");
|
|
1642
1672
|
fields.push({
|
|
1643
|
-
key: "
|
|
1644
|
-
value
|
|
1645
|
-
description: "Output directory for
|
|
1646
|
-
isCommented: !!
|
|
1673
|
+
key: "outDir",
|
|
1674
|
+
value,
|
|
1675
|
+
description: "Output directory for generated code",
|
|
1676
|
+
isCommented: !!outDirMatch[1]
|
|
1647
1677
|
});
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1678
|
+
} else if (outServerMatch || outClientMatch) {
|
|
1679
|
+
const serverPath = outServerMatch?.[2] || "./api/server";
|
|
1680
|
+
const clientPath = outClientMatch?.[2] || "./api/client";
|
|
1681
|
+
const isCommented = !!(outServerMatch?.[1] && outClientMatch?.[1]);
|
|
1651
1682
|
fields.push({
|
|
1652
|
-
key: "
|
|
1653
|
-
value:
|
|
1654
|
-
description: "Output directory for
|
|
1655
|
-
isCommented
|
|
1683
|
+
key: "outDir",
|
|
1684
|
+
value: `{ server: "${serverPath}", client: "${clientPath}" }`,
|
|
1685
|
+
description: "Output directory for generated code",
|
|
1686
|
+
isCommented
|
|
1656
1687
|
});
|
|
1657
1688
|
}
|
|
1658
1689
|
const softDeleteMatch = configContent.match(/^\s*(\/\/)?\s*softDeleteColumn:\s*(.+),?$/m);
|
|
@@ -1808,18 +1839,19 @@ export default {
|
|
|
1808
1839
|
* @default "public"
|
|
1809
1840
|
*/
|
|
1810
1841
|
${getFieldLine("schema", existingFields, mergeStrategy, '"public"', userChoices)}
|
|
1811
|
-
|
|
1812
|
-
/**
|
|
1813
|
-
* Output directory for server-side code (routes, validators, etc.)
|
|
1814
|
-
* @default "./api/server"
|
|
1815
|
-
*/
|
|
1816
|
-
${getFieldLine("outServer", existingFields, mergeStrategy, '"./api/server"', userChoices)}
|
|
1817
|
-
|
|
1842
|
+
|
|
1818
1843
|
/**
|
|
1819
|
-
* Output directory for
|
|
1820
|
-
*
|
|
1844
|
+
* Output directory for generated code
|
|
1845
|
+
*
|
|
1846
|
+
* Simple usage (same directory for both):
|
|
1847
|
+
* outDir: "./api"
|
|
1848
|
+
*
|
|
1849
|
+
* Separate directories for client and server:
|
|
1850
|
+
* outDir: { client: "./sdk", server: "./api" }
|
|
1851
|
+
*
|
|
1852
|
+
* @default { client: "./api/client", server: "./api/server" }
|
|
1821
1853
|
*/
|
|
1822
|
-
${getFieldLine("
|
|
1854
|
+
${getFieldLine("outDir", existingFields, mergeStrategy, '"./api"', userChoices)}
|
|
1823
1855
|
|
|
1824
1856
|
// ========== ADVANCED OPTIONS ==========
|
|
1825
1857
|
|
|
@@ -1920,7 +1952,10 @@ function getFieldLine(key, existingFields, mergeStrategy, defaultValue, userChoi
|
|
|
1920
1952
|
const shouldUseExisting = mergeStrategy === "keep-existing" && existing && !existing.isCommented || mergeStrategy === "interactive" && userChoices?.get(key) === "keep" && existing && !existing.isCommented;
|
|
1921
1953
|
const shouldUseNew = mergeStrategy === "use-defaults" || mergeStrategy === "interactive" && userChoices?.get(key) === "new";
|
|
1922
1954
|
if (shouldUseExisting && existing) {
|
|
1923
|
-
|
|
1955
|
+
let value = existing.value;
|
|
1956
|
+
if (typeof value === "string" && !value.startsWith('"') && !value.startsWith("{") && !value.startsWith("[")) {
|
|
1957
|
+
value = `"${value}"`;
|
|
1958
|
+
}
|
|
1924
1959
|
return `${key}: ${value},`;
|
|
1925
1960
|
}
|
|
1926
1961
|
if (shouldUseNew) {
|
|
@@ -1950,9 +1985,6 @@ function getDefaultComplexBlock(key) {
|
|
|
1950
1985
|
// },`;
|
|
1951
1986
|
case "auth":
|
|
1952
1987
|
return `// auth: {
|
|
1953
|
-
// // Strategy: "none" | "api-key" | "jwt-hs256"
|
|
1954
|
-
// strategy: "none",
|
|
1955
|
-
//
|
|
1956
1988
|
// // For API Key authentication
|
|
1957
1989
|
// apiKeyHeader: "x-api-key", // Header name for API key
|
|
1958
1990
|
// apiKeys: [ // List of valid API keys
|
|
@@ -1963,8 +1995,8 @@ function getDefaultComplexBlock(key) {
|
|
|
1963
1995
|
// // For JWT (HS256) authentication
|
|
1964
1996
|
// jwt: {
|
|
1965
1997
|
// services: [ // Array of services that can authenticate
|
|
1966
|
-
// { issuer: "web-app", secret:
|
|
1967
|
-
// { issuer: "mobile-app", secret:
|
|
1998
|
+
// { issuer: "web-app", secret: "env:WEB_APP_SECRET" },
|
|
1999
|
+
// { issuer: "mobile-app", secret: "env:MOBILE_SECRET" },
|
|
1968
2000
|
// ],
|
|
1969
2001
|
// audience: "my-api", // Optional: validate 'aud' claim
|
|
1970
2002
|
// }
|
|
@@ -3933,7 +3965,7 @@ export type Where<T> = WhereFieldConditions<T> & {
|
|
|
3933
3965
|
|
|
3934
3966
|
// src/emit-auth.ts
|
|
3935
3967
|
function emitAuth(cfgAuth) {
|
|
3936
|
-
const strategy = cfgAuth
|
|
3968
|
+
const strategy = getAuthStrategy(cfgAuth);
|
|
3937
3969
|
const apiKeyHeader = cfgAuth?.apiKeyHeader ?? "x-api-key";
|
|
3938
3970
|
const apiKeys = cfgAuth?.apiKeys ?? [];
|
|
3939
3971
|
const jwtServices = cfgAuth?.jwt?.services ?? [];
|
|
@@ -5494,38 +5526,6 @@ function generateTestCases(table, sampleData, updateData, hasForeignKeys = false
|
|
|
5494
5526
|
// src/index.ts
|
|
5495
5527
|
init_emit_sdk_contract();
|
|
5496
5528
|
init_utils();
|
|
5497
|
-
|
|
5498
|
-
// src/types.ts
|
|
5499
|
-
function normalizeAuthConfig(input) {
|
|
5500
|
-
if (!input)
|
|
5501
|
-
return;
|
|
5502
|
-
if ("strategy" in input && input.strategy) {
|
|
5503
|
-
return input;
|
|
5504
|
-
}
|
|
5505
|
-
if ("apiKey" in input && input.apiKey) {
|
|
5506
|
-
return {
|
|
5507
|
-
strategy: "api-key",
|
|
5508
|
-
apiKeyHeader: input.apiKeyHeader,
|
|
5509
|
-
apiKeys: [input.apiKey, ...input.apiKeys || []]
|
|
5510
|
-
};
|
|
5511
|
-
}
|
|
5512
|
-
if ("apiKeys" in input && input.apiKeys?.length) {
|
|
5513
|
-
return {
|
|
5514
|
-
strategy: "api-key",
|
|
5515
|
-
apiKeyHeader: input.apiKeyHeader,
|
|
5516
|
-
apiKeys: input.apiKeys
|
|
5517
|
-
};
|
|
5518
|
-
}
|
|
5519
|
-
if ("jwt" in input && input.jwt) {
|
|
5520
|
-
return {
|
|
5521
|
-
strategy: "jwt-hs256",
|
|
5522
|
-
jwt: input.jwt
|
|
5523
|
-
};
|
|
5524
|
-
}
|
|
5525
|
-
return { strategy: "none" };
|
|
5526
|
-
}
|
|
5527
|
-
|
|
5528
|
-
// src/index.ts
|
|
5529
5529
|
async function generate(configPath) {
|
|
5530
5530
|
if (!existsSync(configPath)) {
|
|
5531
5531
|
throw new Error(`Config file not found: ${configPath}
|
|
@@ -5599,7 +5599,7 @@ async function generate(configPath) {
|
|
|
5599
5599
|
content: emitIncludeLoader(graph, model, cfg.includeMethodsDepth || 2, cfg.useJsExtensions)
|
|
5600
5600
|
});
|
|
5601
5601
|
files.push({ path: join(serverDir, "logger.ts"), content: emitLogger() });
|
|
5602
|
-
if (normalizedAuth
|
|
5602
|
+
if (getAuthStrategy(normalizedAuth) !== "none") {
|
|
5603
5603
|
files.push({ path: join(serverDir, "auth.ts"), content: emitAuth(normalizedAuth) });
|
|
5604
5604
|
}
|
|
5605
5605
|
files.push({
|
|
@@ -5623,7 +5623,7 @@ async function generate(configPath) {
|
|
|
5623
5623
|
routeContent = emitHonoRoutes(table, graph, {
|
|
5624
5624
|
softDeleteColumn: cfg.softDeleteColumn || null,
|
|
5625
5625
|
includeMethodsDepth: cfg.includeMethodsDepth || 2,
|
|
5626
|
-
authStrategy: normalizedAuth
|
|
5626
|
+
authStrategy: getAuthStrategy(normalizedAuth),
|
|
5627
5627
|
useJsExtensions: cfg.useJsExtensions,
|
|
5628
5628
|
apiPathPrefix: cfg.apiPathPrefix || "/v1"
|
|
5629
5629
|
});
|
|
@@ -5650,7 +5650,7 @@ async function generate(configPath) {
|
|
|
5650
5650
|
if (serverFramework === "hono") {
|
|
5651
5651
|
files.push({
|
|
5652
5652
|
path: join(serverDir, "router.ts"),
|
|
5653
|
-
content: emitHonoRouter(Object.values(model.tables),
|
|
5653
|
+
content: emitHonoRouter(Object.values(model.tables), getAuthStrategy(normalizedAuth) !== "none", cfg.useJsExtensions)
|
|
5654
5654
|
});
|
|
5655
5655
|
}
|
|
5656
5656
|
const { generateUnifiedContract: generateUnifiedContract2, generateUnifiedContractMarkdown: generateUnifiedContractMarkdown2 } = await Promise.resolve().then(() => (init_emit_sdk_contract(), exports_emit_sdk_contract));
|
package/dist/index.js
CHANGED
|
@@ -648,6 +648,31 @@ var init_emit_include_methods = __esm(() => {
|
|
|
648
648
|
init_utils();
|
|
649
649
|
});
|
|
650
650
|
|
|
651
|
+
// src/types.ts
|
|
652
|
+
function getAuthStrategy(auth) {
|
|
653
|
+
if (!auth)
|
|
654
|
+
return "none";
|
|
655
|
+
if (auth.jwt)
|
|
656
|
+
return "jwt-hs256";
|
|
657
|
+
if (auth.apiKeys && auth.apiKeys.length > 0)
|
|
658
|
+
return "api-key";
|
|
659
|
+
return "none";
|
|
660
|
+
}
|
|
661
|
+
function normalizeAuthConfig(input) {
|
|
662
|
+
if (!input)
|
|
663
|
+
return;
|
|
664
|
+
if ("jwt" in input || "apiKeys" in input) {
|
|
665
|
+
return input;
|
|
666
|
+
}
|
|
667
|
+
if ("apiKey" in input && input.apiKey) {
|
|
668
|
+
return {
|
|
669
|
+
apiKeyHeader: input.apiKeyHeader,
|
|
670
|
+
apiKeys: [input.apiKey, ...input.apiKeys || []]
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
|
|
651
676
|
// src/emit-sdk-contract.ts
|
|
652
677
|
var exports_emit_sdk_contract = {};
|
|
653
678
|
__export(exports_emit_sdk_contract, {
|
|
@@ -721,7 +746,8 @@ const sdk = new SDK({
|
|
|
721
746
|
}
|
|
722
747
|
function generateSDKAuthExamples(auth) {
|
|
723
748
|
const examples = [];
|
|
724
|
-
|
|
749
|
+
const strategy = getAuthStrategy(auth);
|
|
750
|
+
if (strategy === "none") {
|
|
725
751
|
examples.push({
|
|
726
752
|
strategy: "none",
|
|
727
753
|
description: "No authentication required",
|
|
@@ -730,7 +756,7 @@ function generateSDKAuthExamples(auth) {
|
|
|
730
756
|
});`
|
|
731
757
|
});
|
|
732
758
|
}
|
|
733
|
-
if (
|
|
759
|
+
if (strategy === "api-key") {
|
|
734
760
|
examples.push({
|
|
735
761
|
strategy: "apiKey",
|
|
736
762
|
description: "API Key authentication",
|
|
@@ -743,7 +769,7 @@ function generateSDKAuthExamples(auth) {
|
|
|
743
769
|
});`
|
|
744
770
|
});
|
|
745
771
|
}
|
|
746
|
-
if (
|
|
772
|
+
if (strategy === "jwt-hs256") {
|
|
747
773
|
examples.push({
|
|
748
774
|
strategy: "jwt",
|
|
749
775
|
description: "JWT Bearer token authentication",
|
|
@@ -3110,7 +3136,7 @@ export type Where<T> = WhereFieldConditions<T> & {
|
|
|
3110
3136
|
|
|
3111
3137
|
// src/emit-auth.ts
|
|
3112
3138
|
function emitAuth(cfgAuth) {
|
|
3113
|
-
const strategy = cfgAuth
|
|
3139
|
+
const strategy = getAuthStrategy(cfgAuth);
|
|
3114
3140
|
const apiKeyHeader = cfgAuth?.apiKeyHeader ?? "x-api-key";
|
|
3115
3141
|
const apiKeys = cfgAuth?.apiKeys ?? [];
|
|
3116
3142
|
const jwtServices = cfgAuth?.jwt?.services ?? [];
|
|
@@ -4671,38 +4697,6 @@ function generateTestCases(table, sampleData, updateData, hasForeignKeys = false
|
|
|
4671
4697
|
// src/index.ts
|
|
4672
4698
|
init_emit_sdk_contract();
|
|
4673
4699
|
init_utils();
|
|
4674
|
-
|
|
4675
|
-
// src/types.ts
|
|
4676
|
-
function normalizeAuthConfig(input) {
|
|
4677
|
-
if (!input)
|
|
4678
|
-
return;
|
|
4679
|
-
if ("strategy" in input && input.strategy) {
|
|
4680
|
-
return input;
|
|
4681
|
-
}
|
|
4682
|
-
if ("apiKey" in input && input.apiKey) {
|
|
4683
|
-
return {
|
|
4684
|
-
strategy: "api-key",
|
|
4685
|
-
apiKeyHeader: input.apiKeyHeader,
|
|
4686
|
-
apiKeys: [input.apiKey, ...input.apiKeys || []]
|
|
4687
|
-
};
|
|
4688
|
-
}
|
|
4689
|
-
if ("apiKeys" in input && input.apiKeys?.length) {
|
|
4690
|
-
return {
|
|
4691
|
-
strategy: "api-key",
|
|
4692
|
-
apiKeyHeader: input.apiKeyHeader,
|
|
4693
|
-
apiKeys: input.apiKeys
|
|
4694
|
-
};
|
|
4695
|
-
}
|
|
4696
|
-
if ("jwt" in input && input.jwt) {
|
|
4697
|
-
return {
|
|
4698
|
-
strategy: "jwt-hs256",
|
|
4699
|
-
jwt: input.jwt
|
|
4700
|
-
};
|
|
4701
|
-
}
|
|
4702
|
-
return { strategy: "none" };
|
|
4703
|
-
}
|
|
4704
|
-
|
|
4705
|
-
// src/index.ts
|
|
4706
4700
|
async function generate(configPath) {
|
|
4707
4701
|
if (!existsSync(configPath)) {
|
|
4708
4702
|
throw new Error(`Config file not found: ${configPath}
|
|
@@ -4776,7 +4770,7 @@ async function generate(configPath) {
|
|
|
4776
4770
|
content: emitIncludeLoader(graph, model, cfg.includeMethodsDepth || 2, cfg.useJsExtensions)
|
|
4777
4771
|
});
|
|
4778
4772
|
files.push({ path: join(serverDir, "logger.ts"), content: emitLogger() });
|
|
4779
|
-
if (normalizedAuth
|
|
4773
|
+
if (getAuthStrategy(normalizedAuth) !== "none") {
|
|
4780
4774
|
files.push({ path: join(serverDir, "auth.ts"), content: emitAuth(normalizedAuth) });
|
|
4781
4775
|
}
|
|
4782
4776
|
files.push({
|
|
@@ -4800,7 +4794,7 @@ async function generate(configPath) {
|
|
|
4800
4794
|
routeContent = emitHonoRoutes(table, graph, {
|
|
4801
4795
|
softDeleteColumn: cfg.softDeleteColumn || null,
|
|
4802
4796
|
includeMethodsDepth: cfg.includeMethodsDepth || 2,
|
|
4803
|
-
authStrategy: normalizedAuth
|
|
4797
|
+
authStrategy: getAuthStrategy(normalizedAuth),
|
|
4804
4798
|
useJsExtensions: cfg.useJsExtensions,
|
|
4805
4799
|
apiPathPrefix: cfg.apiPathPrefix || "/v1"
|
|
4806
4800
|
});
|
|
@@ -4827,7 +4821,7 @@ async function generate(configPath) {
|
|
|
4827
4821
|
if (serverFramework === "hono") {
|
|
4828
4822
|
files.push({
|
|
4829
4823
|
path: join(serverDir, "router.ts"),
|
|
4830
|
-
content: emitHonoRouter(Object.values(model.tables),
|
|
4824
|
+
content: emitHonoRouter(Object.values(model.tables), getAuthStrategy(normalizedAuth) !== "none", cfg.useJsExtensions)
|
|
4831
4825
|
});
|
|
4832
4826
|
}
|
|
4833
4827
|
const { generateUnifiedContract: generateUnifiedContract2, generateUnifiedContractMarkdown: generateUnifiedContractMarkdown2 } = await Promise.resolve().then(() => (init_emit_sdk_contract(), exports_emit_sdk_contract));
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export interface AuthConfig {
|
|
2
|
-
strategy?: "none" | "api-key" | "jwt-hs256";
|
|
3
2
|
apiKeyHeader?: string;
|
|
4
3
|
apiKeys?: string[];
|
|
5
4
|
jwt?: {
|
|
@@ -10,6 +9,7 @@ export interface AuthConfig {
|
|
|
10
9
|
audience?: string;
|
|
11
10
|
};
|
|
12
11
|
}
|
|
12
|
+
export declare function getAuthStrategy(auth: AuthConfig | undefined): "none" | "api-key" | "jwt-hs256";
|
|
13
13
|
export type AuthConfigInput = AuthConfig | {
|
|
14
14
|
apiKey?: string;
|
|
15
15
|
apiKeys?: string[];
|