lh-ops 0.1.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/README.md +93 -0
- package/bin/lh-ops +2 -0
- package/dist/commands/audit.js +66 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/cache-coverage.js +54 -0
- package/dist/commands/cache-coverage.js.map +1 -0
- package/dist/commands/export.js +138 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/login.js +50 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/member.js +25 -0
- package/dist/commands/member.js.map +1 -0
- package/dist/commands/models.js +23 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/org-list.js +45 -0
- package/dist/commands/org-list.js.map +1 -0
- package/dist/commands/org-usage.js +77 -0
- package/dist/commands/org-usage.js.map +1 -0
- package/dist/commands/org.js +72 -0
- package/dist/commands/org.js.map +1 -0
- package/dist/commands/phase2-status.js +41 -0
- package/dist/commands/phase2-status.js.map +1 -0
- package/dist/commands/plan.js +70 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/pricebook.js +39 -0
- package/dist/commands/pricebook.js.map +1 -0
- package/dist/commands/scanners.js +33 -0
- package/dist/commands/scanners.js.map +1 -0
- package/dist/commands/statement.js +101 -0
- package/dist/commands/statement.js.map +1 -0
- package/dist/commands/subscription.js +32 -0
- package/dist/commands/subscription.js.map +1 -0
- package/dist/commands/token.js +61 -0
- package/dist/commands/token.js.map +1 -0
- package/dist/commands/topup.js +34 -0
- package/dist/commands/topup.js.map +1 -0
- package/dist/index.js +795 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/client.js +11 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/credentials.js +68 -0
- package/dist/lib/credentials.js.map +1 -0
- package/dist/lib/errors.js +45 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/output.js +41 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/resolve-client.js +42 -0
- package/dist/lib/resolve-client.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renameOrg = renameOrg;
|
|
4
|
+
exports.createOrg = createOrg;
|
|
5
|
+
exports.showOrg = showOrg;
|
|
6
|
+
exports.suspendOrg = suspendOrg;
|
|
7
|
+
exports.activateOrg = activateOrg;
|
|
8
|
+
exports.listOrgTokens = listOrgTokens;
|
|
9
|
+
exports.renderOrgTokens = renderOrgTokens;
|
|
10
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
11
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
12
|
+
/** Rename a customer org (intent 1). */
|
|
13
|
+
async function renameOrg(input) {
|
|
14
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
15
|
+
return (0, lh_api_client_1.renameOrg)(client, input.orgId, input.name);
|
|
16
|
+
}
|
|
17
|
+
async function createOrg(input) {
|
|
18
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
19
|
+
const body = {
|
|
20
|
+
orgName: input.orgName,
|
|
21
|
+
adminEmail: input.adminEmail,
|
|
22
|
+
adminName: input.adminName,
|
|
23
|
+
};
|
|
24
|
+
if (input.planId)
|
|
25
|
+
body.planId = input.planId;
|
|
26
|
+
return client.request('/platform/orgs', {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async function showOrg(input) {
|
|
32
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
33
|
+
return client.request(`/platform/orgs/${encodeURIComponent(input.orgId)}`);
|
|
34
|
+
}
|
|
35
|
+
async function patchOrgStatus(input, status) {
|
|
36
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
37
|
+
const body = { status };
|
|
38
|
+
if (input.reason)
|
|
39
|
+
body.reason = input.reason;
|
|
40
|
+
return client.request(`/platform/orgs/${encodeURIComponent(input.orgId)}/status`, { method: 'PATCH', body });
|
|
41
|
+
}
|
|
42
|
+
/** Suspend an org (#27). Existing api-keys are rejected at relay preCheck. */
|
|
43
|
+
function suspendOrg(input) {
|
|
44
|
+
return patchOrgStatus(input, 'SUSPENDED');
|
|
45
|
+
}
|
|
46
|
+
/** Reactivate a suspended org (#27). */
|
|
47
|
+
function activateOrg(input) {
|
|
48
|
+
return patchOrgStatus(input, 'ACTIVE');
|
|
49
|
+
}
|
|
50
|
+
async function listOrgTokens(input) {
|
|
51
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
52
|
+
return (0, lh_api_client_1.getOrgTokens)(client, input.orgId);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* One line per token. `remain=unlimited` renders new-api's -1 (UnlimitedQuota,
|
|
56
|
+
* V2). The masked key is what new-api returns — never the full secret.
|
|
57
|
+
*/
|
|
58
|
+
function renderOrgTokens(rows, opts) {
|
|
59
|
+
if (opts.json)
|
|
60
|
+
return JSON.stringify(rows);
|
|
61
|
+
if (rows.length === 0) {
|
|
62
|
+
return '(no new-api tokens for this org)\n';
|
|
63
|
+
}
|
|
64
|
+
return (rows
|
|
65
|
+
.map((t) => {
|
|
66
|
+
const remain = t.remainQuota === -1 ? 'unlimited' : String(t.remainQuota);
|
|
67
|
+
const expired = t.isExpired ? ' EXPIRED' : '';
|
|
68
|
+
return `${t.tokenId} ${t.statusText}${expired} key=${t.maskedKey} remain=${remain} used=${t.usedQuota}`;
|
|
69
|
+
})
|
|
70
|
+
.join('\n') + '\n');
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=org.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org.js","sourceRoot":"","sources":["../../src/commands/org.ts"],"names":[],"mappings":";;AAgBA,8BAGC;AAgBD,8BAeC;AAMD,0BAKC;AAsBD,gCAEC;AAGD,kCAEC;AAQD,sCAKC;AAMD,0CAiBC;AA9HD,iDAKuB;AACvB,0DAAmE;AASnE,wCAAwC;AACjC,KAAK,UAAU,SAAS,CAAC,KAAqB;IACnD,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,yBAAY,EAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAgBM,KAAK,UAAU,SAAS,CAC7B,KAAqB;IAErB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAA2B;QACnC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IACF,IAAI,KAAK,CAAC,MAAM;QAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAE7C,OAAO,MAAM,CAAC,OAAO,CAAoB,gBAAgB,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,IAAI;KACL,CAAC,CAAC;AACL,CAAC;AAMM,KAAK,UAAU,OAAO,CAAC,KAAmB;IAC/C,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,OAAO,CACnB,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CACpD,CAAC;AACJ,CAAC;AAOD,KAAK,UAAU,cAAc,CAC3B,KAAwB,EACxB,MAA8B;IAE9B,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAA2B,EAAE,MAAM,EAAE,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM;QAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAE7C,OAAO,MAAM,CAAC,OAAO,CACnB,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAC1D,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAC1B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,SAAgB,UAAU,CAAC,KAAwB;IACjD,OAAO,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED,wCAAwC;AACxC,SAAgB,WAAW,CAAC,KAAwB;IAClD,OAAO,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAQM,KAAK,UAAU,aAAa,CACjC,KAAqB;IAErB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,4BAAe,EAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAC7B,IAAoB,EACpB,IAAuB;IAEvB,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,oCAAoC,CAAC;IAC9C,CAAC;IACD,OAAO,CACL,IAAI;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,UAAU,GAAG,OAAO,QAAQ,CAAC,CAAC,SAAS,WAAW,MAAM,SAAS,CAAC,CAAC,SAAS,EAAE,CAAC;IAC1G,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CACrB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// T9 of v0.1.7 #279 / #284. CLI wrapper around lh-api-client's phase2
|
|
3
|
+
// pure logic + state-file IO. Only the CLI-specific renderer lives here
|
|
4
|
+
// — the rest is the shared SDK (#303 / #305 dedup).
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PHASE2_BANNER = exports.DEFAULT_STATE_PATH = exports.savePhase2State = exports.loadPhase2State = exports.savePhase2Flags = exports.loadPhase2Flags = exports.evaluatePhase2State = void 0;
|
|
7
|
+
exports.renderPhase2Status = renderPhase2Status;
|
|
8
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
9
|
+
var lh_api_client_2 = require("lh-api-client");
|
|
10
|
+
Object.defineProperty(exports, "evaluatePhase2State", { enumerable: true, get: function () { return lh_api_client_2.evaluatePhase2State; } });
|
|
11
|
+
Object.defineProperty(exports, "loadPhase2Flags", { enumerable: true, get: function () { return lh_api_client_2.loadPhase2Flags; } });
|
|
12
|
+
Object.defineProperty(exports, "savePhase2Flags", { enumerable: true, get: function () { return lh_api_client_2.savePhase2Flags; } });
|
|
13
|
+
// Backward-compat aliases (original lh-ops used State suffix, SDK uses Flags).
|
|
14
|
+
// Keep one release to avoid mass-renaming tests, remove next cycle.
|
|
15
|
+
Object.defineProperty(exports, "loadPhase2State", { enumerable: true, get: function () { return lh_api_client_2.loadPhase2Flags; } });
|
|
16
|
+
Object.defineProperty(exports, "savePhase2State", { enumerable: true, get: function () { return lh_api_client_2.savePhase2Flags; } });
|
|
17
|
+
Object.defineProperty(exports, "DEFAULT_STATE_PATH", { enumerable: true, get: function () { return lh_api_client_2.DEFAULT_STATE_PATH; } });
|
|
18
|
+
Object.defineProperty(exports, "PHASE2_BANNER", { enumerable: true, get: function () { return lh_api_client_2.PHASE2_BANNER; } });
|
|
19
|
+
/**
|
|
20
|
+
* CLI renderer — text checklist by default; `--json` passes through the
|
|
21
|
+
* evaluated state as a structured blob for release-pack automation.
|
|
22
|
+
* Banner appears when ≥2/3 triggers are met.
|
|
23
|
+
*/
|
|
24
|
+
function renderPhase2Status(state, opts) {
|
|
25
|
+
if (opts.json) {
|
|
26
|
+
return JSON.stringify(state);
|
|
27
|
+
}
|
|
28
|
+
const lines = [];
|
|
29
|
+
lines.push(`Phase 2 SPA trigger state: ${state.satisfied}/3 satisfied`);
|
|
30
|
+
for (const t of state.triggers) {
|
|
31
|
+
const mark = t.satisfied ? 'x' : ' ';
|
|
32
|
+
lines.push(` [${mark}] (${t.id}) ${t.name}`);
|
|
33
|
+
lines.push(` ${t.detail}`);
|
|
34
|
+
}
|
|
35
|
+
if (state.satisfied >= 2) {
|
|
36
|
+
lines.push('');
|
|
37
|
+
lines.push(lh_api_client_1.PHASE2_BANNER);
|
|
38
|
+
}
|
|
39
|
+
return lines.join('\n') + '\n';
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=phase2-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase2-status.js","sourceRoot":"","sources":["../../src/commands/phase2-status.ts"],"names":[],"mappings":";AAAA,sEAAsE;AACtE,wEAAwE;AACxE,oDAAoD;;;AA6BpD,gDAmBC;AA7CD,iDAA8C;AAE9C,+CAUuB;AATrB,oHAAA,mBAAmB,OAAA;AACnB,gHAAA,eAAe,OAAA;AACf,gHAAA,eAAe,OAAA;AACf,+EAA+E;AAC/E,oEAAoE;AACpE,gHAAA,eAAe,OAAmB;AAClC,gHAAA,eAAe,OAAmB;AAClC,mHAAA,kBAAkB,OAAA;AAClB,8GAAA,aAAa,OAAA;AAUf;;;;GAIG;AACH,SAAgB,kBAAkB,CAChC,KAAkB,EAClB,IAAuB;IAEvB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,SAAS,cAAc,CAAC,CAAC;IACxE,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,6BAAa,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.publishPlan = publishPlan;
|
|
4
|
+
exports.listPlans = listPlans;
|
|
5
|
+
exports.showPlan = showPlan;
|
|
6
|
+
exports.updatePlan = updatePlan;
|
|
7
|
+
exports.archivePlan = archivePlan;
|
|
8
|
+
exports.formatPlanLine = formatPlanLine;
|
|
9
|
+
exports.renderPlanList = renderPlanList;
|
|
10
|
+
exports.renderPlan = renderPlan;
|
|
11
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
12
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
13
|
+
const login_1 = require("./login");
|
|
14
|
+
async function publishPlan(input) {
|
|
15
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
16
|
+
const dto = await (0, login_1.readJsonFile)(input.filePath);
|
|
17
|
+
return client.request('/platform/plans', { method: 'POST', body: dto });
|
|
18
|
+
}
|
|
19
|
+
async function listPlans(input) {
|
|
20
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
21
|
+
return (0, lh_api_client_1.listPlans)(client, input);
|
|
22
|
+
}
|
|
23
|
+
async function showPlan(input) {
|
|
24
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
25
|
+
return (0, lh_api_client_1.getPlan)(client, input.planId);
|
|
26
|
+
}
|
|
27
|
+
async function updatePlan(input) {
|
|
28
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
29
|
+
const dto = (await (0, login_1.readJsonFile)(input.filePath));
|
|
30
|
+
return (0, lh_api_client_1.updatePlan)(client, input.planId, dto, input.ifMatch);
|
|
31
|
+
}
|
|
32
|
+
async function archivePlan(input) {
|
|
33
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
34
|
+
return (0, lh_api_client_1.archivePlan)(client, input.planId, input.ifMatch);
|
|
35
|
+
}
|
|
36
|
+
// ===== Renderers. --json bypasses formatting so operators can pipe to jq. =====
|
|
37
|
+
/**
|
|
38
|
+
* One line per plan. `updated=<updatedAt>` is shown deliberately — it is the
|
|
39
|
+
* optimistic-lock token the operator copies into `--if-match` for update/archive.
|
|
40
|
+
*/
|
|
41
|
+
function formatPlanLine(p) {
|
|
42
|
+
const idShort = p.id.slice(0, 8);
|
|
43
|
+
const base = p.isBaseTier ? ' base' : '';
|
|
44
|
+
return `${idShort} ${p.family}/${p.tier} ${p.status}${base} "${p.displayName}" updated=${p.updatedAt}`;
|
|
45
|
+
}
|
|
46
|
+
function renderPlanList(plans, opts) {
|
|
47
|
+
if (opts.json)
|
|
48
|
+
return JSON.stringify(plans);
|
|
49
|
+
if (plans.length === 0)
|
|
50
|
+
return '(no plans match)\n';
|
|
51
|
+
return plans.map(formatPlanLine).join('\n') + '\n';
|
|
52
|
+
}
|
|
53
|
+
function renderPlan(plan, opts) {
|
|
54
|
+
if (opts.json)
|
|
55
|
+
return JSON.stringify(plan);
|
|
56
|
+
const quotas = plan.quotas
|
|
57
|
+
.map((q) => ` - ${q.dimension}: ${q.limit} / ${q.window}`)
|
|
58
|
+
.join('\n');
|
|
59
|
+
return [
|
|
60
|
+
`id: ${plan.id}`,
|
|
61
|
+
`family/tier: ${plan.family}/${plan.tier}`,
|
|
62
|
+
`displayName: ${plan.displayName}`,
|
|
63
|
+
`status: ${plan.status}${plan.isBaseTier ? ' (base tier)' : ''}`,
|
|
64
|
+
`updatedAt: ${plan.updatedAt} <- use as --if-match for update/archive`,
|
|
65
|
+
`quotas:`,
|
|
66
|
+
quotas || ' (none)',
|
|
67
|
+
'',
|
|
68
|
+
].join('\n');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.publishPriceBook = publishPriceBook;
|
|
4
|
+
exports.activatePriceBook = activatePriceBook;
|
|
5
|
+
exports.listPriceBooks = listPriceBooks;
|
|
6
|
+
exports.renderPriceBookList = renderPriceBookList;
|
|
7
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
8
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
9
|
+
const login_1 = require("./login");
|
|
10
|
+
async function publishPriceBook(input) {
|
|
11
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
12
|
+
const dto = await (0, login_1.readJsonFile)(input.filePath);
|
|
13
|
+
return client.request('/platform/pricebook', { method: 'POST', body: dto });
|
|
14
|
+
}
|
|
15
|
+
async function activatePriceBook(input) {
|
|
16
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
17
|
+
return client.request(`/platform/pricebook/${encodeURIComponent(input.version)}/activate`, {
|
|
18
|
+
method: 'POST',
|
|
19
|
+
query: input.allowRemovals ? { allowRemovals: 'true' } : undefined,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
// ===== US-2 list (#434) — thin wrapper over lh-api-client. =====
|
|
23
|
+
async function listPriceBooks(input) {
|
|
24
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
25
|
+
return (0, lh_api_client_1.listPriceBooks)(client);
|
|
26
|
+
}
|
|
27
|
+
function renderPriceBookList(rows, opts) {
|
|
28
|
+
if (opts.json)
|
|
29
|
+
return JSON.stringify(rows);
|
|
30
|
+
if (rows.length === 0)
|
|
31
|
+
return '(no price books)\n';
|
|
32
|
+
return (rows
|
|
33
|
+
.map((r) => {
|
|
34
|
+
const active = r.isActive ? 'ACTIVE ' : ' ';
|
|
35
|
+
return `${active} ${r.version} effectiveFrom=${r.effectiveFrom}`;
|
|
36
|
+
})
|
|
37
|
+
.join('\n') + '\n');
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=pricebook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricebook.js","sourceRoot":"","sources":["../../src/commands/pricebook.ts"],"names":[],"mappings":";;AAaA,4CAMC;AAOD,8CAWC;AAID,wCAKC;AAED,kDAcC;AA9DD,iDAGuB;AACvB,0DAAmE;AACnE,mCAAuC;AAQhC,KAAK,UAAU,gBAAgB,CACpC,KAA4B;IAE5B,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,MAAM,IAAA,oBAAY,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;AAC9E,CAAC;AAOM,KAAK,UAAU,iBAAiB,CACrC,KAA6B;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,OAAO,CACnB,uBAAuB,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EACnE;QACE,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;KACnE,CACF,CAAC;AACJ,CAAC;AAED,kEAAkE;AAE3D,KAAK,UAAU,cAAc,CAClC,KAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,8BAAiB,EAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,mBAAmB,CACjC,IAAwB,EACxB,IAAuB;IAEvB,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACnD,OAAO,CACL,IAAI;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAClD,OAAO,GAAG,MAAM,IAAI,CAAC,CAAC,OAAO,kBAAkB,CAAC,CAAC,aAAa,EAAE,CAAC;IACnE,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CACrB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getScannersStatus = getScannersStatus;
|
|
4
|
+
exports.renderScannersStatus = renderScannersStatus;
|
|
5
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
6
|
+
/**
|
|
7
|
+
* US-OP-11 (T4 of v0.1.7 #279 / #282). Background-job liveness for the
|
|
8
|
+
* platform operator. Output answers "are workers still ticking after my
|
|
9
|
+
* deploy?" — one line per scanner with last/next tick + counters.
|
|
10
|
+
*/
|
|
11
|
+
async function getScannersStatus(opts) {
|
|
12
|
+
const client = await (0, resolve_client_1.resolveClient)(opts);
|
|
13
|
+
const body = await client.request('/platform/scanners/status', { method: 'GET' });
|
|
14
|
+
return body.scanners;
|
|
15
|
+
}
|
|
16
|
+
function renderScannersStatus(rows, opts) {
|
|
17
|
+
if (opts.json) {
|
|
18
|
+
return JSON.stringify(rows);
|
|
19
|
+
}
|
|
20
|
+
if (rows.length === 0) {
|
|
21
|
+
return '(no scanner data yet; wait one cadence cycle)\n';
|
|
22
|
+
}
|
|
23
|
+
return (rows
|
|
24
|
+
.map((r) => {
|
|
25
|
+
const countersStr = Object.entries(r.counters)
|
|
26
|
+
.map(([k, v]) => `${k}=${String(v)}`)
|
|
27
|
+
.join(' ');
|
|
28
|
+
const nextTick = r.nextTickAt ?? 'n/a';
|
|
29
|
+
return `${r.name} ${r.status} last=${r.lastTickAt} next=${nextTick} ${countersStr}`;
|
|
30
|
+
})
|
|
31
|
+
.join('\n') + '\n');
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=scanners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanners.js","sourceRoot":"","sources":["../../src/commands/scanners.ts"],"names":[],"mappings":";;AAkBA,8CASC;AAED,oDAqBC;AAlDD,0DAAmE;AAanE;;;;GAIG;AACI,KAAK,UAAU,iBAAiB,CACrC,IAAiB;IAEjB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,IAAI,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAC/B,2BAA2B,EAC3B,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;IACF,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC;AAED,SAAgB,oBAAoB,CAClC,IAAkB,EAClB,IAAuB;IAEvB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,iDAAiD,CAAC;IAC3D,CAAC;IACD,OAAO,CACL,IAAI;SACD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;aAC3C,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;aACpC,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC;QACvC,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,UAAU,SAAS,QAAQ,IAAI,WAAW,EAAE,CAAC;IACtF,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CACrB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStatement = getStatement;
|
|
4
|
+
exports.renderStatement = renderStatement;
|
|
5
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
6
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
7
|
+
/**
|
|
8
|
+
* US-OP-10 (T3 of v0.1.7 #279 / #281). Monthly checkpoint statement.
|
|
9
|
+
* CLI-side wrapper around lh-api-client's `getStatement`. Server stays
|
|
10
|
+
* JSON-only; presentation (md / csv) is dispatched client-side in
|
|
11
|
+
* `renderStatement` below.
|
|
12
|
+
*/
|
|
13
|
+
async function getStatement(input) {
|
|
14
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
15
|
+
return (0, lh_api_client_1.getStatement)(client, { orgId: input.orgId, month: input.month });
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Format dispatch.
|
|
19
|
+
* - json: canonical pretty-printed JSON for programmatic consumption
|
|
20
|
+
* - md: sectioned Markdown with consumption table + balance/keys + hash
|
|
21
|
+
* footer; human-readable for sales reconciliation
|
|
22
|
+
* - csv: flat row-per-section format for one-sheet spreadsheet import
|
|
23
|
+
*
|
|
24
|
+
* Both md and csv are derived from the same payload — server stays
|
|
25
|
+
* JSON-only; presentation is operator-side.
|
|
26
|
+
*/
|
|
27
|
+
function renderStatement(stmt, opts) {
|
|
28
|
+
if (opts.format === 'json')
|
|
29
|
+
return JSON.stringify(stmt, null, 2);
|
|
30
|
+
if (opts.format === 'md')
|
|
31
|
+
return renderStatementMd(stmt);
|
|
32
|
+
return renderStatementCsv(stmt);
|
|
33
|
+
}
|
|
34
|
+
function renderStatementMd(stmt) {
|
|
35
|
+
const lines = [];
|
|
36
|
+
lines.push(`# Statement — ${stmt.orgId} — ${stmt.month}`);
|
|
37
|
+
lines.push('');
|
|
38
|
+
lines.push(`Period: ${stmt.periodStart} → ${stmt.periodEnd}`);
|
|
39
|
+
lines.push('');
|
|
40
|
+
// Consumption section
|
|
41
|
+
lines.push('## Consumption');
|
|
42
|
+
lines.push('');
|
|
43
|
+
if (stmt.consumption.length === 0) {
|
|
44
|
+
lines.push('(no usage this period)');
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
lines.push('| Subscription | Model | Requests | Prompt tokens | Completion tokens | Cost |');
|
|
48
|
+
lines.push('|---|---|---|---|---|---|');
|
|
49
|
+
for (const c of stmt.consumption) {
|
|
50
|
+
lines.push(`| ${c.subscriptionId} | ${c.model} | ${c.requestCount} | ${c.promptTokens} | ${c.completionTokens} | ${c.cost} |`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
lines.push('');
|
|
54
|
+
// Balance section
|
|
55
|
+
lines.push('## Balance');
|
|
56
|
+
lines.push('');
|
|
57
|
+
lines.push(`- Starting: ${stmt.balance.starting}`);
|
|
58
|
+
lines.push(`- Topups: ${stmt.balance.topups}`);
|
|
59
|
+
lines.push(`- Charges: ${stmt.balance.charges}`);
|
|
60
|
+
lines.push(`- Ending: ${stmt.balance.ending}`);
|
|
61
|
+
lines.push('');
|
|
62
|
+
// Keys section
|
|
63
|
+
lines.push('## API Keys');
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push(`- Active at start: ${stmt.keys.activeStart}`);
|
|
66
|
+
lines.push(`- Active at end: ${stmt.keys.activeEnd}`);
|
|
67
|
+
lines.push(`- New: ${stmt.keys.newInPeriod}`);
|
|
68
|
+
lines.push(`- Revoked: ${stmt.keys.revokedInPeriod}`);
|
|
69
|
+
lines.push(`- Auto-inactivated: ${stmt.keys.dormancyInPeriod}`);
|
|
70
|
+
lines.push('');
|
|
71
|
+
// Chain of custody footer
|
|
72
|
+
lines.push('---');
|
|
73
|
+
lines.push(`chain-of-custody-sha256: ${stmt.reconciliationHash}`);
|
|
74
|
+
return lines.join('\n') + '\n';
|
|
75
|
+
}
|
|
76
|
+
// CSV: 8-column flat format. Column 1 = section name, column 2 = key,
|
|
77
|
+
// remaining columns hold values whose meaning depends on the section:
|
|
78
|
+
// consumption: subscriptionId, model, requestCount, promptTokens,
|
|
79
|
+
// completionTokens, cost
|
|
80
|
+
// balance: starting/topups/charges/ending → just one value in col 8
|
|
81
|
+
// keys: same shape as balance for symmetry
|
|
82
|
+
// This shape lets sales pivot in spreadsheet by filtering column 1.
|
|
83
|
+
const CSV_HEADER = 'section,key,subscriptionId,model,requestCount,promptTokens,completionTokens,cost';
|
|
84
|
+
function renderStatementCsv(stmt) {
|
|
85
|
+
const lines = [CSV_HEADER];
|
|
86
|
+
for (const c of stmt.consumption) {
|
|
87
|
+
lines.push(`consumption,,${c.subscriptionId},${c.model},${c.requestCount},${c.promptTokens},${c.completionTokens},${c.cost}`);
|
|
88
|
+
}
|
|
89
|
+
lines.push(`balance,starting,,,,,,${stmt.balance.starting}`);
|
|
90
|
+
lines.push(`balance,topups,,,,,,${stmt.balance.topups}`);
|
|
91
|
+
lines.push(`balance,charges,,,,,,${stmt.balance.charges}`);
|
|
92
|
+
lines.push(`balance,ending,,,,,,${stmt.balance.ending}`);
|
|
93
|
+
lines.push(`keys,activeStart,,,,,,${stmt.keys.activeStart}`);
|
|
94
|
+
lines.push(`keys,activeEnd,,,,,,${stmt.keys.activeEnd}`);
|
|
95
|
+
lines.push(`keys,newInPeriod,,,,,,${stmt.keys.newInPeriod}`);
|
|
96
|
+
lines.push(`keys,revokedInPeriod,,,,,,${stmt.keys.revokedInPeriod}`);
|
|
97
|
+
lines.push(`keys,dormancyInPeriod,,,,,,${stmt.keys.dormancyInPeriod}`);
|
|
98
|
+
lines.push(`# chain-of-custody-sha256: ${stmt.reconciliationHash}`);
|
|
99
|
+
return lines.join('\n') + '\n';
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=statement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statement.js","sourceRoot":"","sources":["../../src/commands/statement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addSubscription = addSubscription;
|
|
4
|
+
exports.extendContract = extendContract;
|
|
5
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
6
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
7
|
+
/**
|
|
8
|
+
* Operator-only path (issue #83): add an additional subscription to an
|
|
9
|
+
* already-existing org. Maps directly to
|
|
10
|
+
* `POST /platform/orgs/:orgId/subscriptions` on the LH backend.
|
|
11
|
+
*/
|
|
12
|
+
async function addSubscription(input) {
|
|
13
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
14
|
+
const body = {
|
|
15
|
+
planId: input.planId,
|
|
16
|
+
maxKeys: input.maxKeys,
|
|
17
|
+
contractStart: input.contractStart,
|
|
18
|
+
commitmentEnd: input.commitmentEnd,
|
|
19
|
+
};
|
|
20
|
+
if (input.priceBookVersion) {
|
|
21
|
+
body.priceBookVersion = input.priceBookVersion;
|
|
22
|
+
}
|
|
23
|
+
return client.request(`/platform/orgs/${encodeURIComponent(input.orgId)}/subscriptions`, { method: 'POST', body });
|
|
24
|
+
}
|
|
25
|
+
async function extendContract(input) {
|
|
26
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
27
|
+
return (0, lh_api_client_1.extendContract)(client, input.orgId, input.subId, {
|
|
28
|
+
commitmentEnd: input.commitmentEnd,
|
|
29
|
+
memo: input.memo,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/commands/subscription.ts"],"names":[],"mappings":";;AA+BA,0CAkBC;AAaD,wCAQC;AAtED,iDAGuB;AACvB,0DAAmE;AAsBnE;;;;GAIG;AACI,KAAK,UAAU,eAAe,CACnC,KAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAoC;QAC5C,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAC;IACF,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC3B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACjD,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,CACnB,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EACjE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CACzB,CAAC;AACJ,CAAC;AAaM,KAAK,UAAU,cAAc,CAClC,KAA0B;IAE1B,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,8BAAiB,EAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;QACzD,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.issueToken = issueToken;
|
|
4
|
+
exports.listTokens = listTokens;
|
|
5
|
+
exports.revokeToken = revokeToken;
|
|
6
|
+
exports.renderIssuedToken = renderIssuedToken;
|
|
7
|
+
exports.formatTokenLine = formatTokenLine;
|
|
8
|
+
exports.renderTokenList = renderTokenList;
|
|
9
|
+
const lh_api_client_1 = require("lh-api-client");
|
|
10
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
11
|
+
async function issueToken(input) {
|
|
12
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
13
|
+
return (0, lh_api_client_1.issuePlatformToken)(client, {
|
|
14
|
+
scopes: input.scopes,
|
|
15
|
+
label: input.label,
|
|
16
|
+
expiresInDays: input.expiresInDays,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function listTokens(input) {
|
|
20
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
21
|
+
return (0, lh_api_client_1.listPlatformTokens)(client);
|
|
22
|
+
}
|
|
23
|
+
async function revokeToken(input) {
|
|
24
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
25
|
+
return (0, lh_api_client_1.revokePlatformToken)(client, input.tokenId);
|
|
26
|
+
}
|
|
27
|
+
// ===== Renderers =====
|
|
28
|
+
/**
|
|
29
|
+
* Issue output. The plaintext `token` is shown ONCE — make it unmissable and
|
|
30
|
+
* separate from the metadata so an operator copies the right value.
|
|
31
|
+
*/
|
|
32
|
+
function renderIssuedToken(t, opts) {
|
|
33
|
+
if (opts.json)
|
|
34
|
+
return JSON.stringify(t);
|
|
35
|
+
const expires = t.expiresAt ? t.expiresAt.slice(0, 10) : 'never';
|
|
36
|
+
return [
|
|
37
|
+
`id: ${t.id}`,
|
|
38
|
+
`scopes: ${t.scopes.join(', ')}`,
|
|
39
|
+
`label: ${t.label ?? '(none)'}`,
|
|
40
|
+
`expires: ${expires}`,
|
|
41
|
+
'',
|
|
42
|
+
' ⚠ Copy this token now — it is shown ONCE and cannot be retrieved again:',
|
|
43
|
+
'',
|
|
44
|
+
` ${t.token}`,
|
|
45
|
+
'',
|
|
46
|
+
].join('\n');
|
|
47
|
+
}
|
|
48
|
+
function formatTokenLine(t) {
|
|
49
|
+
const idShort = t.id.slice(0, 8);
|
|
50
|
+
const expires = t.expiresAt ? t.expiresAt.slice(0, 10) : 'never';
|
|
51
|
+
const used = t.lastUsedAt ? t.lastUsedAt.slice(0, 10) : 'never';
|
|
52
|
+
return `${idShort} ${t.tokenPrefix}… ${t.status} [${t.scopes.join(',')}] "${t.label ?? ''}" expires=${expires} used=${used}`;
|
|
53
|
+
}
|
|
54
|
+
function renderTokenList(tokens, opts) {
|
|
55
|
+
if (opts.json)
|
|
56
|
+
return JSON.stringify(tokens);
|
|
57
|
+
if (tokens.length === 0)
|
|
58
|
+
return '(no service-account tokens)\n';
|
|
59
|
+
return tokens.map(formatTokenLine).join('\n') + '\n';
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/commands/token.ts"],"names":[],"mappings":";;AAmBA,gCAOC;AAED,gCAGC;AAMD,kCAKC;AAQD,8CAiBC;AAED,0CAKC;AAED,0CAOC;AAnFD,iDAMuB;AACvB,0DAAmE;AAY5D,KAAK,UAAU,UAAU,CAAC,KAAsB;IACrD,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,kCAAkB,EAAC,MAAM,EAAE;QAChC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,KAAkB;IACjD,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,kCAAkB,EAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAMM,KAAK,UAAU,WAAW,CAC/B,KAAuB;IAEvB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,IAAA,mCAAmB,EAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AACpD,CAAC;AAED,wBAAwB;AAExB;;;GAGG;AACH,SAAgB,iBAAiB,CAC/B,CAAc,EACd,IAAuB;IAEvB,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,OAAO;QACL,aAAa,CAAC,CAAC,EAAE,EAAE;QACnB,aAAa,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAClC,aAAa,CAAC,CAAC,KAAK,IAAI,QAAQ,EAAE;QAClC,aAAa,OAAO,EAAE;QACtB,EAAE;QACF,4EAA4E;QAC5E,EAAE;QACF,OAAO,CAAC,CAAC,KAAK,EAAE;QAChB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,eAAe,CAAC,CAAe;IAC7C,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,aAAa,OAAO,SAAS,IAAI,EAAE,CAAC;AAC/H,CAAC;AAED,SAAgB,eAAe,CAC7B,MAAsB,EACtB,IAAuB;IAEvB,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,+BAA+B,CAAC;IAChE,OAAO,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeTopup = executeTopup;
|
|
4
|
+
exports.listTopups = listTopups;
|
|
5
|
+
const resolve_client_1 = require("../lib/resolve-client");
|
|
6
|
+
async function executeTopup(input) {
|
|
7
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
8
|
+
const body = {
|
|
9
|
+
orgId: input.orgId,
|
|
10
|
+
amountUsd: input.amountUsd,
|
|
11
|
+
};
|
|
12
|
+
if (input.memo)
|
|
13
|
+
body.memo = input.memo;
|
|
14
|
+
return client.request('/platform/topups/execute', {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
body,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function listTopups(input) {
|
|
20
|
+
const client = await (0, resolve_client_1.resolveClient)(input);
|
|
21
|
+
const query = {
|
|
22
|
+
orgId: input.orgId,
|
|
23
|
+
from: input.from,
|
|
24
|
+
to: input.to,
|
|
25
|
+
actor: input.actor,
|
|
26
|
+
limit: input.limit,
|
|
27
|
+
offset: input.offset,
|
|
28
|
+
};
|
|
29
|
+
return client.request('/platform/topups', {
|
|
30
|
+
method: 'GET',
|
|
31
|
+
query,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=topup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topup.js","sourceRoot":"","sources":["../../src/commands/topup.ts"],"names":[],"mappings":";;AAQA,oCAcC;AA4BD,gCAiBC;AAnED,0DAAmE;AAQ5D,KAAK,UAAU,YAAY,CAChC,KAAwB;IAExB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAoC;QAC5C,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IACF,IAAI,KAAK,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IAEvC,OAAO,MAAM,CAAC,OAAO,CAAC,0BAA0B,EAAE;QAChD,MAAM,EAAE,MAAM;QACd,IAAI;KACL,CAAC,CAAC;AACL,CAAC;AA4BM,KAAK,UAAU,UAAU,CAC9B,KAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAgD;QACzD,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;IAEF,OAAO,MAAM,CAAC,OAAO,CAAkB,kBAAkB,EAAE;QACzD,MAAM,EAAE,KAAK;QACb,KAAK;KACN,CAAC,CAAC;AACL,CAAC"}
|