avo 3.3.1 → 3.5.0-alpha.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/cli.js +81 -15
- package/package.json +4 -4
package/cli.js
CHANGED
|
@@ -909,6 +909,23 @@ function codegen(json, { schema, sources: targets, warnings, success, errors })
|
|
|
909
909
|
function matchesSource(source, filter) {
|
|
910
910
|
return source.name.toLowerCase() === filter.toLowerCase();
|
|
911
911
|
}
|
|
912
|
+
// Prompt message helpers — exported for testing
|
|
913
|
+
export function buildFolderMessage(source) {
|
|
914
|
+
const examplePath = source.outputDirExample ?? 'src/analytics';
|
|
915
|
+
const folderDescription = 'Generated telemetry code — place it inside your source tree';
|
|
916
|
+
return `${folderDescription}\n(e.g. ${examplePath})`;
|
|
917
|
+
}
|
|
918
|
+
export function buildInterfaceFolderMessage(source) {
|
|
919
|
+
const examplePath = source.outputDirExample ?? 'src/analytics';
|
|
920
|
+
const interfaceFolderDescription = 'Generated interface file — place it inside your source tree';
|
|
921
|
+
return `${interfaceFolderDescription}\n(e.g. ${examplePath})`;
|
|
922
|
+
}
|
|
923
|
+
export function buildFilenameMessage() {
|
|
924
|
+
return "This file is regenerated on every 'avo pull' — do not edit it manually";
|
|
925
|
+
}
|
|
926
|
+
export function buildInterfaceFilenameMessage() {
|
|
927
|
+
return "This file is regenerated on every 'avo pull' — do not edit it manually";
|
|
928
|
+
}
|
|
912
929
|
function selectSource(sourceToAdd, json) {
|
|
913
930
|
wait('Fetching sources');
|
|
914
931
|
return api
|
|
@@ -932,6 +949,14 @@ function selectSource(sourceToAdd, json) {
|
|
|
932
949
|
return 1;
|
|
933
950
|
return 0;
|
|
934
951
|
});
|
|
952
|
+
// Resolve source early when sourceToAdd is provided, so the folder
|
|
953
|
+
// prompt can show a platform-specific example path
|
|
954
|
+
const resolvedSource = sourceToAdd
|
|
955
|
+
? sources.find((s) => matchesSource(s, sourceToAdd))
|
|
956
|
+
: null;
|
|
957
|
+
if (sourceToAdd && !resolvedSource) {
|
|
958
|
+
throw new AvoError(`Source ${sourceToAdd} does not exist`);
|
|
959
|
+
}
|
|
935
960
|
const prompts = [
|
|
936
961
|
{
|
|
937
962
|
type: 'fuzzypath',
|
|
@@ -940,7 +965,8 @@ function selectSource(sourceToAdd, json) {
|
|
|
940
965
|
maybeExcludePath.startsWith('.git'),
|
|
941
966
|
itemType: 'directory',
|
|
942
967
|
rootPath: '.',
|
|
943
|
-
message
|
|
968
|
+
// @ts-ignore — message is a callback to access selected source's outputDirExample
|
|
969
|
+
message: (answers) => buildFolderMessage(answers.source ?? resolvedSource ?? {}),
|
|
944
970
|
default: '.',
|
|
945
971
|
suggestOnly: false,
|
|
946
972
|
depthLimit: 10,
|
|
@@ -954,7 +980,7 @@ function selectSource(sourceToAdd, json) {
|
|
|
954
980
|
prompts.unshift({
|
|
955
981
|
type: 'list',
|
|
956
982
|
name: 'source',
|
|
957
|
-
message: '
|
|
983
|
+
message: 'In Avo, a source represents one platform/language target for codegen.\nSelect a source to set up',
|
|
958
984
|
// @ts-ignore
|
|
959
985
|
choices,
|
|
960
986
|
pageSize: 15,
|
|
@@ -962,7 +988,7 @@ function selectSource(sourceToAdd, json) {
|
|
|
962
988
|
prompts.push({
|
|
963
989
|
type: 'input',
|
|
964
990
|
name: 'filename',
|
|
965
|
-
message:
|
|
991
|
+
message: buildFilenameMessage(),
|
|
966
992
|
// @ts-ignore
|
|
967
993
|
default(answers) {
|
|
968
994
|
return answers.source.filenameHint;
|
|
@@ -970,14 +996,11 @@ function selectSource(sourceToAdd, json) {
|
|
|
970
996
|
});
|
|
971
997
|
}
|
|
972
998
|
else {
|
|
973
|
-
const source =
|
|
974
|
-
if (!source) {
|
|
975
|
-
throw new AvoError(`Source ${sourceToAdd} does not exist`);
|
|
976
|
-
}
|
|
999
|
+
const source = resolvedSource;
|
|
977
1000
|
prompts.push({
|
|
978
1001
|
type: 'input',
|
|
979
1002
|
name: 'filename',
|
|
980
|
-
message:
|
|
1003
|
+
message: buildFilenameMessage(),
|
|
981
1004
|
// @ts-ignore
|
|
982
1005
|
default() {
|
|
983
1006
|
return source.filenameHint;
|
|
@@ -1001,7 +1024,7 @@ function selectSource(sourceToAdd, json) {
|
|
|
1001
1024
|
maybeExcludePath.startsWith('.git'),
|
|
1002
1025
|
itemType: 'directory',
|
|
1003
1026
|
rootPath: '.',
|
|
1004
|
-
message:
|
|
1027
|
+
message: buildInterfaceFolderMessage(answerSource),
|
|
1005
1028
|
default: '.',
|
|
1006
1029
|
suggestOnly: false,
|
|
1007
1030
|
depthLimit: 10,
|
|
@@ -1009,10 +1032,11 @@ function selectSource(sourceToAdd, json) {
|
|
|
1009
1032
|
{
|
|
1010
1033
|
type: 'input',
|
|
1011
1034
|
name: 'interfaceFilename',
|
|
1012
|
-
message: (
|
|
1035
|
+
message: buildInterfaceFilenameMessage(),
|
|
1013
1036
|
// @ts-ignore
|
|
1014
1037
|
default() {
|
|
1015
|
-
return answerSource.
|
|
1038
|
+
return (answerSource.interfaceFilenameHint ??
|
|
1039
|
+
answerSource.filenameHint);
|
|
1016
1040
|
},
|
|
1017
1041
|
},
|
|
1018
1042
|
]
|
|
@@ -1434,11 +1458,44 @@ function _respondWithRedirect(req, res, Location) {
|
|
|
1434
1458
|
resolve();
|
|
1435
1459
|
});
|
|
1436
1460
|
}
|
|
1461
|
+
function _extractAuthorizationCode(codeOrUrl) {
|
|
1462
|
+
const input = codeOrUrl.trim();
|
|
1463
|
+
if (!input) {
|
|
1464
|
+
return input;
|
|
1465
|
+
}
|
|
1466
|
+
try {
|
|
1467
|
+
const parsedUrl = new URL(input);
|
|
1468
|
+
const code = parsedUrl.searchParams.get('code');
|
|
1469
|
+
if (code) {
|
|
1470
|
+
return code.trim();
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
catch {
|
|
1474
|
+
// Not a full URL, fall back to parsing possible query-like input.
|
|
1475
|
+
}
|
|
1476
|
+
const query = input.includes('?')
|
|
1477
|
+
? input.split('?').slice(1).join('?')
|
|
1478
|
+
: input;
|
|
1479
|
+
const code = new URLSearchParams(query).get('code');
|
|
1480
|
+
return code ? code.trim() : input;
|
|
1481
|
+
}
|
|
1437
1482
|
function _loginWithoutLocalhost() {
|
|
1438
1483
|
const callbackUrl = _getCallbackUrl();
|
|
1439
1484
|
const authUrl = _getLoginUrl(callbackUrl);
|
|
1440
1485
|
report.info(`Visit this URL on any device to login: ${new URL(authUrl)}`);
|
|
1441
|
-
|
|
1486
|
+
open(authUrl);
|
|
1487
|
+
return inquirer
|
|
1488
|
+
.prompt([
|
|
1489
|
+
{
|
|
1490
|
+
type: 'input',
|
|
1491
|
+
name: 'codeOrUrl',
|
|
1492
|
+
message: 'Paste full redirect URL or code (value after code=):',
|
|
1493
|
+
},
|
|
1494
|
+
])
|
|
1495
|
+
.then((answers) => _getTokensFromAuthorizationCode(_extractAuthorizationCode(answers.codeOrUrl), callbackUrl).then((tokens) => ({
|
|
1496
|
+
user: jwt.decode(tokens.idToken),
|
|
1497
|
+
tokens,
|
|
1498
|
+
})));
|
|
1442
1499
|
}
|
|
1443
1500
|
function _loginWithLocalhost(port) {
|
|
1444
1501
|
return new Promise((resolve, reject) => {
|
|
@@ -1476,7 +1533,10 @@ function _loginWithLocalhost(port) {
|
|
|
1476
1533
|
});
|
|
1477
1534
|
});
|
|
1478
1535
|
}
|
|
1479
|
-
function login() {
|
|
1536
|
+
function login(forceManual = false) {
|
|
1537
|
+
if (forceManual) {
|
|
1538
|
+
return _loginWithoutLocalhost();
|
|
1539
|
+
}
|
|
1480
1540
|
return _getPort().then(_loginWithLocalhost, _loginWithoutLocalhost);
|
|
1481
1541
|
}
|
|
1482
1542
|
function logout(refreshToken) {
|
|
@@ -2044,14 +2104,20 @@ if (isMainModule) {
|
|
|
2044
2104
|
.command({
|
|
2045
2105
|
command: 'login',
|
|
2046
2106
|
describe: 'Log into the Avo platform',
|
|
2047
|
-
|
|
2107
|
+
builder: (yargs) => yargs.option('force-manual', {
|
|
2108
|
+
alias: 'm',
|
|
2109
|
+
describe: 'Force manual login (copy-paste code)',
|
|
2110
|
+
type: 'boolean',
|
|
2111
|
+
default: false,
|
|
2112
|
+
}),
|
|
2113
|
+
handler: (argv) => {
|
|
2048
2114
|
const command = () => {
|
|
2049
2115
|
const user = conf.get('user');
|
|
2050
2116
|
if (user) {
|
|
2051
2117
|
report.info(`Already logged in as ${email(user.email)}`);
|
|
2052
2118
|
return;
|
|
2053
2119
|
}
|
|
2054
|
-
login()
|
|
2120
|
+
login(argv.forceManual)
|
|
2055
2121
|
.then((result) => {
|
|
2056
2122
|
conf.set('user', result.user);
|
|
2057
2123
|
conf.set('tokens', result.tokens);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avo",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The command-line interface for Avo",
|
|
6
6
|
"author": "Avo (https://www.avo.app)",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"got": "^12.1.0",
|
|
38
38
|
"http-shutdown": "^1.2.0",
|
|
39
39
|
"ignore-walk": "^5.0.1",
|
|
40
|
-
"inquirer": "
|
|
40
|
+
"inquirer": "8.2.6",
|
|
41
41
|
"inquirer-fuzzy-path": "^2.3.0",
|
|
42
42
|
"jsonwebtoken": "^9.0.3",
|
|
43
43
|
"load-json-file": "^7.0.1",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@types/ignore-walk": "^4.0.0",
|
|
60
60
|
"@types/jest": "^29.5.14",
|
|
61
61
|
"@types/minimatch": "^5.1.2",
|
|
62
|
-
"@types/node": "^
|
|
62
|
+
"@types/node": "^25.3.0",
|
|
63
63
|
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
|
64
64
|
"@typescript-eslint/parser": "^5.30.5",
|
|
65
65
|
"eslint": "^7.32.0 || ^8.2.0",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"eslint-config-prettier": "^10.0.1",
|
|
68
68
|
"eslint-plugin-import": "^2.25.2",
|
|
69
69
|
"jest": "^29.7.0",
|
|
70
|
-
"prettier": "3.
|
|
70
|
+
"prettier": "3.8.1",
|
|
71
71
|
"ts-jest": "^29.4.5",
|
|
72
72
|
"typescript": "^5.0.2"
|
|
73
73
|
},
|