@jacebenson/jsn 3.4.3 → 4.0.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.
Files changed (40) hide show
  1. package/README.md +5 -4
  2. package/package.json +3 -1
  3. package/skills/servicenow/SKILL.md +3 -3
  4. package/src/app.js +7 -7
  5. package/src/auth.js +34 -63
  6. package/src/cli.js +27 -20
  7. package/src/commands/_ticket.js +7 -1
  8. package/src/commands/auth.js +303 -40
  9. package/src/commands/catalog.js +3 -4
  10. package/src/commands/dev/_generic.js +7 -14
  11. package/src/commands/dev/flows.js +110 -2
  12. package/src/commands/dev/forms.js +0 -11
  13. package/src/commands/dev/import.js +1 -1
  14. package/src/commands/dev/lists.js +2 -2
  15. package/src/commands/dev/updatesets.js +0 -16
  16. package/src/commands/docs/community-sources.json +18 -0
  17. package/src/commands/docs/community.js +343 -0
  18. package/src/commands/docs/db.js +38 -2
  19. package/src/commands/docs/docs.js +41 -0
  20. package/src/commands/docs/ingest.js +4 -17
  21. package/src/commands/docs/refresh.js +4 -17
  22. package/src/commands/docs/search.js +3 -3
  23. package/src/commands/docs/serve.js +2 -2
  24. package/src/commands/grouproles.js +5 -1
  25. package/src/commands/groups.js +6 -3
  26. package/src/commands/records.js +5 -2
  27. package/src/commands/requests.js +2 -1
  28. package/src/commands/setup.js +10 -84
  29. package/src/commands/skill.js +5 -7
  30. package/src/commands/tickets.js +4 -1
  31. package/src/commands/users.js +4 -1
  32. package/src/config.js +9 -0
  33. package/src/errors.js +26 -0
  34. package/src/help.js +2 -4
  35. package/src/helpers.js +65 -8
  36. package/src/mutations.js +40 -9
  37. package/src/output.js +6 -3
  38. package/src/paginated-search.js +1 -1
  39. package/src/records/inspect.js +2 -1
  40. package/src/commands/profiles.js +0 -190
