@oauth2-cli/qui-cli 0.4.3 → 0.5.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.5.1](https://github.com/battis/oauth2-cli/compare/qui-cli-plugin/0.5.0...qui-cli-plugin/0.5.1) (2026-01-15)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * implement convenience methods as methods, not properties ([a3f67fe](https://github.com/battis/oauth2-cli/commit/a3f67fecde50ae19d8cf960fe6828623e745126b))
11
+
12
+ ## [0.5.0](https://github.com/battis/oauth2-cli/compare/qui-cli-plugin/0.4.3...qui-cli-plugin/0.5.0) (2026-01-14)
13
+
14
+
15
+ ### ⚠ BREAKING CHANGES
16
+
17
+ * move to currently active Node.js v24
18
+ * consistent parameter names and URL support links
19
+
20
+ ### Features
21
+
22
+ * add configurable hints for CLI option parameters ([b78ab2b](https://github.com/battis/oauth2-cli/commit/b78ab2b894a7807e2fced4531930c648fe275304))
23
+ * configurable opt names to avoid collision with multiple APIs ([d147e3e](https://github.com/battis/oauth2-cli/commit/d147e3e9dfce1f0f4629d5a0e7f649258b7e9487))
24
+ * consistent parameter names and URL support links ([671c371](https://github.com/battis/oauth2-cli/commit/671c3715c7218ab3b92e84a6da69835c5148462a))
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * export pre-registered plugin as an EJS module ([19b232e](https://github.com/battis/oauth2-cli/commit/19b232e5c65de4fd43fa604c8a3c38718d4a7ab9))
30
+ * move to currently active Node.js v24 ([a651159](https://github.com/battis/oauth2-cli/commit/a6511594460c7fbc9f59e8a86c6b2f17bfb3564e))
31
+
5
32
  ## [0.4.3](https://github.com/battis/oauth2-cli/compare/qui-cli-plugin/0.4.2...qui-cli-plugin/0.4.3) (2026-01-12)
6
33
 
7
34
 
@@ -0,0 +1,11 @@
1
+ export * from './OAuth2.js';
2
+ export declare const name: string;
3
+ export declare const configure: (proposal?: import("./OAuth2.js").ConfigurationProposal) => void;
4
+ export declare const options: () => import("@qui-cli/plugin").Options;
5
+ export declare const init: ({ values }: import("@qui-cli/plugin").ExpectedArguments<typeof this.options>) => Promise<void>;
6
+ export declare const getToken: () => Promise<import("oauth2-cli").Token | undefined>;
7
+ export declare const getClient: () => import("oauth2-cli").Client;
8
+ export declare const request: (url: string | URL, method?: string | undefined, body?: import("openid-client").FetchBody, headers?: Headers | undefined, dPoPOptions?: import("openid-client").DPoPOptions | undefined) => Promise<Response>;
9
+ export declare const requestJSON: <T extends import("@battis/typescript-tricks").JSONValue>(url: string | URL, method?: string | undefined, body?: import("openid-client").FetchBody, headers?: Headers | undefined, dPoPOptions?: import("openid-client").DPoPOptions | undefined) => Promise<T>;
10
+ export declare const fetch: (endpoint: string | URL | Request, init?: RequestInit | undefined) => Promise<Response>;
11
+ export declare const fetchJSON: <T extends import("@battis/typescript-tricks").JSONValue>(endpoint: string | URL | Request, init?: RequestInit | undefined) => Promise<T>;
package/dist/Module.js ADDED
@@ -0,0 +1,13 @@
1
+ import { OAuth2 } from './OAuth2.js';
2
+ export * from './OAuth2.js';
3
+ const plugin = new OAuth2();
4
+ export const name = plugin.name;
5
+ export const configure = plugin.configure.bind(plugin);
6
+ export const options = plugin.options.bind(plugin);
7
+ export const init = plugin.init.bind(plugin);
8
+ export const getToken = plugin.getToken.bind(plugin);
9
+ export const getClient = plugin.getClient.bind(plugin);
10
+ export const request = plugin.request.bind(plugin);
11
+ export const requestJSON = plugin.requestJSON.bind(plugin);
12
+ export const fetch = plugin.fetch.bind(plugin);
13
+ export const fetchJSON = plugin.fetchJSON.bind(plugin);
package/dist/OAuth2.d.ts CHANGED
@@ -1,47 +1,38 @@
1
1
  import { PathString, URLString } from '@battis/descriptive-types';
2
2
  import { JSONValue } from '@battis/typescript-tricks';
3
- import '@qui-cli/env-1password';
4
3
  import * as Plugin from '@qui-cli/plugin';
5
4
  import * as OAuth2CLI from 'oauth2-cli';
6
5
  export { Credentials } from 'oauth2-cli';
7
- type EnvironmentVars = {
8
- client_id: string;
9
- client_secret: string;
10
- redirect_uri: string;
11
- authorization_endpoint: string;
12
- token_endpoint: string;
13
- token_path: string;
14
- access_token: string;
15
- };
16
- type OptionSuppression = {
17
- clientId?: boolean;
18
- clientSecret?: boolean;
19
- redirectUri?: boolean;
20
- authorizationEndpoint?: boolean;
21
- tokenEndpoint?: boolean;
22
- tokenPath?: boolean;
23
- };
6
+ type ParamNames = 'clientId' | 'clientSecret' | 'redirectUri' | 'authorizationEndpoint' | 'tokenEndpoint' | 'tokenPath' | 'accessToken';
7
+ type EnvironmentVars = Record<ParamNames, string>;
8
+ type SupportUrls = Record<ParamNames, URLString>;
9
+ type Hints = Record<ParamNames, string>;
10
+ type OptionNames = Record<ParamNames, string>;
11
+ type OptionSuppression = Record<ParamNames, boolean>;
24
12
  type Usage = {
25
13
  heading: string;
26
14
  text?: string[];
27
15
  };
28
16
  export type Configuration = Plugin.Configuration & {
29
- client_id?: string;
30
- client_secret?: string;
31
- redirect_uri?: URLString;
17
+ clientId?: string;
18
+ clientSecret?: string;
19
+ redirectUri?: URLString;
32
20
  headers?: Record<string, string>;
33
- authorization_endpoint?: URLString;
34
- token_endpoint?: URLString;
21
+ authorizationEndpoint?: URLString;
22
+ tokenEndpoint?: URLString;
35
23
  store?: OAuth2CLI.TokenStorage;
36
- token_path?: PathString;
24
+ tokenPath?: PathString;
25
+ opt: OptionNames;
26
+ url?: Partial<SupportUrls>;
27
+ hint?: Partial<Hints>;
37
28
  env: EnvironmentVars;
38
29
  man: Usage;
39
- suppress?: OptionSuppression;
30
+ suppress?: Partial<OptionSuppression>;
40
31
  };
41
- export type ConfigurationProposal = Partial<Omit<Configuration, 'env' | 'man' | 'suppress'>> & {
32
+ export type ConfigurationProposal = Partial<Omit<Configuration, 'opt' | 'env' | 'man'>> & {
33
+ opt?: Partial<OptionNames>;
42
34
  env?: Partial<EnvironmentVars>;
43
35
  man?: Partial<Usage>;
44
- suppress?: Partial<OptionSuppression>;
45
36
  };
46
37
  export declare class OAuth2 {
47
38
  readonly name: string;
@@ -53,11 +44,11 @@ export declare class OAuth2 {
53
44
  private client;
54
45
  configure(proposal?: ConfigurationProposal): void;
55
46
  options(): Plugin.Options;
56
- init(args: Plugin.ExpectedArguments<typeof this.options>): Promise<void>;
47
+ init({ values }: Plugin.ExpectedArguments<typeof this.options>): Promise<void>;
57
48
  getClient(): OAuth2CLI.Client;
58
- getToken: () => Promise<OAuth2CLI.Token | undefined>;
59
- request: (...args: Parameters<OAuth2CLI.Client["request"]>) => Promise<Response>;
60
- fetch: (...args: Parameters<OAuth2CLI.Client["fetch"]>) => Promise<Response>;
61
- requestJSON: <T extends JSONValue>(...args: Parameters<OAuth2CLI.Client["requestJSON"]>) => Promise<T>;
62
- fetchJSON: <T extends JSONValue>(...args: Parameters<OAuth2CLI.Client["fetchJSON"]>) => Promise<T>;
49
+ getToken(): Promise<OAuth2CLI.Token | undefined>;
50
+ request(...args: Parameters<OAuth2CLI.Client['request']>): Promise<Response>;
51
+ requestJSON<T extends JSONValue>(...args: Parameters<OAuth2CLI.Client['requestJSON']>): Promise<T>;
52
+ fetch(...args: Parameters<OAuth2CLI.Client['fetch']>): Promise<Response>;
53
+ fetchJSON<T extends JSONValue>(...args: Parameters<OAuth2CLI.Client['fetchJSON']>): Promise<T>;
63
54
  }
package/dist/OAuth2.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Colors } from '@qui-cli/colors';
2
- import '@qui-cli/env-1password';
3
2
  import { Env } from '@qui-cli/env-1password';
4
3
  import { Log } from '@qui-cli/log';
5
4
  import { Root } from '@qui-cli/root';
@@ -10,27 +9,40 @@ export class OAuth2 {
10
9
  name;
11
10
  static names = [];
12
11
  static ports = {};
13
- constructor(name = '@oauth2-cli/qui-cli-plugin') {
12
+ constructor(name = '@oauth2-cli/qui-cli') {
14
13
  this.name = name;
15
14
  if (OAuth2.names.includes(name)) {
16
15
  throw new Error(`A @qui-cli/plugin named ${Colors.value(name)} has already been instantiated.`);
17
16
  }
18
17
  }
19
18
  cliConfig = {
19
+ opt: {
20
+ clientId: 'clientId',
21
+ clientSecret: 'clientSecret',
22
+ redirectUri: 'redirectUri',
23
+ authorizationEndpoint: 'authorizationEndpoint',
24
+ tokenEndpoint: 'tokenEndpoint',
25
+ tokenPath: 'tokenPath',
26
+ accessToken: 'accessToken'
27
+ },
28
+ hint: {
29
+ redirectUri: Colors.quotedValue(`"https://localhost:3000/redirect"`)
30
+ },
20
31
  env: {
21
- client_id: 'CLIENT_ID',
22
- client_secret: 'CLIENT_SECRET',
23
- redirect_uri: 'REDIRECT_URI',
24
- authorization_endpoint: 'AUTHORIZATION_ENDPOINT',
25
- token_endpoint: 'TOKEN_ENDPOINT',
26
- token_path: 'TOKEN_PATH',
27
- access_token: 'ACCESS_TOKEN'
32
+ clientId: 'CLIENT_ID',
33
+ clientSecret: 'CLIENT_SECRET',
34
+ redirectUri: 'REDIRECT_URI',
35
+ authorizationEndpoint: 'AUTHORIZATION_ENDPOINT',
36
+ tokenEndpoint: 'TOKEN_ENDPOINT',
37
+ tokenPath: 'TOKEN_PATH',
38
+ accessToken: 'ACCESS_TOKEN'
28
39
  },
29
40
  man: {
30
41
  heading: 'OAuth 2.0 client options'
31
42
  },
32
43
  suppress: {
33
- tokenPath: true
44
+ tokenPath: true,
45
+ accessToken: true
34
46
  }
35
47
  };
36
48
  client = undefined;
@@ -41,15 +53,15 @@ export class OAuth2 {
41
53
  }
42
54
  }
43
55
  if (!this.cliConfig.store) {
44
- if (this.cliConfig.token_path) {
45
- this.cliConfig.store = new OAuth2CLI.FileStorage(path.resolve(Root.path(), this.cliConfig.token_path));
56
+ if (this.cliConfig.tokenPath) {
57
+ this.cliConfig.store = new OAuth2CLI.FileStorage(path.resolve(Root.path(), this.cliConfig.tokenPath));
46
58
  }
47
59
  else {
48
- this.cliConfig.store = new EnvironmentStorage(this.cliConfig.env.access_token);
60
+ this.cliConfig.store = new EnvironmentStorage(this.cliConfig.env.accessToken);
49
61
  }
50
62
  }
51
- if (this.cliConfig.redirect_uri) {
52
- const url = new URL(this.cliConfig.redirect_uri);
63
+ if (this.cliConfig.redirectUri) {
64
+ const url = new URL(this.cliConfig.redirectUri);
53
65
  if (url.hostname !== 'localhost') {
54
66
  Log.warning(`The ${Colors.varName('redirect_uri')} value ${Colors.url(this.cliConfig.redirect_uri)} may not work: it ${Colors.keyword('must')} point to ${Colors.url('localhost')}`);
55
67
  }
@@ -66,49 +78,46 @@ export class OAuth2 {
66
78
  }
67
79
  }
68
80
  options() {
69
- const opt = {
70
- clientId: {
71
- description: `OAuth 2.0 client ID (defaults to environment variable ` +
72
- `${Colors.value(this.cliConfig.env.client_id)})`,
73
- secret: true,
74
- default: this.cliConfig.client_id
75
- },
76
- clientSecret: {
77
- description: `OAuth 2.0 client secret (defaults to environment ` +
78
- `variable ${Colors.value(this.cliConfig.env.client_secret)}`,
79
- secret: true,
80
- default: this.cliConfig.client_secret
81
- },
82
- redirectUri: {
83
- description: `OAuth 2.0 redirect URI (must be to host ` +
84
- `${Colors.url('localhost')}, defaults to environment variables ` +
85
- `${Colors.value(this.cliConfig.env.redirect_uri)})`,
86
- hint: Colors.quotedValue(`"http://localhost:XXXX/path/to/redirect"`),
87
- default: this.cliConfig.redirect_uri
88
- },
89
- authorizationEndpoint: {
90
- description: `OAuth 2.0 authorization endpoint (defaults to ` +
91
- `environment variable ${Colors.value(this.cliConfig.env.authorization_endpoint)}`,
92
- default: this.cliConfig.authorization_endpoint
93
- },
94
- tokenEndpoint: {
95
- description: `OAuth 2.0 token endpoint (will fall back to ` +
96
- `authorization endpoint if not provided, defaults to environment ` +
97
- `variable ${Colors.value(this.cliConfig.env.token_endpoint)}`,
98
- default: this.cliConfig.token_endpoint
99
- },
100
- tokenPath: {
101
- description: `Path to token storage JSON file (defaults to environent ` +
102
- `variable ${Colors.value(this.cliConfig.env.token_path)}`,
103
- default: this.cliConfig.token_path
104
- }
81
+ const descriptions = {
82
+ clientId: `OAuth 2.0 client ID. Defaults to environment variable ` +
83
+ `${Colors.value(this.cliConfig.env.clientId)}, if present.`,
84
+ clientSecret: `OAuth 2.0 client secret. Defaults to environment variable ` +
85
+ `${Colors.value(this.cliConfig.env.clientSecret)}, if present.`,
86
+ redirectUri: `OAuth 2.0 redirect URI, must be to host ${Colors.url('localhost')}. ` +
87
+ `Defaults to environment variable ` +
88
+ `${Colors.value(this.cliConfig.env.redirectUri)}, if present.`,
89
+ authorizationEndpoint: `OAuth 2.0 authorization endpoint. Defaults to environment variable ` +
90
+ `${Colors.value(this.cliConfig.env.authorizationEndpoint)}, if present.`,
91
+ tokenEndpoint: `OAuth 2.0 token endpoint, will fall back to ` +
92
+ `${Colors.optionArg(`--${this.cliConfig.opt['authorizationEndpoint']}`)} if ` +
93
+ `not provided. Defaults to environment ariable ` +
94
+ `${Colors.value(this.cliConfig.env.tokenEndpoint)}, if present.`,
95
+ tokenPath: `Path to token storage JSON file. Defaults to environent variable ` +
96
+ `${Colors.value(this.cliConfig.env.tokenPath)}, if present.`,
97
+ accessToken: `Access token JSON object value. Defaults to environment variable ` +
98
+ `${Colors.value(this.cliConfig.env.accessToken)}, if present.`
105
99
  };
106
- if (this.cliConfig.suppress) {
107
- let option;
108
- for (option in this.cliConfig.suppress) {
109
- if (this.cliConfig.suppress[option]) {
110
- delete opt[option];
100
+ const opt = {};
101
+ for (const paramName of Object.keys(descriptions)) {
102
+ if (!this.cliConfig.suppress || !this.cliConfig.suppress[paramName]) {
103
+ const option = { description: descriptions[paramName] };
104
+ if (this.cliConfig.url && this.cliConfig.url[paramName]) {
105
+ option.description = `${option.description} See ${Colors.url(this.cliConfig.url[paramName])} for more information.`;
106
+ }
107
+ if (this.cliConfig.hint && this.cliConfig.hint[paramName]) {
108
+ option.hint = this.cliConfig.hint[paramName];
109
+ }
110
+ switch (paramName) {
111
+ case 'clientId':
112
+ case 'clientSecret':
113
+ case 'accessToken':
114
+ option.secret = true;
115
+ }
116
+ const param = this.cliConfig[paramName];
117
+ if (typeof param === 'string') {
118
+ option.default = param;
111
119
  }
120
+ opt[this.cliConfig.opt[paramName]] = option;
112
121
  }
113
122
  }
114
123
  return {
@@ -119,32 +128,20 @@ export class OAuth2 {
119
128
  opt
120
129
  };
121
130
  }
122
- async init(args) {
123
- const { values: { clientId: client_id = await Env.get({
124
- key: this.cliConfig.env.client_id
125
- }), clientSecret: client_secret = await Env.get({
126
- key: this.cliConfig.env.client_secret
127
- }), redirectUri: redirect_uri = await Env.get({
128
- key: this.cliConfig.env.redirect_uri
129
- }), authorizationEndpoint: authorization_endpoint = await Env.get({
130
- key: this.cliConfig.env.authorization_endpoint
131
- }), tokenEndpoint: token_endpoint = await Env.get({
132
- key: this.cliConfig.env.token_endpoint
133
- }), tokenPath: token_path = await Env.get({
134
- key: this.cliConfig.env.token_path
135
- }) } } = args;
136
- this.configure({
137
- client_id,
138
- client_secret,
139
- redirect_uri,
140
- authorization_endpoint,
141
- token_endpoint,
142
- token_path
143
- });
131
+ async init({ values }) {
132
+ const proposal = {};
133
+ let paramName;
134
+ for (paramName of Object.keys(this.cliConfig.opt)) {
135
+ proposal[paramName] =
136
+ values[this.cliConfig.opt[paramName]] ||
137
+ this.cliConfig[paramName] ||
138
+ (await Env.get({ key: this.cliConfig.env[paramName] }));
139
+ }
140
+ this.configure(proposal);
144
141
  }
145
142
  getClient() {
146
143
  if (!this.client) {
147
- const { client_id, client_secret, redirect_uri, authorization_endpoint, token_endpoint, headers, store } = this.cliConfig;
144
+ const { clientId: client_id, clientSecret: client_secret, redirectUri: redirect_uri, authorizationEndpoint: authorization_endpoint, tokenEndpoint: token_endpoint, headers, store } = this.cliConfig;
148
145
  if (!client_id) {
149
146
  throw new Error('OAuth 2.0 client ID not defined');
150
147
  }
@@ -169,9 +166,19 @@ export class OAuth2 {
169
166
  }
170
167
  return this.client;
171
168
  }
172
- getToken = () => this.getClient().getToken();
173
- request = (...args) => this.getClient().request(...args);
174
- fetch = (...args) => this.getClient().fetch(...args);
175
- requestJSON = (...args) => this.getClient().requestJSON(...args);
176
- fetchJSON = (...args) => this.getClient().fetchJSON(...args);
169
+ getToken() {
170
+ return this.getClient().getToken();
171
+ }
172
+ request(...args) {
173
+ return this.getClient().request(...args);
174
+ }
175
+ requestJSON(...args) {
176
+ return this.getClient().requestJSON(...args);
177
+ }
178
+ fetch(...args) {
179
+ return this.getClient().fetch(...args);
180
+ }
181
+ fetchJSON(...args) {
182
+ return this.getClient().fetchJSON(...args);
183
+ }
177
184
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { OAuth2 as Plugin } from './OAuth2.js';
1
+ import * as OAuth2 from './Module.js';
2
2
  export * from './EnvironmentStorage.js';
3
- export declare const OAuth2: Plugin;
3
+ export { OAuth2 };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { register } from '@qui-cli/plugin';
2
- import { OAuth2 as Plugin } from './OAuth2.js';
2
+ import * as OAuth2 from './Module.js';
3
3
  export * from './EnvironmentStorage.js';
4
- export const OAuth2 = new Plugin();
4
+ export { OAuth2 };
5
5
  await register(OAuth2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oauth2-cli/qui-cli",
3
- "version": "0.4.3",
3
+ "version": "0.5.1",
4
4
  "description": "@qui-cli/plugin wrapper for oauth2-cli",
5
5
  "homepage": "https://github.com/battis/oauth2-cli/tree/main/packages/qui-cli#readme",
6
6
  "repository": {
@@ -19,7 +19,7 @@
19
19
  "@qui-cli/colors": "^3.2.1",
20
20
  "@qui-cli/log": "^4.0.2",
21
21
  "openid-client": "^6.8.1",
22
- "oauth2-cli": "0.4.0"
22
+ "oauth2-cli": "0.5.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@battis/descriptive-types": "^0.2.6",
@@ -27,9 +27,9 @@
27
27
  "@qui-cli/env-1password": "^1.2.6",
28
28
  "@qui-cli/plugin": "^4.0.0",
29
29
  "@qui-cli/root": "^3.0.6",
30
- "@tsconfig/node20": "^20.1.8",
30
+ "@tsconfig/node24": "^24.0.3",
31
31
  "commit-and-tag-version": "^12.6.1",
32
- "del-cli": "^6.0.0",
32
+ "del-cli": "^7.0.0",
33
33
  "npm-run-all": "^4.1.5",
34
34
  "typescript": "^5.9.3"
35
35
  },