11import {
22 defineCommand ,
3- buildCanonicalQuery ,
4- signRequest ,
5- modelStudioHost ,
63 detectOutputFormat ,
7- maskToken ,
8- trackingHeaders ,
94 type Config ,
105 type GlobalFlags ,
11- type AddOrganizationMemberResponse ,
126 BailianError ,
137 ExitCode ,
148} from "bailian-cli-core" ;
159import { emitResult , emitBare } from "../../output/output.ts" ;
1610import { padEnd } from "../../output/cjk-width.ts" ;
11+ import type { AddOrganizationMemberResponse } from "./types.ts" ;
12+ import {
13+ TOKEN_PLAN_AK_OPTIONS ,
14+ TOKEN_PLAN_COMMON_QUERY_OPTIONS ,
15+ appendCommonQueryParams ,
16+ callTokenPlanApi ,
17+ prepareTokenPlanRequest ,
18+ resolveTokenPlanCredentials ,
19+ type TokenPlanQueryParams ,
20+ } from "./utils.ts" ;
1721
18- const API_VERSION = "2026-02-10" ;
1922const API_ACTION = "AddOrganizationMember" ;
2023const API_PATH = "/tokenplan/organization/member-additions" ;
2124
@@ -36,19 +39,8 @@ export default defineCommand({
3639 flag : "--spec-type <type>" ,
3740 description : "Seat tier to assign on creation: standard, pro, or max" ,
3841 } ,
39- {
40- flag : "--caller-uac-account-id <id>" ,
41- description : "Caller UAC account ID" ,
42- } ,
43- {
44- flag : "--namespace-id <id>" ,
45- description : "Product namespace ID (Token Plan default: namespace-1)" ,
46- } ,
47- { flag : "--access-key-id <key>" , description : "Alibaba Cloud Access Key ID (deprecated)" } ,
48- {
49- flag : "--access-key-secret <key>" ,
50- description : "Alibaba Cloud Access Key Secret (deprecated)" ,
51- } ,
42+ ...TOKEN_PLAN_COMMON_QUERY_OPTIONS ,
43+ ...TOKEN_PLAN_AK_OPTIONS ,
5244 ] ,
5345 examples : [
5446 "bl tokenplan add-member --account-name dev_user --org-id org_123" ,
@@ -57,16 +49,7 @@ export default defineCommand({
5749 ] ,
5850 async run ( config : Config , flags : GlobalFlags ) {
5951 const format = detectOutputFormat ( config . output ) ;
60- const accessKeyId = ( flags . accessKeyId as string ) || config . accessKeyId ;
61- const accessKeySecret = ( flags . accessKeySecret as string ) || config . accessKeySecret ;
62-
63- if ( ! accessKeyId || ! accessKeySecret ) {
64- throw new BailianError (
65- "No credentials found.\n" +
66- "Set ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET." ,
67- ExitCode . AUTH ,
68- ) ;
69- }
52+ const credentials = resolveTokenPlanCredentials ( config , flags ) ;
7053
7154 const accountName = flags . accountName as string | undefined ;
7255 const orgId = flags . orgId as string | undefined ;
@@ -78,52 +61,26 @@ export default defineCommand({
7861 }
7962
8063 const queryParams = buildQueryParams ( flags ) ;
81- const queryString = buildCanonicalQuery ( queryParams ) ;
82- const host = modelStudioHost ( config . region ) ;
83- const endpoint = `https://${ host } ${ API_PATH } ${ queryString ? `?${ queryString } ` : "" } ` ;
8464
8565 if ( config . dryRun ) {
86- emitResult ( { endpoint, query : queryParams } , format ) ;
66+ const { endpoint, queryParams : query } = prepareTokenPlanRequest (
67+ config ,
68+ API_PATH ,
69+ queryParams ,
70+ ) ;
71+ emitResult ( { endpoint, query } , format ) ;
8772 return ;
8873 }
8974
90- const headers = signRequest ( {
91- accessKeyId ,
92- accessKeySecret ,
75+ const data = await callTokenPlanApi < AddOrganizationMemberResponse > ( {
76+ config ,
77+ credentials ,
9378 action : API_ACTION ,
94- version : API_VERSION ,
95- body : "" ,
96- host,
97- pathname : API_PATH ,
79+ path : API_PATH ,
9880 method : "POST" ,
99- queryString ,
81+ queryParams ,
10082 } ) ;
10183
102- if ( config . verbose ) {
103- process . stderr . write ( `> POST ${ endpoint } \n` ) ;
104- process . stderr . write ( `> AK: ${ maskToken ( accessKeyId ) } \n` ) ;
105- }
106-
107- const timeoutMs = config . timeout * 1000 ;
108- const res = await fetch ( endpoint , {
109- method : "POST" ,
110- headers : { ...headers , ...trackingHeaders ( ) } ,
111- signal : AbortSignal . timeout ( timeoutMs ) ,
112- } ) ;
113-
114- if ( config . verbose ) {
115- process . stderr . write ( `< ${ res . status } ${ res . statusText } \n` ) ;
116- }
117-
118- const data = ( await res . json ( ) ) as AddOrganizationMemberResponse ;
119-
120- if ( ! res . ok || data . Success === false ) {
121- throw new BailianError (
122- `${ data . Code || res . status } - ${ data . Message || res . statusText } ` ,
123- ExitCode . GENERAL ,
124- ) ;
125- }
126-
12784 if ( config . quiet || format === "text" ) {
12885 emitTextMember ( data ) ;
12986 } else {
@@ -132,8 +89,8 @@ export default defineCommand({
13289 } ,
13390} ) ;
13491
135- function buildQueryParams ( flags : GlobalFlags ) : Record < string , string | string [ ] | undefined > {
136- const params : Record < string , string | string [ ] | undefined > = { } ;
92+ function buildQueryParams ( flags : GlobalFlags ) : TokenPlanQueryParams {
93+ const params : TokenPlanQueryParams = { } ;
13794
13895 if ( flags . accountName ) params . AccountName = flags . accountName as string ;
13996 if ( flags . orgId ) params . OrgId = flags . orgId as string ;
@@ -142,8 +99,7 @@ function buildQueryParams(flags: GlobalFlags): Record<string, string | string[]
14299 ? flags . orgRoleCode
143100 : DEFAULT_ORG_ROLE ;
144101 if ( flags . specType ) params . SpecType = flags . specType as string ;
145- if ( flags . callerUacAccountId ) params . CallerUacAccountId = flags . callerUacAccountId as string ;
146- if ( flags . namespaceId ) params . NamespaceId = flags . namespaceId as string ;
102+ appendCommonQueryParams ( params , flags ) ;
147103
148104 return params ;
149105}
0 commit comments