neutrinos-cli 1.0.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.
Files changed (57) hide show
  1. package/.configs/auth.json +5 -0
  2. package/.configs/preferences.json +5 -0
  3. package/.env +6 -0
  4. package/README.md +173 -0
  5. package/bin/cli.js +239 -0
  6. package/cli-auth/auth.js +54 -0
  7. package/cli-auth/publish.js +7 -0
  8. package/cli-auth/server.js +44 -0
  9. package/cli-auth/services/auth-utils.js +68 -0
  10. package/commands/alpha-publish.js +219 -0
  11. package/commands/attribute.js +155 -0
  12. package/commands/build.js +83 -0
  13. package/commands/deprecate.js +88 -0
  14. package/commands/dev.js +21 -0
  15. package/commands/generate.js +19 -0
  16. package/commands/new-workspace.js +142 -0
  17. package/commands/publish.js +334 -0
  18. package/commands/select-packages.mjs +36 -0
  19. package/commands/serve.js +27 -0
  20. package/package.json +34 -0
  21. package/setup.js +55 -0
  22. package/templates/assets/default-icon.png +0 -0
  23. package/templates/component/.component.ts.hbs +126 -0
  24. package/templates/component/.spec.ts.hbs +15 -0
  25. package/templates/component/.styles.ts.hbs +2 -0
  26. package/templates/module/.module.js.hbs +11 -0
  27. package/templates/plugins-server/index.js +18 -0
  28. package/templates/project/.vscode/extensions.json +6 -0
  29. package/templates/project/ATTRIBUTE.md +127 -0
  30. package/templates/project/Dockerfile +15 -0
  31. package/templates/project/helmchart/.helmignore +23 -0
  32. package/templates/project/helmchart/Chart.yaml +24 -0
  33. package/templates/project/helmchart/templates/NOTES.txt +22 -0
  34. package/templates/project/helmchart/templates/_helpers.tpl +62 -0
  35. package/templates/project/helmchart/templates/deployment.yaml +69 -0
  36. package/templates/project/helmchart/templates/ingress.yaml +62 -0
  37. package/templates/project/helmchart/templates/service.yaml +14 -0
  38. package/templates/project/helmchart/values.yaml +74 -0
  39. package/templates/project/index.html +24 -0
  40. package/templates/project/index.ts +86 -0
  41. package/templates/project/public-api.ts +0 -0
  42. package/templates/project/tsconfig.json +27 -0
  43. package/utils/attribute-utils.js +149 -0
  44. package/utils/check-valid-ws.js +21 -0
  45. package/utils/copy-utils.js +68 -0
  46. package/utils/create-client.js +23 -0
  47. package/utils/file-utils.js +43 -0
  48. package/utils/generate-component.js +101 -0
  49. package/utils/generate-module.js +51 -0
  50. package/utils/get-package-info.js +53 -0
  51. package/utils/get-packages.js +15 -0
  52. package/utils/inquirer-utils.js +49 -0
  53. package/utils/logger.js +35 -0
  54. package/utils/marketplace-api-utils.js +34 -0
  55. package/utils/path-utils.js +40 -0
  56. package/utils/prettify.js +36 -0
  57. package/utils/user-seesion-utils.js +43 -0