@@ -1,190 +0,0 @@
1
- import { normalizeInstanceURL, saveConfig, setProfile } from '../config.js';
2
-
3
- export function profilesCmd(wrap) {
4
- return {
5
- command: 'profiles [subcommand]',
6
- aliases: ['profile'],
7
- describe: 'Manage configuration profiles',
8
- builder: (yargs) => {
9
- return yargs
10
- .command({
11
- command: 'create <name>',
12
- describe: 'Create a new profile',
13
- builder: (sub) => sub
14
- .positional('name', {
15
- describe: 'Profile name',
16
- type: 'string',
17
- })
18
- .option('instance', {
19
- alias: 'i',
20
- describe: 'ServiceNow instance URL (e.g. dev12345.service-now.com)',
21
- type: 'string',
22
- })
23
- .option('username', {
24
- alias: 'u',
25
- describe: 'Username for basic auth',
26
- type: 'string',
27
- })
28
- .option('password', {
29
- alias: 'p',
30
- describe: 'Password for basic auth',
31
- type: 'string',
32
- })
33
- .option('read-only', {
34
- describe: 'Mark profile as read-only (blocks mutation commands)',
35
- type: 'boolean',
36
- default: false,
37
- }),
38
- handler: wrap(async (argv, app) => {
39
- const name = argv.name;
40
- if (app.config.profiles && app.config.profiles[name]) {
41
- throw new Error(`Profile "${name}" already exists. Use "jsn profiles update" or remove it first.`);
42
- }
43
-
44
- let instance = argv.instance;
45
- if (!instance) {
46
- throw new Error(`Instance URL is required.\n\n jsn profiles create ${name} --instance https://dev12345.service-now.com`);
47
- }
48
- instance = normalizeInstanceURL(instance);
49
-
50
- const profile = { instance_url: instance };
51
-
52
- // If username/password provided, save credentials too
53
- if (argv.username && argv.password) {
54
- const { saveCredentials } = await import('../auth.js');
55
- saveCredentials(instance, {
56
- auth_method: 'basic',
57
- username: argv.username,
58
- password: argv.password,
59
- }, argv.username);
60
- profile.auth_method = 'basic';
61
- profile.username = argv.username;
62
- }
63
-
64
- // If read-only flag is set, mark the profile
65
- if (argv['read-only']) {
66
- profile.read_only = true;
67
- }
68
-
69
- await setProfile(app.config, name, profile);
70
-
71
- app.ok({
72
- profile: name,
73
- instance,
74
- auth_method: profile.auth_method || 'oauth (not yet logged in)',
75
- }, { summary: `Profile "${name}" created for ${instance}` });
76
- }),
77
- })
78
- .command({
79
- command: 'list',
80
- describe: 'List all profiles',
81
- handler: wrap(async (_argv, app) => {
82
- const profiles = [];
83
- for (const [name, profile] of Object.entries(app.config.profiles || {})) {
84
- const instance = profile.instance_url || '';
85
- const isAuth = app.auth.isAuthenticatedFor(instance);
86
- const isDefault = name === app.config.defaultProfile;
87
- profiles.push({
88
- name,
89
- instance,
90
- username: profile.username || '',
91
- authenticated: isAuth,
92
- default: isDefault,
93
- read_only: profile.read_only || false,
94
- });
95
- }
96
-
97
- // Build context-aware breadcrumb: suggest switching to a non-active profile
98
- const breadcrumbs = [];
99
- if (profiles.length > 0) {
100
- const activeName = app.config.activeProfile || app.config.defaultProfile;
101
- const nonActiveProfiles = profiles.filter(p => p.name !== activeName);
102
- if (nonActiveProfiles.length > 0) {
103
- const suggestName = nonActiveProfiles[0].name;
104
- breadcrumbs.push({
105
- action: 'switch',
106
- cmd: `jsn profiles use ${suggestName}`,
107
- description: 'Switch to a different profile',
108
- });
109
- }
110
- }
111
-
112
- app.ok({ profiles }, { summary: `${profiles.length} profile(s)`, breadcrumbs });
113
- }),
114
- })
115
- .command({
116
- command: 'use <name>',
117
- describe: 'Set active profile',
118
- handler: wrap(async (argv, app) => {
119
- const name = argv.name;
120
- if (!app.config.profiles[name]) {
121
- throw new Error(`Profile not found: ${name}`);
122
- }
123
- app.config.defaultProfile = name;
124
- app.config.activeProfile = name;
125
- saveConfig(app.config);
126
- app.ok({ active_profile: name }, { summary: `Active profile: ${name}` });
127
- }),
128
- })
129
- .command({
130
- command: 'show [name]',
131
- describe: 'Show profile details',
132
- handler: wrap(async (argv, app) => {
133
- const name = argv.name || app.config.defaultProfile || Object.keys(app.config.profiles || {})[0];
134
- if (!name || !app.config.profiles[name]) {
135
- throw new Error('No profiles configured');
136
- }
137
- const profile = app.config.profiles[name];
138
- const readOnlyNote = profile.read_only ? ' [READ-ONLY]' : '';
139
- app.ok({ name, ...profile }, { summary: `Profile: ${name}${readOnlyNote}` });
140
- }),
141
- })
142
- .command({
143
- command: 'remove <name>',
144
- describe: 'Remove a profile',
145
- handler: wrap(async (argv, app) => {
146
- const name = argv.name;
147
- if (!app.config.profiles[name]) {
148
- throw new Error(`Profile not found: ${name}`);
149
- }
150
- const instance = app.config.profiles[name].instance_url;
151
- delete app.config.profiles[name];
152
- if (app.config.defaultProfile === name) {
153
- app.config.defaultProfile = '';
154
- }
155
- if (app.config.activeProfile === name) {
156
- app.config.activeProfile = '';
157
- }
158
- saveConfig(app.config);
159
-
160
- // Only clean up credentials if no other profile uses this instance URL
161
- const stillInUse = instance && Object.values(app.config.profiles || {})
162
- .some(p => p.instance_url === instance);
163
- if (instance && !stillInUse) {
164
- app.auth.logout(instance);
165
- }
166
-
167
- app.ok({ removed: name }, { summary: `Removed profile: ${name}` });
168
- }),
169
- })
170
-
171
- },
172
- handler: (argv) => {
173
- // When no subcommand is given, show help
174
- if (!argv._[1]) {
175
- console.log('Manage your ServiceNow instance profiles.\n');
176
- console.log('Usage: jsn profiles <create|list|show|use|remove> [options]\n');
177
- console.log('Commands:');
178
- console.log(' create <name> Create a new profile (--instance required)');
179
- console.log(' list List all profiles');
180
- console.log(' show [name] Show profile details');
181
- console.log(' use <name> Switch to a different profile');
182
- console.log(' remove <name> Remove a profile');
183
- console.log('\nRun "jsn profiles <command> --help" for more details.');
184
- console.log('\nNote: You can also create a profile by authenticating:');
185
- console.log(' jsn auth login --profile <name> <instance-url>');
186
- console.log(' jsn auth login --profile staging --password https://dev12345.service-now.com');
187
- }
188
- },
189
- };
190
- }