@quonfig/cli 0.0.16 → 0.0.18
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 +33 -33
- package/dist/commands/migrate.js +47 -1
- package/dist/migrate/local-write.d.ts +7 -1
- package/dist/migrate/local-write.js +54 -6
- package/dist/migrate/migration-report.d.ts +18 -0
- package/dist/migrate/migration-report.js +64 -1
- package/dist/migrate/push-to-cloud.d.ts +13 -2
- package/dist/migrate/push-to-cloud.js +76 -5
- package/dist/migrate/source.d.ts +50 -1
- package/dist/migrate/sources/launch/translate.d.ts +27 -1
- package/dist/migrate/sources/launch/translate.js +123 -6
- package/dist/migrate/sources/launch/types.d.ts +3 -0
- package/dist/migrate/sources/launch/zod-to-json-schema.d.ts +9 -0
- package/dist/migrate/sources/launch/zod-to-json-schema.js +521 -0
- package/dist/migrate/sources/launch.js +52 -7
- package/dist/util/get-client.js +5 -4
- package/dist/util/get-valid-token.d.ts +3 -1
- package/dist/util/get-valid-token.js +28 -3
- package/dist/util/token-storage.js +5 -1
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
|
@@ -6,38 +6,62 @@
|
|
|
6
6
|
* directly as a bearer token and no disk reads/writes or refresh calls
|
|
7
7
|
* are made. This is the non-interactive (CI) path.
|
|
8
8
|
*/
|
|
9
|
+
import { getDomain } from './domain-urls.js';
|
|
9
10
|
import { decodeJWT, refreshAccessToken } from './oauth-client.js';
|
|
10
11
|
import { loadTokens, saveTokens } from './token-storage.js';
|
|
11
|
-
|
|
12
|
+
const noopLog = () => { };
|
|
13
|
+
export async function getValidAccessToken(log = noopLog) {
|
|
12
14
|
const envKey = process.env.QUONFIG_API_KEY;
|
|
13
15
|
if (envKey && envKey.length > 0) {
|
|
14
16
|
if (!envKey.startsWith('qf_uk_')) {
|
|
15
17
|
throw new Error(`QUONFIG_API_KEY must start with "qf_uk_" (got "${envKey.slice(0, 8)}..."). Generate one from the web UI under Settings → API Keys.`);
|
|
16
18
|
}
|
|
19
|
+
log('getValidAccessToken: using QUONFIG_API_KEY (CI path)');
|
|
17
20
|
return envKey;
|
|
18
21
|
}
|
|
19
22
|
const tokens = await loadTokens();
|
|
23
|
+
log('getValidAccessToken: loaded tokens', {
|
|
24
|
+
domain: getDomain(),
|
|
25
|
+
hasAccessToken: Boolean(tokens?.accessToken),
|
|
26
|
+
hasRefreshToken: Boolean(tokens?.refreshToken),
|
|
27
|
+
expiresAt: tokens?.expiresAt,
|
|
28
|
+
});
|
|
20
29
|
if (!tokens?.accessToken) {
|
|
21
30
|
throw new Error('Not authenticated. Please run `qfg login` first.');
|
|
22
31
|
}
|
|
23
32
|
// Check expiry using the JWT's exp claim, falling back to stored expiresAt
|
|
24
33
|
let expired = tokens.expiresAt ? tokens.expiresAt < Date.now() : false;
|
|
34
|
+
let expirySource = 'stored';
|
|
25
35
|
try {
|
|
26
36
|
const payload = decodeJWT(tokens.accessToken);
|
|
27
37
|
if (typeof payload.exp === 'number') {
|
|
28
38
|
expired = payload.exp * 1000 < Date.now();
|
|
39
|
+
expirySource = 'jwt';
|
|
29
40
|
}
|
|
30
41
|
}
|
|
31
42
|
catch {
|
|
32
43
|
/* use stored expiresAt */
|
|
33
44
|
}
|
|
45
|
+
log('getValidAccessToken: expiry check', { expired, expirySource, now: Date.now() });
|
|
34
46
|
if (!expired) {
|
|
35
47
|
return tokens.accessToken;
|
|
36
48
|
}
|
|
37
49
|
if (!tokens.refreshToken) {
|
|
38
|
-
throw new Error('Session expired. Please run `qfg login` to re-authenticate.');
|
|
50
|
+
throw new Error('Session expired (no refresh_token on disk). Please run `qfg login` to re-authenticate.');
|
|
39
51
|
}
|
|
40
|
-
|
|
52
|
+
log('getValidAccessToken: access token expired, calling WorkOS refresh');
|
|
53
|
+
let refreshed;
|
|
54
|
+
try {
|
|
55
|
+
refreshed = await refreshAccessToken(tokens.refreshToken);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
59
|
+
log('getValidAccessToken: refresh FAILED', { detail });
|
|
60
|
+
throw new Error(`Token refresh failed: ${detail}`);
|
|
61
|
+
}
|
|
62
|
+
log('getValidAccessToken: refresh succeeded', {
|
|
63
|
+
gotNewRefreshToken: Boolean(refreshed.refresh_token),
|
|
64
|
+
});
|
|
41
65
|
let expiresAt = Date.now() + 300 * 1000;
|
|
42
66
|
try {
|
|
43
67
|
const payload = decodeJWT(refreshed.access_token);
|
|
@@ -55,5 +79,6 @@ export async function getValidAccessToken() {
|
|
|
55
79
|
refreshToken: refreshed.refresh_token,
|
|
56
80
|
};
|
|
57
81
|
await saveTokens(updated);
|
|
82
|
+
log('getValidAccessToken: refreshed tokens saved', { newExpiresAt: expiresAt });
|
|
58
83
|
return refreshed.access_token;
|
|
59
84
|
}
|
|
@@ -8,7 +8,11 @@ const getTokenFile = (options) => {
|
|
|
8
8
|
const filename = domain === 'quonfig.com' ? 'tokens.json' : `tokens-${domain.replaceAll('.', '-')}.json`;
|
|
9
9
|
return path.join(getQuonfigDir(options), filename);
|
|
10
10
|
};
|
|
11
|
-
const getConfigFile = (options) =>
|
|
11
|
+
const getConfigFile = (options) => {
|
|
12
|
+
const domain = getDomain();
|
|
13
|
+
const filename = domain === 'quonfig.com' ? 'config' : `config-${domain.replaceAll('.', '-')}`;
|
|
14
|
+
return path.join(getQuonfigDir(options), filename);
|
|
15
|
+
};
|
|
12
16
|
/**
|
|
13
17
|
* Find a workspace ID by slug across all saved profiles.
|
|
14
18
|
* Used to resolve QUONFIG_WORKSPACE and --workspace flag values.
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageManager": "yarn@4.11.0+sha512.4e54aeace9141df2f0177c266b05ec50dc044638157dae128c471ba65994ac802122d7ab35bcd9e81641228b7dcf24867d28e750e0bcae8a05277d600008ad54",
|
|
3
3
|
"name": "@quonfig/cli",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.18",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/quonfig/cli/issues"
|
|
7
7
|
},
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"lodash.camelcase": "^4.3.0",
|
|
33
33
|
"mustache": "^4.2.0",
|
|
34
34
|
"node-forge": "^1.4.0",
|
|
35
|
+
"typescript": "^5",
|
|
35
36
|
"zod": "^4.1.12"
|
|
36
37
|
},
|
|
37
38
|
"description": "Quonfig CLI. For arbitrary targeting rules (email, plan, segment, custom property), run `qfg config-schema` then `qfg pull`.",
|
|
@@ -58,8 +59,7 @@
|
|
|
58
59
|
"prettier": "^3.6.2",
|
|
59
60
|
"shx": "^0.3.4",
|
|
60
61
|
"ts-node": "^10.9.1",
|
|
61
|
-
"tsx": "^4.21.0"
|
|
62
|
-
"typescript": "^5"
|
|
62
|
+
"tsx": "^4.21.0"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">=18.0.0"
|