@@ -0,0 +1,5 @@
1
+ {
2
+ "clientId": "your-client-id",
3
+ "clientSecret": "your-client-secret",
4
+ "redirectUri": "http://localhost:3000/callback"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "theme": "light",
3
+ "language": "en",
4
+ "showNotifications": true
5
+ }
package/.env ADDED
@@ -0,0 +1,6 @@
1
+ PORT=32231
2
+ ISSUER_URL=https://marketplace.neutrinos-apps.com
3
+ IDS_CLIENT_ID=FYqh5ZhdbIp2SrQPGZYMe
4
+ IDS_CLIENT_SECRET=7aJ3-A70E7rS-o5rBwspFeeefM6OfCfOODEy1xDn4iqLLVRreKgvkE9N61cz2I3pn8I0n_DjHAsxr3iDHnAQJw
5
+ MARKETPLACE_URL=https://marketplace.neutrinos-apps.com/marketplace-headless/api/packages/
6
+ MARKETPLACE_URL_PROD=https://marketplace.neutrinos-apps.com/marketplace-headless/api/packages/
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # neutrinos CLI
2
+
3
+ neutrinos CLI is a command-line interface for managing, developing and publishing the packages.
4
+
5
+ ### Installation
6
+
7
+ To install neutrinos CLI, use the following command:
8
+
9
+ ```sh
10
+ npm i -g neutrinos-cli
11
+ ```
12
+
13
+ ### Usage
14
+
15
+ ```sh
16
+ neutrinos command [options]
17
+ ```
18
+
19
+ ### Commands
20
+
21
+ - `new <name>` Create a new project
22
+ - `generate` | `g` Generate a new plugin. Run "help generate" for more information.
23
+ - `auth` Perform authentication tasks like login, logout, or status
24
+ - `publish [options] [packageName]` Bundle and publish the plugin
25
+ - `build <type> [pluginName]` Build the plugin
26
+ - `start [options]` Start the live server for the plugin
27
+ - `serve` Start the express server that serves the plugins
28
+
29
+ ### Options
30
+
31
+ - `-v, --version` Output the version number
32
+ - `-h, --help` Display help for command
33
+
34
+ ---
35
+
36
+ ## Commands
37
+
38
+ ---
39
+
40
+ ### `new <name>`
41
+
42
+ ##### Description
43
+
44
+ - Create a new project with the given name. The project will be created in the current directory.
45
+
46
+ ##### Usage
47
+
48
+ ```sh
49
+ neutrinos new <name>
50
+ ```
51
+
52
+ ##### Arguments
53
+
54
+ - `<name>` project or workspace name
55
+
56
+ ---
57
+
58
+ ### `generate` | `g`
59
+
60
+ ##### Description
61
+
62
+ - Generate a new component or module
63
+
64
+ ##### Usage
65
+
66
+ ```sh
67
+ neutrinos generate [command] [argument] || neutrinos g [command] [argument]
68
+ ```
69
+
70
+ ##### commands
71
+
72
+ - `component <name>` | `c <name>` Component is a package enabling drag and drop functionality within the canvas
73
+ - `module <name>` | `m <name>` Module is a globally accessible package, available throughout the entire project on `alpha.plugins` | `ap`.
74
+ - `attribute [command] [options]` | `a [command] [options]` Generate an Attribute for a component, Read the `ATTRIBUTE.md` file in projetc/workspcae directory for more help
75
+
76
+ ##### Arguments
77
+
78
+ - `<name>` component or module name
79
+
80
+ ---
81
+
82
+ ## `Build <type> [pluginName]`
83
+
84
+ #### Description
85
+
86
+ - Build the plugins
87
+
88
+ #### Usage
89
+
90
+ ```sh
91
+ neutrinos build <type> [pluginName]
92
+ ```
93
+
94
+ #### Arguments
95
+
96
+ - `<type>` The type of build, it can be one of `plugin` or `docker`
97
+ - `pluginName` package Name of the component/module to build, it is an optional argument and if not pluginName it will build every package in the current workspace
98
+
99
+ ---
100
+
101
+ ## `start [options]`
102
+
103
+ #### Description
104
+
105
+ - Start the live server for the workspace
106
+
107
+ #### Usage
108
+
109
+ ```sh
110
+ neutrinos start [options]
111
+ ```
112
+
113
+ #### Options
114
+
115
+ - `-p, --port <port>` Port to start the server on, default is 6969
116
+
117
+ ---
118
+
119
+ ## `serve`
120
+
121
+ #### Description
122
+
123
+ - Start the express server that serves the plugins
124
+
125
+ #### Usage
126
+
127
+ ```sh
128
+ neutrinos serve
129
+ ```
130
+
131
+ ---
132
+
133
+ ### `auth [command]`
134
+
135
+ #### Description
136
+
137
+ - Perform authentication tasks like login or status
138
+
139
+ #### Usage
140
+
141
+ ```sh
142
+ neutrinos auth [command]
143
+ ```
144
+
145
+ #### Commands:
146
+
147
+ - `login` Authenticate with the server
148
+ - `state` Get the current state of auth
149
+
150
+ ---
151
+
152
+ ## `publish [PackageName] [options]`
153
+
154
+ #### Description
155
+
156
+ - Publish a package to the server
157
+
158
+ #### Usage
159
+
160
+ ```sh
161
+ neutrinos publish [PackageName] [Options]
162
+ ```
163
+
164
+ #### Arguments
165
+
166
+ - `PackageName` The name of the component/module to publish, if not cli will show the list of packages inside the current workspace/project
167
+
168
+ #### Options
169
+
170
+ - `-t, --version-type <versionType>` Version type for verion up, it can be one of `patch`, `minor`, `major`
171
+ - `-d, --display-name <displayName>` Display Name for the package
172
+ - `-i, --icon <iconPath>` Path to the icon
173
+ - `-m, --images <imagePaths...>` path to the image
package/bin/cli.js ADDED
@@ -0,0 +1,239 @@
1
+ #! /usr/bin/env node
2
+ //@ts-check
3
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
4
+ import dotenv from 'dotenv';
5
+ dotenv.config({
6
+ path: join(__dirname, '../.env'),
7
+ });
8
+ ////////////////////////////////////
9
+ import { greenBright } from 'colorette';
10
+ import { Command, InvalidArgumentError } from 'commander';
11
+ import EventEmitter from 'node:events';
12
+ import { cwd, env, exit } from 'node:process';
13
+ import { fileURLToPath } from 'node:url';
14
+ import open from 'open';
15
+ import { join } from 'path';
16
+ import { init } from '../cli-auth/server.js';
17
+ import { publish as alphaPublish } from '../commands/alpha-publish.js';
18
+ import { addAttribute } from '../commands/attribute.js';
19
+ import { build } from '../commands/build.js';
20
+ import { deprecate } from '../commands/deprecate.js';
21
+ import { servePlugin } from '../commands/dev.js';
22
+ import { generate } from '../commands/generate.js';
23
+ import { createWorkspace } from '../commands/new-workspace.js';
24
+ import { publish } from '../commands/publish.js';
25
+ import { startPluginsServer } from '../commands/serve.js';
26
+ import { validateWorkspace } from '../utils/check-valid-ws.js';
27
+ import { done, failed, inprogress, log } from '../utils/logger.js';
28
+ import { authConfigJson } from '../utils/path-utils.js';
29
+ export const createProgram = () => {
30
+ const program = new Command();
31
+
32
+ program.version('1.0.0', '-v, --version', 'Output the version number');
33
+
34
+ program
35
+ .command('new <name>')
36
+ .description('Create a new project')
37
+ .action((name) => {
38
+ createWorkspace(join(cwd(), name), name);
39
+ });
40
+ const generateCmd = program
41
+ .command('generate')
42
+ .alias('g')
43
+ .description('Generate a new plugin. Run "help generate" for more information.');
44
+
45
+ generateCmd
46
+ .command('component')
47
+ .alias('c')
48
+ .argument('<name>', 'Component name')
49
+ .option('-d,--description <description>', 'Description of the package')
50
+ .description('Generate a new component plugin')
51
+ .action(async (name, options) => {
52
+ await generate.component({
53
+ name,
54
+ dir: cwd(),
55
+ description: options.description,
56
+ });
57
+ });
58
+ generateCmd
59
+ .command('module')
60
+ .alias('m')
61
+ .argument('<name>', 'Module name')
62
+ .option('-d,--description <description>', 'Description of the package')
63
+ .description('Generate a new module plugin')
64
+ .action(async (name, options) => {
65
+ await generate.module({
66
+ name,
67
+ dir: cwd(),
68
+ description: options.description,
69
+ });
70
+ });
71
+ generateCmd
72
+ .command('attribute')
73
+ .alias('a')
74
+ .argument('[componentName]', 'Component name')
75
+ .option('-t , --type <attributeType>', 'Type of attribute can be property, event, validation')
76
+ .option(
77
+ '-u , --ui-type <uiType>',
78
+ 'Ui-type of attribute can be ===> input, toggle, dropdown, multi-select, typed-input, range, color-picker, data-source, data-set, table-actions, data-mapping',
79
+ )
80
+ .option('-l , --label <label>', 'Label for an attribute')
81
+ .option('-e , --event <event>', 'Event name for an attribute if -t/--type is event')
82
+ .option('-c , --category <category>', 'Category for an attribute')
83
+ .option('-p , --placeholder <placeholder>', 'Placeholder for an attribute')
84
+ .option('-d , --defaultValue <defaultValue>', 'DefaultValue for an attribute')
85
+ .option('-o , --options <options...>', 'Options for an attribute')
86
+ .option('-f , --fieldMappings <FieldMappings>', 'FieldMappings for package')
87
+ .option('-n , --validation <validation>', 'Validation for an attribute')
88
+ .description('Generate an Attribute for component')
89
+ .action(async (componentName, options) => {
90
+ return await addAttribute(componentName, cwd(), options);
91
+ });
92
+
93
+ const authCommand = program.command('auth').description('perform: login, logout, or status');
94
+ authCommand
95
+ .command('login')
96
+ .description('authenticate with the server')
97
+ .action((action) => {
98
+ return new Promise(async (resolve, reject) => {
99
+ inprogress(`logging in...`);
100
+ const cliServer = await init({
101
+ tokenSetPath: authConfigJson(),
102
+ });
103
+ if (!cliServer) {
104
+ failed('Issuer not found');
105
+ return;
106
+ }
107
+ const eventEmitter = new EventEmitter();
108
+ eventEmitter.on('cli-auth:login', () => {
109
+ done('login successful');
110
+ resolve();
111
+ process.exit(0);
112
+ });
113
+ eventEmitter.on('cli-auth:login-failed', () => {
114
+ failed('login failed');
115
+ reject();
116
+ process.exit(1);
117
+ });
118
+ process.on('SIGINT', () => {
119
+ failed('exitting unexpectedly');
120
+ cliServer.stop();
121
+ exit(0);
122
+ });
123
+ process.on('SIGTERM', () => {
124
+ failed('exitting unexpectedly');
125
+ cliServer.stop();
126
+ exit(0);
127
+ });
128
+ await cliServer.start(eventEmitter);
129
+ const url = `http://localhost:${env.PORT}/login`;
130
+ inprogress(`open to login ${greenBright(url)}`);
131
+ await open(url);
132
+ });
133
+ });
134
+ authCommand
135
+ .command('state')
136
+ .description('get the current state of auth')
137
+ .action(() => {
138
+ console.log('state');
139
+ });
140
+
141
+ program
142
+ .command('publish')
143
+ .argument('[packageName]', 'Component name')
144
+ .option(
145
+ '-t, --version-type <versionType>',
146
+ 'Version type for verion up can be one of "patch", "minor", "major"',
147
+ )
148
+ .option('-d, --display-name <displayName>', 'Display Name for the package')
149
+ .option('-i, --icon <iconPath>', 'Icon path')
150
+ .option('-m, --images <imagePaths...>', 'Image paths')
151
+ .description('Bundle and publish the plugin')
152
+ .action(async (packageName, options) => {
153
+ if (
154
+ options.versionType &&
155
+ !['patch', 'minor', 'major'].includes((options.versionType || '').toLowerCase())
156
+ ) {
157
+ failed('Invalid version type should be one of "patch", "minor", "major"');
158
+ exit(0);
159
+ }
160
+ return await publish(packageName, cwd(), options);
161
+ });
162
+
163
+ program
164
+ .command('alpha:publish')
165
+ .argument('[packageName]', 'Component name')
166
+ .option(
167
+ '-t, --version-type <versionType>',
168
+ 'Version type for version up can be one of "patch", "minor", "major"',
169
+ )
170
+ .option('-d, --display-name <displayName>', 'Display Name for the package')
171
+ .option('-i, --icon <iconPath>', 'Icon path')
172
+ .option('-m, --images <imagePaths...>', 'Image paths')
173
+ .option('--accept-defaults', 'Accept all default values')
174
+ .option('--all', 'Select all the packages')
175
+ .description('Bundle and publish the plugin')
176
+ .action(async (packageName, options) => {
177
+ if (
178
+ options.versionType &&
179
+ !['patch', 'minor', 'major'].includes((options.versionType || '').toLowerCase())
180
+ ) {
181
+ failed('Invalid version type should be one of "patch", "minor", "major"');
182
+ exit(0);
183
+ }
184
+ return await alphaPublish(packageName, cwd(), options);
185
+ });
186
+
187
+ program
188
+ .command('deprecate')
189
+ .option('-y, --yes', 'Confirmation to deprecate a package')
190
+ .option('--all', 'Select all the packages')
191
+ .argument('[packageName]', 'Package name')
192
+ .action(async (packageName, options) => {
193
+ return await deprecate(packageName, cwd(), options);
194
+ });
195
+
196
+ program
197
+ .command('build')
198
+ .argument('<type>', 'Type of build: "plugins" or "docker"', (value, prevValue) => {
199
+ if (value !== 'plugins' && value !== 'docker') {
200
+ throw new InvalidArgumentError('"build" can be "plugins" or "docker"');
201
+ }
202
+ return value;
203
+ })
204
+ .argument('[pluginName]', 'Name of the plugin')
205
+ .option('--module', 'Build the plugin as a module')
206
+ .option('--all', 'Build all the plugin of the workspace')
207
+ .description('Build the plugin')
208
+ .action((type, pluginName, options) => {
209
+ build[type](cwd(), pluginName, options || {});
210
+ });
211
+ program
212
+ .command('start')
213
+ .option('-p, --port <port>', 'Port number for serving the plugin')
214
+ .description('start the live server for the plugin')
215
+ .action((options) => {
216
+ servePlugin(cwd(), options.port || 6969);
217
+ });
218
+ program
219
+ .command('serve')
220
+ .description('Start the express server that serves the plugins')
221
+ .action(() => {
222
+ startPluginsServer(cwd());
223
+ });
224
+ program.hook('preAction', async (thisCmd, actionCmd) => {
225
+ const cmd = actionCmd.name();
226
+ if (cmd === 'new' || cmd === 'login') {
227
+ return;
228
+ }
229
+ if (!validateWorkspace(cwd())) {
230
+ log('Please run this command in a valid workspace directory');
231
+ exit(1);
232
+ }
233
+ });
234
+
235
+ return program;
236
+ };
237
+
238
+ const program = createProgram();
239
+ program.parse(process.argv);
@@ -0,0 +1,54 @@
1
+ import EventEmitter from 'node:events';
2
+ import { existsSync } from 'node:fs';
3
+ import { mkdir, writeFile } from 'node:fs/promises';
4
+ import { sep } from 'node:path';
5
+ import { authUtils } from './services/auth-utils.js';
6
+
7
+ /**
8
+ * @param {import('openid-client').Client} client
9
+ * @param {string} tokenSetPath
10
+ */
11
+ export const auth = (client, tokenSetPath) => {
12
+ const authStateNonce = {
13
+ state: '',
14
+ nonce: '',
15
+ };
16
+ /**
17
+ *
18
+ * @param {import('fastify').FastifyRequest} req
19
+ * @param {import('fastify').FastifyReply} reply
20
+ */
21
+ return {
22
+ /**
23
+ * @param {import('fastify').FastifyInstance} server
24
+ * @param {EventEmitter} eventEmitter
25
+ */
26
+ mount: (server, eventEmitter) => {
27
+ server.get('/login', async (request, reply) => {
28
+ const redirectUrl = await authUtils.login(client, authStateNonce);
29
+ reply.redirect(redirectUrl);
30
+ });
31
+ server.get('/login-callback', async (request, reply) => {
32
+ const { tokenSet } = await authUtils.loginCallback(
33
+ client.callbackParams(request),
34
+ client,
35
+ authStateNonce,
36
+ );
37
+ const dirPath = tokenSetPath.substring(0, tokenSetPath.lastIndexOf(sep));
38
+ if (!existsSync(dirPath)) {
39
+ await mkdir(dirPath, { recursive: true });
40
+ }
41
+ await writeFile(tokenSetPath, JSON.stringify(tokenSet, null, 2), {
42
+ encoding: 'utf-8',
43
+ });
44
+ if (tokenSet) {
45
+ reply.send('Login successful');
46
+ eventEmitter.emit('cli-auth:login');
47
+ return;
48
+ }
49
+ reply.send('Login failed');
50
+ eventEmitter.emit('cli-auth:login-failed');
51
+ });
52
+ },
53
+ };
54
+ };
@@ -0,0 +1,7 @@
1
+ export const publish = (server) => {
2
+ return {
3
+ publish: async () => {
4
+ console.log('Publishing the plugin...');
5
+ },
6
+ };
7
+ };
@@ -0,0 +1,44 @@
1
+ import fastify from 'fastify';
2
+ import { env } from 'node:process';
3
+ import { Issuer } from 'openid-client';
4
+ import { auth } from './auth.js';
5
+
6
+ /**
7
+ * @param {{tokenSetPath: string}} config
8
+ * @returns
9
+ */
10
+ export const init = async (config) => {
11
+ if (!env.ISSUER_URL) {
12
+ console.error('Issuer URL not found');
13
+ return;
14
+ }
15
+ const issuer = await Issuer.discover(env.ISSUER_URL);
16
+ if (!issuer) {
17
+ console.error('Issuer not found');
18
+ return;
19
+ }
20
+ if (!env.IDS_CLIENT_ID || !env.IDS_CLIENT_SECRET) {
21
+ console.error('Client ID or Client Secret not found');
22
+ return;
23
+ }
24
+ const client = new issuer.Client({
25
+ client_id: env.IDS_CLIENT_ID,
26
+ client_secret: env.IDS_CLIENT_SECRET,
27
+ });
28
+ const server = fastify();
29
+ const auth_ = auth(client, config.tokenSetPath);
30
+ return {
31
+ start: async (eventEmitter) => {
32
+ const port = parseInt(env.PORT || '32231');
33
+ auth_.mount(server, eventEmitter);
34
+ await server.listen({
35
+ port,
36
+ });
37
+ return server;
38
+ },
39
+ stop: async () => {
40
+ await server.close();
41
+ return server;
42
+ },
43
+ };
44
+ };
@@ -0,0 +1,68 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { readFile, writeFile } from 'node:fs/promises';
3
+ import { env } from 'node:process';
4
+
5
+ export const authUtils = {
6
+ /**
7
+ * @param {import('openid-client').Client} client
8
+ * @param {{state: string, nonce: string}} authStateNonce
9
+ */
10
+ login: async (client, authStateNonce) => {
11
+ const authorizationRequest = {
12
+ redirect_uri: `http://localhost:${env.PORT}/login-callback`,
13
+ scope: 'openid profile email address phone offline_access user',
14
+ state: randomBytes(16).toString('hex'),
15
+ nonce: randomBytes(16).toString('hex'),
16
+ response_type: client.response_types[0],
17
+ prompt: 'consent',
18
+ };
19
+ authStateNonce.state = authorizationRequest.state;
20
+ authStateNonce.nonce = authorizationRequest.nonce;
21
+ const redirect = client.authorizationUrl(authorizationRequest);
22
+ return redirect;
23
+ },
24
+ /**
25
+ * @param {*} callbackParams
26
+ * @param {import('openid-client').Client} client
27
+ * @param {{state: string, nonce: string}} authStateNonce
28
+ * @returns {Promise<{redirect: string, tokenSet: null | any}>}
29
+ */
30
+ loginCallback: async (callbackParams, client, authStateNonce) => {
31
+ /** @type {{redirect: string, tokenSet: null | any}} */
32
+ const result = {
33
+ redirect: '',
34
+ tokenSet: null,
35
+ };
36
+ if (Object.keys(callbackParams).length === 0) {
37
+ result.redirect = '/login';
38
+ return result;
39
+ }
40
+ const tokenset = await client.callback(`http://localhost:${env.PORT}/login-callback`, callbackParams, {
41
+ nonce: authStateNonce.nonce,
42
+ state: authStateNonce.state,
43
+ });
44
+ authStateNonce.state = '';
45
+ authStateNonce.nonce = '';
46
+ result.tokenSet = tokenset;
47
+ result.redirect = '/login-success';
48
+ return result;
49
+ },
50
+ /**
51
+ * @param {import('openid-client').Client} client
52
+ * @param {string} tokenSetPath
53
+ * @returns {Promise<import('openid-client').IntrospectionResponse>}
54
+ */
55
+ verifyToken: async (client, tokenSetPath) => {
56
+ const tokenSet = JSON.parse(await readFile(tokenSetPath, 'utf-8'));
57
+ return await client.introspect(tokenSet.access_token);
58
+ },
59
+ /**
60
+ * @param {import('openid-client').Client} client
61
+ * @param {string} tokenSetPath
62
+ */
63
+ refreshToken: async (client, tokenSetPath) => {
64
+ const tokenSet = JSON.parse(await readFile(tokenSetPath, 'utf-8'));
65
+ const updatedTokenSet = await client.refresh(tokenSet.refresh_token);
66
+ await writeFile(tokenSetPath, JSON.stringify(updatedTokenSet, null, 2));
67
+ },
68
+ };