@ar.io/sdk 3.19.0-alpha.1 → 3.19.0-alpha.11
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 +155 -7
- package/bundles/web.bundle.min.js +88 -72
- package/lib/cjs/cli/cli.js +14 -1
- package/lib/cjs/cli/commands/antCommands.js +82 -16
- package/lib/cjs/cli/options.js +36 -1
- package/lib/cjs/cli/utils.js +25 -11
- package/lib/cjs/common/ant.js +452 -12
- package/lib/cjs/common/io.js +2 -2
- package/lib/cjs/constants.js +2 -1
- package/lib/cjs/types/ant.js +18 -0
- package/lib/cjs/utils/ant.js +4 -0
- package/lib/cjs/utils/ao.js +3 -1
- package/lib/cjs/utils/processes.js +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/esm/cli/cli.js +16 -3
- package/lib/esm/cli/commands/antCommands.js +81 -17
- package/lib/esm/cli/options.js +35 -0
- package/lib/esm/cli/utils.js +24 -11
- package/lib/esm/common/ant.js +453 -13
- package/lib/esm/common/io.js +2 -2
- package/lib/esm/constants.js +1 -0
- package/lib/esm/types/ant.js +18 -0
- package/lib/esm/utils/ant.js +4 -0
- package/lib/esm/utils/ao.js +3 -1
- package/lib/esm/utils/processes.js +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/types/cli/commands/antCommands.d.ts +12 -0
- package/lib/types/cli/options.d.ts +25 -0
- package/lib/types/cli/types.d.ts +1 -0
- package/lib/types/cli/utils.d.ts +15 -2
- package/lib/types/common/ant.d.ts +167 -6
- package/lib/types/common/io.d.ts +1 -1
- package/lib/types/constants.d.ts +1 -0
- package/lib/types/types/ant.d.ts +131 -9
- package/lib/types/types/common.d.ts +31 -0
- package/lib/types/utils/ant.d.ts +4 -0
- package/lib/types/utils/ao.d.ts +2 -1
- package/lib/types/utils/processes.d.ts +1 -1
- package/lib/types/version.d.ts +1 -1
- package/package.json +3 -2
package/lib/cjs/cli/cli.js
CHANGED
|
@@ -536,6 +536,7 @@ const utils_js_1 = require("./utils.js");
|
|
|
536
536
|
state,
|
|
537
537
|
signer: (0, utils_js_1.requiredAoSignerFromOptions)(options),
|
|
538
538
|
logger: (0, utils_js_1.getLoggerFromOptions)(options),
|
|
539
|
+
...(options.module !== undefined ? { module: options.module } : {}),
|
|
539
540
|
});
|
|
540
541
|
return {
|
|
541
542
|
processId: antProcessId,
|
|
@@ -632,7 +633,19 @@ const utils_js_1 = require("./utils.js");
|
|
|
632
633
|
name: 'set-ant-undername',
|
|
633
634
|
description: 'Set an undername of an ANT process',
|
|
634
635
|
options: options_js_1.setAntUndernameOptions,
|
|
635
|
-
action: antCommands_js_1.
|
|
636
|
+
action: antCommands_js_1.setAntUndernameCLICommand,
|
|
637
|
+
});
|
|
638
|
+
(0, utils_js_1.makeCommand)({
|
|
639
|
+
name: 'transfer-record',
|
|
640
|
+
description: 'Transfer ownership of a specific record (undername) to another address',
|
|
641
|
+
options: options_js_1.transferRecordOwnershipOptions,
|
|
642
|
+
action: antCommands_js_1.transferRecordOwnershipCLICommand,
|
|
643
|
+
});
|
|
644
|
+
(0, utils_js_1.makeCommand)({
|
|
645
|
+
name: 'upgrade-ant',
|
|
646
|
+
description: 'Upgrade an ANT by forking it to the latest version and reassigning names',
|
|
647
|
+
options: options_js_1.upgradeAntOptions,
|
|
648
|
+
action: antCommands_js_1.upgradeAntCLICommand,
|
|
636
649
|
});
|
|
637
650
|
(0, utils_js_1.makeCommand)({
|
|
638
651
|
name: 'set-ant-ticker',
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.setAntRecordCLICommand = setAntRecordCLICommand;
|
|
4
4
|
exports.setAntBaseNameCLICommand = setAntBaseNameCLICommand;
|
|
5
5
|
exports.setAntUndernameCLICommand = setAntUndernameCLICommand;
|
|
6
|
+
exports.transferRecordOwnershipCLICommand = transferRecordOwnershipCLICommand;
|
|
7
|
+
exports.upgradeAntCLICommand = upgradeAntCLICommand;
|
|
6
8
|
const utils_js_1 = require("../utils.js");
|
|
7
9
|
/** @deprecated -- use set-ant-base-name and set-ant-undername */
|
|
8
10
|
async function setAntRecordCLICommand(o) {
|
|
@@ -10,38 +12,102 @@ async function setAntRecordCLICommand(o) {
|
|
|
10
12
|
const undername = (0, utils_js_1.requiredStringFromOptions)(o, 'undername');
|
|
11
13
|
const transactionId = (0, utils_js_1.requiredStringFromOptions)(o, 'transactionId');
|
|
12
14
|
const writeAnt = (0, utils_js_1.writeANTFromOptions)(o);
|
|
13
|
-
|
|
14
|
-
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set this record on the ANT process ${writeAnt.processId}?\n${JSON.stringify({ undername, transactionId, ttlSeconds }, null, 2)}`, o);
|
|
15
|
-
}
|
|
16
|
-
return (0, utils_js_1.writeANTFromOptions)(o).setRecord({
|
|
15
|
+
const recordParams = {
|
|
17
16
|
undername,
|
|
18
17
|
transactionId,
|
|
19
18
|
ttlSeconds,
|
|
20
|
-
|
|
19
|
+
...(0, utils_js_1.antRecordMetadataFromOptions)(o),
|
|
20
|
+
};
|
|
21
|
+
if (!o.skipConfirmation) {
|
|
22
|
+
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set this record on the ANT process ${writeAnt.processId}?\n${JSON.stringify(recordParams, null, 2)}`, o);
|
|
23
|
+
}
|
|
24
|
+
return (0, utils_js_1.writeANTFromOptions)(o).setRecord(recordParams, (0, utils_js_1.customTagsFromOptions)(o));
|
|
21
25
|
}
|
|
22
26
|
async function setAntBaseNameCLICommand(o) {
|
|
23
27
|
const ttlSeconds = +(o.ttlSeconds ?? utils_js_1.defaultTtlSecondsCLI);
|
|
24
28
|
const transactionId = (0, utils_js_1.requiredStringFromOptions)(o, 'transactionId');
|
|
29
|
+
const params = {
|
|
30
|
+
transactionId,
|
|
31
|
+
ttlSeconds,
|
|
32
|
+
...(0, utils_js_1.antRecordMetadataFromOptions)(o),
|
|
33
|
+
};
|
|
25
34
|
const writeAnt = (0, utils_js_1.writeANTFromOptions)(o);
|
|
26
35
|
if (!o.skipConfirmation) {
|
|
27
|
-
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set this base name on the ANT process ${writeAnt.processId}?\n${JSON.stringify(
|
|
36
|
+
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set this base name on the ANT process ${writeAnt.processId}?\n${JSON.stringify(params, null, 2)}`, o);
|
|
28
37
|
}
|
|
29
|
-
return (0, utils_js_1.writeANTFromOptions)(o).setBaseNameRecord(
|
|
30
|
-
transactionId,
|
|
31
|
-
ttlSeconds,
|
|
32
|
-
}, (0, utils_js_1.customTagsFromOptions)(o));
|
|
38
|
+
return (0, utils_js_1.writeANTFromOptions)(o).setBaseNameRecord(params, (0, utils_js_1.customTagsFromOptions)(o));
|
|
33
39
|
}
|
|
34
40
|
async function setAntUndernameCLICommand(o) {
|
|
35
41
|
const ttlSeconds = +(o.ttlSeconds ?? utils_js_1.defaultTtlSecondsCLI);
|
|
36
42
|
const undername = (0, utils_js_1.requiredStringFromOptions)(o, 'undername');
|
|
37
43
|
const transactionId = (0, utils_js_1.requiredStringFromOptions)(o, 'transactionId');
|
|
38
|
-
const
|
|
39
|
-
if (!o.skipConfirmation) {
|
|
40
|
-
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set this undername on the ANT process ${writeAnt.processId}?\n${JSON.stringify({ undername, transactionId, ttlSeconds }, null, 2)}`, o);
|
|
41
|
-
}
|
|
42
|
-
return (0, utils_js_1.writeANTFromOptions)(o).setUndernameRecord({
|
|
44
|
+
const params = {
|
|
43
45
|
undername,
|
|
44
46
|
transactionId,
|
|
45
47
|
ttlSeconds,
|
|
46
|
-
|
|
48
|
+
...(0, utils_js_1.antRecordMetadataFromOptions)(o),
|
|
49
|
+
};
|
|
50
|
+
const writeAnt = (0, utils_js_1.writeANTFromOptions)(o);
|
|
51
|
+
if (!o.skipConfirmation) {
|
|
52
|
+
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to set this undername on the ANT process ${writeAnt.processId}?\n${JSON.stringify(params, null, 2)}`, o);
|
|
53
|
+
}
|
|
54
|
+
return (0, utils_js_1.writeANTFromOptions)(o).setUndernameRecord(params, (0, utils_js_1.customTagsFromOptions)(o));
|
|
55
|
+
}
|
|
56
|
+
async function transferRecordOwnershipCLICommand(o) {
|
|
57
|
+
const undername = (0, utils_js_1.requiredStringFromOptions)(o, 'undername');
|
|
58
|
+
const recipient = (0, utils_js_1.requiredStringFromOptions)(o, 'recipient');
|
|
59
|
+
const writeAnt = (0, utils_js_1.writeANTFromOptions)(o);
|
|
60
|
+
if (!o.skipConfirmation) {
|
|
61
|
+
await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to transfer ownership of "${undername}" to "${recipient}" on ANT process ${writeAnt.processId}?\n${JSON.stringify({ undername, recipient }, null, 2)}`, o);
|
|
62
|
+
}
|
|
63
|
+
return (0, utils_js_1.writeANTFromOptions)(o).transferRecord({ undername, recipient }, (0, utils_js_1.customTagsFromOptions)(o));
|
|
64
|
+
}
|
|
65
|
+
async function upgradeAntCLICommand(o) {
|
|
66
|
+
const writeAnt = (0, utils_js_1.writeANTFromOptions)(o);
|
|
67
|
+
const arioProcessId = (0, utils_js_1.arioProcessIdFromOptions)(o);
|
|
68
|
+
const ario = (0, utils_js_1.readARIOFromOptions)(o);
|
|
69
|
+
const reassignAffiliatedNames = (0, utils_js_1.booleanFromOptions)(o, 'reassignAffiliatedNames');
|
|
70
|
+
const names = (0, utils_js_1.stringArrayFromOptions)(o, 'names') || [];
|
|
71
|
+
if (reassignAffiliatedNames) {
|
|
72
|
+
// Fetch all ArNS records that point to this ANT process
|
|
73
|
+
const allRecords = await ario.getArNSRecords({
|
|
74
|
+
filters: {
|
|
75
|
+
processId: writeAnt.processId,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
// Filter records that belong to this ANT
|
|
79
|
+
const affiliatedNames = allRecords.items.map((record) => record.name);
|
|
80
|
+
names.push(...affiliatedNames);
|
|
81
|
+
}
|
|
82
|
+
if (names.length === 0) {
|
|
83
|
+
throw new Error('No names to reassign');
|
|
84
|
+
}
|
|
85
|
+
if (!o.skipConfirmation) {
|
|
86
|
+
await (0, utils_js_1.assertConfirmationPrompt)(`Upgrade all names affiliated with this ANT on ARIO process?\n` +
|
|
87
|
+
`ARIO Process ID: ${arioProcessId}\n` +
|
|
88
|
+
`ANT Process ID: ${writeAnt.processId}\n` +
|
|
89
|
+
`Names that will be reassigned (${names.length}): ${names.join(', ')}`, o);
|
|
90
|
+
}
|
|
91
|
+
const result = reassignAffiliatedNames
|
|
92
|
+
? await (0, utils_js_1.writeANTFromOptions)(o).upgrade({
|
|
93
|
+
reassignAffiliatedNames,
|
|
94
|
+
arioProcessId,
|
|
95
|
+
})
|
|
96
|
+
: await (0, utils_js_1.writeANTFromOptions)(o).upgrade({
|
|
97
|
+
names,
|
|
98
|
+
arioProcessId,
|
|
99
|
+
});
|
|
100
|
+
// Serialize error objects for JSON compatibility
|
|
101
|
+
const serializedFailedReassignedNames = {};
|
|
102
|
+
for (const [name, failure] of Object.entries(result.failedReassignedNames)) {
|
|
103
|
+
serializedFailedReassignedNames[name] = {
|
|
104
|
+
id: failure.id,
|
|
105
|
+
error: failure.error.message,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
forkedProcessId: result.forkedProcessId,
|
|
110
|
+
reassignedNames: result.reassignedNames,
|
|
111
|
+
failedReassignedNames: serializedFailedReassignedNames,
|
|
112
|
+
};
|
|
47
113
|
}
|
package/lib/cjs/cli/options.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.setAntUndernameOptions = exports.setAntBaseNameOptions = exports.antStateOptions = exports.buyRecordOptions = exports.joinNetworkOptions = exports.updateGatewaySettingsOptions = exports.decreaseDelegateStakeOptions = exports.delegateStakeOptions = exports.redelegateStakeOptions = exports.operatorStakeOptions = exports.vaultedTransferOptions = exports.transferOptions = exports.tokenCostOptions = exports.getVaultOptions = exports.paginationAddressOptions = exports.paginationOptions = exports.nameWriteOptions = exports.addressAndVaultIdOptions = exports.epochOptions = exports.arnsPurchaseOptions = exports.writeActionOptions = exports.globalOptions = exports.walletOptions = exports.optionMap = void 0;
|
|
18
|
+
exports.transferRecordOwnershipOptions = exports.upgradeAntOptions = exports.setAntUndernameOptions = exports.setAntBaseNameOptions = exports.antStateOptions = exports.buyRecordOptions = exports.joinNetworkOptions = exports.updateGatewaySettingsOptions = exports.decreaseDelegateStakeOptions = exports.delegateStakeOptions = exports.redelegateStakeOptions = exports.operatorStakeOptions = exports.vaultedTransferOptions = exports.transferOptions = exports.tokenCostOptions = exports.getVaultOptions = exports.paginationAddressOptions = exports.paginationOptions = exports.nameWriteOptions = exports.addressAndVaultIdOptions = exports.epochOptions = exports.arnsPurchaseOptions = exports.writeActionOptions = exports.globalOptions = exports.walletOptions = exports.optionMap = void 0;
|
|
19
19
|
exports.optionMap = {
|
|
20
20
|
walletFile: {
|
|
21
21
|
alias: '-w, --wallet-file <walletFilePath>',
|
|
@@ -254,6 +254,14 @@ exports.optionMap = {
|
|
|
254
254
|
description: 'The keywords for the ANT',
|
|
255
255
|
type: 'array',
|
|
256
256
|
},
|
|
257
|
+
owner: {
|
|
258
|
+
alias: '--owner <owner>',
|
|
259
|
+
description: 'The owner address for the record',
|
|
260
|
+
},
|
|
261
|
+
displayName: {
|
|
262
|
+
alias: '--display-name <displayName>',
|
|
263
|
+
description: 'The display name for the record',
|
|
264
|
+
},
|
|
257
265
|
names: {
|
|
258
266
|
alias: '--names <names...>',
|
|
259
267
|
description: 'The names to interact with',
|
|
@@ -289,6 +297,10 @@ exports.optionMap = {
|
|
|
289
297
|
alias: '--logo <logo>',
|
|
290
298
|
description: 'The ANT logo',
|
|
291
299
|
},
|
|
300
|
+
module: {
|
|
301
|
+
alias: '--module <module>',
|
|
302
|
+
description: 'The module ID to use for spawning the ANT process',
|
|
303
|
+
},
|
|
292
304
|
token: {
|
|
293
305
|
alias: '-t, --token <type>',
|
|
294
306
|
description: 'Crypto token type for wallet or action',
|
|
@@ -303,6 +315,11 @@ exports.optionMap = {
|
|
|
303
315
|
alias: '--referrer <referrer>',
|
|
304
316
|
description: 'The referrer for ArNS purchase tracking',
|
|
305
317
|
},
|
|
318
|
+
reassignAffiliatedNames: {
|
|
319
|
+
alias: '--reassign-affiliated-names',
|
|
320
|
+
description: 'Reassign all affiliated names to the new process',
|
|
321
|
+
type: 'boolean',
|
|
322
|
+
},
|
|
306
323
|
};
|
|
307
324
|
exports.walletOptions = [
|
|
308
325
|
exports.optionMap.walletFile,
|
|
@@ -411,14 +428,32 @@ exports.antStateOptions = [
|
|
|
411
428
|
exports.optionMap.controllers,
|
|
412
429
|
exports.optionMap.ttlSeconds,
|
|
413
430
|
exports.optionMap.logo,
|
|
431
|
+
exports.optionMap.module,
|
|
414
432
|
];
|
|
415
433
|
exports.setAntBaseNameOptions = [
|
|
416
434
|
exports.optionMap.processId,
|
|
417
435
|
exports.optionMap.transactionId,
|
|
418
436
|
exports.optionMap.ttlSeconds,
|
|
437
|
+
exports.optionMap.owner,
|
|
438
|
+
exports.optionMap.displayName,
|
|
439
|
+
exports.optionMap.logo,
|
|
440
|
+
exports.optionMap.description,
|
|
441
|
+
exports.optionMap.keywords,
|
|
419
442
|
...exports.writeActionOptions,
|
|
420
443
|
];
|
|
421
444
|
exports.setAntUndernameOptions = [
|
|
422
445
|
...exports.setAntBaseNameOptions,
|
|
423
446
|
exports.optionMap.undername,
|
|
424
447
|
];
|
|
448
|
+
exports.upgradeAntOptions = [
|
|
449
|
+
exports.optionMap.processId,
|
|
450
|
+
exports.optionMap.names,
|
|
451
|
+
exports.optionMap.reassignAffiliatedNames,
|
|
452
|
+
...exports.writeActionOptions,
|
|
453
|
+
];
|
|
454
|
+
exports.transferRecordOwnershipOptions = [
|
|
455
|
+
exports.optionMap.processId,
|
|
456
|
+
exports.optionMap.undername,
|
|
457
|
+
exports.optionMap.recipient,
|
|
458
|
+
...exports.writeActionOptions,
|
|
459
|
+
];
|
package/lib/cjs/cli/utils.js
CHANGED
|
@@ -9,11 +9,11 @@ exports.runCommand = runCommand;
|
|
|
9
9
|
exports.applyOptions = applyOptions;
|
|
10
10
|
exports.makeCommand = makeCommand;
|
|
11
11
|
exports.arioProcessIdFromOptions = arioProcessIdFromOptions;
|
|
12
|
+
exports.antRegistryIdFromOptions = antRegistryIdFromOptions;
|
|
12
13
|
exports.requiredJwkFromOptions = requiredJwkFromOptions;
|
|
13
14
|
exports.jwkToAddress = jwkToAddress;
|
|
14
15
|
exports.getLoggerFromOptions = getLoggerFromOptions;
|
|
15
16
|
exports.readARIOFromOptions = readARIOFromOptions;
|
|
16
|
-
exports.ANTRegistryProcessFromOptions = ANTRegistryProcessFromOptions;
|
|
17
17
|
exports.readANTRegistryFromOptions = readANTRegistryFromOptions;
|
|
18
18
|
exports.contractSignerFromOptions = contractSignerFromOptions;
|
|
19
19
|
exports.requiredContractSignerFromOptions = requiredContractSignerFromOptions;
|
|
@@ -50,6 +50,7 @@ exports.getTokenCostParamsFromOptions = getTokenCostParamsFromOptions;
|
|
|
50
50
|
exports.fundFromFromOptions = fundFromFromOptions;
|
|
51
51
|
exports.referrerFromOptions = referrerFromOptions;
|
|
52
52
|
exports.assertLockLengthInRange = assertLockLengthInRange;
|
|
53
|
+
exports.antRecordMetadataFromOptions = antRecordMetadataFromOptions;
|
|
53
54
|
/**
|
|
54
55
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
55
56
|
*
|
|
@@ -130,6 +131,15 @@ function arioProcessIdFromOptions({ arioProcessId, devnet, testnet, }) {
|
|
|
130
131
|
}
|
|
131
132
|
return index_js_1.ARIO_MAINNET_PROCESS_ID;
|
|
132
133
|
}
|
|
134
|
+
function antRegistryIdFromOptions({ antRegistryProcessId, testnet, }) {
|
|
135
|
+
if (antRegistryProcessId !== undefined) {
|
|
136
|
+
return antRegistryProcessId;
|
|
137
|
+
}
|
|
138
|
+
if (testnet) {
|
|
139
|
+
return index_js_1.ANT_REGISTRY_TESTNET_ID;
|
|
140
|
+
}
|
|
141
|
+
return index_js_1.ANT_REGISTRY_ID;
|
|
142
|
+
}
|
|
133
143
|
function walletFromOptions({ privateKey, walletFile, }) {
|
|
134
144
|
if (privateKey !== undefined) {
|
|
135
145
|
return JSON.parse(privateKey);
|
|
@@ -177,18 +187,9 @@ function readARIOFromOptions(options) {
|
|
|
177
187
|
paymentUrl: options.paymentUrl,
|
|
178
188
|
});
|
|
179
189
|
}
|
|
180
|
-
function ANTRegistryProcessFromOptions(options) {
|
|
181
|
-
return new index_js_1.AOProcess({
|
|
182
|
-
processId: options.antRegistryProcessId ?? index_js_1.ANT_REGISTRY_ID,
|
|
183
|
-
ao: (0, aoconnect_1.connect)({
|
|
184
|
-
MODE: 'legacy',
|
|
185
|
-
CU_URL: options.cuUrl,
|
|
186
|
-
}),
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
190
|
function readANTRegistryFromOptions(options) {
|
|
190
191
|
return index_js_1.ANTRegistry.init({
|
|
191
|
-
process:
|
|
192
|
+
process: aoProcessFromOptions(options),
|
|
192
193
|
hyperbeamUrl: options.hyperbeamUrl,
|
|
193
194
|
});
|
|
194
195
|
}
|
|
@@ -559,3 +560,16 @@ function assertLockLengthInRange(lockLengthMs, assertMin = true) {
|
|
|
559
560
|
throw new Error(`Lock length must be at least 14 days (1209600000 ms). Provided lock length: ${lockLengthMs} ms`);
|
|
560
561
|
}
|
|
561
562
|
}
|
|
563
|
+
function antRecordMetadataFromOptions(options) {
|
|
564
|
+
return {
|
|
565
|
+
...(options.owner != null &&
|
|
566
|
+
options.owner !== '' && { owner: options.owner }),
|
|
567
|
+
...(options.displayName != null &&
|
|
568
|
+
options.displayName !== '' && { displayName: options.displayName }),
|
|
569
|
+
...(options.logo != null && options.logo !== '' && { logo: options.logo }),
|
|
570
|
+
...(options.description != null &&
|
|
571
|
+
options.description !== '' && { description: options.description }),
|
|
572
|
+
...(options.keywords != null &&
|
|
573
|
+
options.keywords.length > 0 && { keywords: options.keywords }),
|
|
574
|
+
};
|
|
575
|
+
}
|