sn-typescript-util 1.3.2 → 1.3.4
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 +49 -2
- package/bin/snts.js +81 -79
- package/bun.lockb +0 -0
- package/package.json +8 -8
- package/scripts/options.ts +6 -0
- package/scripts/snts.ts +22 -6
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ A [TypeScript](https://www.typescriptlang.org/) CLI utility that works on-top of
|
|
|
11
11
|
1. [Installation and Setup](#installation-and-setup)
|
|
12
12
|
1. [Basic Workflow](#basic-workflow)
|
|
13
13
|
1. [Commands](#commands)
|
|
14
|
+
1. [Project Structure](#project-structure)
|
|
14
15
|
1. [License](#license)
|
|
15
16
|
|
|
16
17
|
## Benefits
|
|
@@ -27,9 +28,9 @@ Using TypeScript, the CLI provides an enhanced developer workflow.
|
|
|
27
28
|
## Prerequisites
|
|
28
29
|
|
|
29
30
|
- [Node.js](https://nodejs.org/)
|
|
30
|
-
- [
|
|
31
|
+
- [Ruby](https://www.ruby-lang.org/en/documentation/installation/)
|
|
31
32
|
- [ServiceNow Extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ServiceNow.now-vscode)
|
|
32
|
-
-
|
|
33
|
+
- An [imported application](https://docs.servicenow.com/bundle/vancouver-application-development/page/build/applications/task/vscode-import-application.html) in VS Code
|
|
33
34
|
|
|
34
35
|
**[Back to top](#table-of-contents)**
|
|
35
36
|
|
|
@@ -137,6 +138,52 @@ snts -V
|
|
|
137
138
|
|
|
138
139
|
**[Back to top](#table-of-contents)**
|
|
139
140
|
|
|
141
|
+
## Project Structure
|
|
142
|
+
|
|
143
|
+
Inside of the application directory (after the build), the project structure will look something like this.
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
/
|
|
147
|
+
├── background scripts/
|
|
148
|
+
├── scratch/
|
|
149
|
+
├── src/
|
|
150
|
+
│ ├── Server Development/
|
|
151
|
+
│ │ └── Script Includes/
|
|
152
|
+
│ │ └── DataService.script.js
|
|
153
|
+
│ │ └── Utils.script.js
|
|
154
|
+
│ └── Service Portal/
|
|
155
|
+
│ └── Widgets/
|
|
156
|
+
│ └── Dashboard/
|
|
157
|
+
│ └── Dashboard.client_script.js
|
|
158
|
+
│ └── Dashboard.css.scss
|
|
159
|
+
│ └── Dashboard.demo_data.json
|
|
160
|
+
│ └── Dashboard.link.js
|
|
161
|
+
│ └── Dashboard.option_schema.json
|
|
162
|
+
│ └── Dashboard.script.js
|
|
163
|
+
│ └── Dashboard.template.html
|
|
164
|
+
├── system/
|
|
165
|
+
├── ts/
|
|
166
|
+
│ ├── Server Development/
|
|
167
|
+
│ │ └── Script Includes/
|
|
168
|
+
│ │ └── DataService.script.ts
|
|
169
|
+
│ │ └── Utils.script.ts
|
|
170
|
+
│ ├── Service Portal/
|
|
171
|
+
│ │ └── Widgets/
|
|
172
|
+
│ │ └── Dashboard/
|
|
173
|
+
│ │ └── Dashboard.client_script.ts
|
|
174
|
+
│ │ └── Dashboard.link.ts
|
|
175
|
+
│ │ └── Dashboard.script.ts
|
|
176
|
+
│ └── Types/
|
|
177
|
+
│ └── Table.ts
|
|
178
|
+
│ └── User.ts
|
|
179
|
+
├── .eslintrc
|
|
180
|
+
└── app.config.json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This example project has two script includes, a widget, and a `Types` directory for interfaces & types.
|
|
184
|
+
|
|
185
|
+
**[Back to top](#table-of-contents)**
|
|
186
|
+
|
|
140
187
|
## License
|
|
141
188
|
|
|
142
189
|
[MIT License](LICENSE)
|
package/bin/snts.js
CHANGED
|
@@ -7,111 +7,113 @@ import { fileURLToPath } from 'url';
|
|
|
7
7
|
import { bold, red } from 'colorette';
|
|
8
8
|
import { intro, outro, spinner } from '@clack/prompts';
|
|
9
9
|
async function doBuild() {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const s = startPrompts('Installing configs', 'Build started');
|
|
11
|
+
return await execFile(getFilePath('init.rb'), (stdout) => {
|
|
12
|
+
stopPrompt(s, 'Configs installed');
|
|
13
|
+
runSync();
|
|
14
|
+
return stdout;
|
|
15
|
+
});
|
|
16
16
|
}
|
|
17
17
|
async function doCompile() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
const s = startPrompts('Processing', 'Compile started');
|
|
19
|
+
return await execFile(getFilePath('compile.rb'), (stdout) => {
|
|
20
|
+
stopPrompt(s, 'Completed');
|
|
21
|
+
return stdout;
|
|
22
|
+
});
|
|
23
23
|
}
|
|
24
24
|
function doOptions(program) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
25
|
+
program.parse(process.argv).opts();
|
|
26
|
+
const option = Object.keys(program.opts()).toString();
|
|
27
|
+
const options = {
|
|
28
|
+
build: () => {
|
|
29
|
+
doBuild();
|
|
30
|
+
},
|
|
31
|
+
compile: () => {
|
|
32
|
+
doCompile();
|
|
33
|
+
},
|
|
34
|
+
sync: () => {
|
|
35
|
+
doSync();
|
|
36
|
+
},
|
|
37
|
+
default: () => {
|
|
38
|
+
program.help();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return handleOptions(program, options, option);
|
|
42
42
|
}
|
|
43
43
|
async function doSync() {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
const s = startPrompts('Processing', 'Sync started');
|
|
45
|
+
return await execFile(getFilePath('sync.sh'), (stdout) => {
|
|
46
|
+
stopPrompt(s, 'Completed');
|
|
47
|
+
return stdout;
|
|
48
|
+
});
|
|
49
49
|
}
|
|
50
50
|
function getErrorMsg() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const url = `https://docs.servicenow.com/bundle/vancouver-application-development/page/build/applications/task/create-project.html`;
|
|
52
|
+
const msg = `No active application detected. Please create a project with the ServiceNow Extension for VS Code.\n\n${url}`;
|
|
53
|
+
return console.error(bold(red(msg)));
|
|
54
54
|
}
|
|
55
55
|
function getFilePath(file, dir = 'scripts') {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const fileName = fileURLToPath(import.meta.url);
|
|
57
|
+
const dirName = path.dirname(fileName);
|
|
58
|
+
return `${path.join(dirName, `../${dir}`)}/${file}`;
|
|
59
59
|
}
|
|
60
60
|
async function getPackageInfo() {
|
|
61
|
-
|
|
61
|
+
return JSON.parse(readFileSync(getFilePath('package.json', '.')).toString());
|
|
62
62
|
}
|
|
63
63
|
function getWorkspace() {
|
|
64
|
-
|
|
64
|
+
return JSON.parse(readFileSync('./system/sn-workspace.json').toString());
|
|
65
|
+
}
|
|
66
|
+
function handleOptions(program, options, option) {
|
|
67
|
+
return (shouldShowHelp(program, option) ||
|
|
68
|
+
((hasApplication() && options[option]) || showHelp(program))());
|
|
65
69
|
}
|
|
66
70
|
async function hasApplication() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
try {
|
|
72
|
+
const workspace = await getWorkspace();
|
|
73
|
+
const app = workspace.ACTIVE_APPLICATION;
|
|
74
|
+
return Object.entries(app).length === 0 ? getErrorMsg() : true;
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
getErrorMsg();
|
|
78
|
+
return process.exit(1);
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
81
|
(async () => {
|
|
77
|
-
|
|
82
|
+
return init();
|
|
78
83
|
})();
|
|
79
84
|
async function init() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
'-
|
|
86
|
-
'
|
|
87
|
-
|
|
88
|
-
program.option(
|
|
89
|
-
'-c, --compile',
|
|
90
|
-
'compile TypeScript files to JavaScript & move to src'
|
|
91
|
-
);
|
|
92
|
-
program.option(
|
|
93
|
-
'-s, --sync',
|
|
94
|
-
'sync new instance-based src files to the ts directory'
|
|
95
|
-
);
|
|
96
|
-
return doOptions(program);
|
|
85
|
+
const program = new Command();
|
|
86
|
+
const info = await getPackageInfo();
|
|
87
|
+
program.description(info.description);
|
|
88
|
+
program.version(info.version);
|
|
89
|
+
program.option('-b, --build', 'build project utility files & package dependencies');
|
|
90
|
+
program.option('-c, --compile', 'compile TypeScript files to JavaScript & move to src');
|
|
91
|
+
program.option('-s, --sync', 'sync new instance-based src files to the ts directory');
|
|
92
|
+
return doOptions(program);
|
|
97
93
|
}
|
|
98
94
|
function introPrompt(msg) {
|
|
99
|
-
|
|
95
|
+
return intro(msg);
|
|
100
96
|
}
|
|
101
97
|
async function runSync() {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
const s = startPrompts('Syncing', null);
|
|
99
|
+
return await execFile(getFilePath('sync.sh'), (stdout) => {
|
|
100
|
+
stopPrompt(s, 'Sync completed');
|
|
101
|
+
outro('Completed');
|
|
102
|
+
return stdout;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function shouldShowHelp(program, option) {
|
|
106
|
+
return !option && showHelp(program);
|
|
107
|
+
}
|
|
108
|
+
function showHelp(program) {
|
|
109
|
+
return program.help();
|
|
108
110
|
}
|
|
109
111
|
function startPrompts(start, intro) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
intro && introPrompt(intro);
|
|
113
|
+
const s = spinner();
|
|
114
|
+
s.start(start);
|
|
115
|
+
return s;
|
|
114
116
|
}
|
|
115
117
|
function stopPrompt(spinner, msg) {
|
|
116
|
-
|
|
118
|
+
return spinner.stop(msg);
|
|
117
119
|
}
|
package/bun.lockb
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sn-typescript-util",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "A TypeScript utility for ServiceNow developers using VS Code",
|
|
5
5
|
"bin": {
|
|
6
6
|
"snts": "bin/snts.js"
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
"type": "module",
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@clack/prompts": "^0.7.0",
|
|
28
|
-
"@types/servicenow": "^10.0.
|
|
28
|
+
"@types/servicenow": "^10.0.4",
|
|
29
29
|
"colorette": "^2.0.20",
|
|
30
30
|
"commander": "^11.1.0",
|
|
31
31
|
"npm-add-script": "^1.1.0",
|
|
32
|
-
"typescript": "^5.
|
|
32
|
+
"typescript": "^5.3.3"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
36
|
-
"@typescript-eslint/parser": "^6.
|
|
37
|
-
"bun-types": "^1.0.
|
|
38
|
-
"eslint": "^8.
|
|
39
|
-
"prettier": "^3.
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
|
36
|
+
"@typescript-eslint/parser": "^6.15.0",
|
|
37
|
+
"bun-types": "^1.0.18-1",
|
|
38
|
+
"eslint": "^8.56.0",
|
|
39
|
+
"prettier": "^3.1.1"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/scripts/snts.ts
CHANGED
|
@@ -7,11 +7,12 @@ import { readFileSync } from 'fs';
|
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { bold, red } from 'colorette';
|
|
9
9
|
import { intro, outro, spinner } from '@clack/prompts';
|
|
10
|
+
import { Options } from './options.js';
|
|
10
11
|
import { Workspace } from './workspace.js';
|
|
11
12
|
|
|
12
13
|
async function doBuild() {
|
|
13
14
|
const s = startPrompts('Installing configs', 'Build started');
|
|
14
|
-
return await execFile(getFilePath('init.rb'), (stdout) => {
|
|
15
|
+
return await execFile(getFilePath('init.rb'), (stdout: unknown) => {
|
|
15
16
|
stopPrompt(s, 'Configs installed');
|
|
16
17
|
runSync();
|
|
17
18
|
return stdout;
|
|
@@ -20,7 +21,7 @@ async function doBuild() {
|
|
|
20
21
|
|
|
21
22
|
async function doCompile() {
|
|
22
23
|
const s = startPrompts('Processing', 'Compile started');
|
|
23
|
-
return await execFile(getFilePath('compile.rb'), (stdout) => {
|
|
24
|
+
return await execFile(getFilePath('compile.rb'), (stdout: unknown) => {
|
|
24
25
|
stopPrompt(s, 'Completed');
|
|
25
26
|
return stdout;
|
|
26
27
|
});
|
|
@@ -29,7 +30,7 @@ async function doCompile() {
|
|
|
29
30
|
function doOptions(program: any) {
|
|
30
31
|
program.parse(process.argv).opts();
|
|
31
32
|
const option: string = Object.keys(program.opts()).toString();
|
|
32
|
-
const options:
|
|
33
|
+
const options: Options = {
|
|
33
34
|
build: () => {
|
|
34
35
|
doBuild();
|
|
35
36
|
},
|
|
@@ -43,12 +44,12 @@ function doOptions(program: any) {
|
|
|
43
44
|
program.help();
|
|
44
45
|
}
|
|
45
46
|
};
|
|
46
|
-
return (
|
|
47
|
+
return handleOptions(program, options, option);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
async function doSync() {
|
|
50
51
|
const s = startPrompts('Processing', 'Sync started');
|
|
51
|
-
return await execFile(getFilePath('sync.sh'), (stdout:
|
|
52
|
+
return await execFile(getFilePath('sync.sh'), (stdout: unknown) => {
|
|
52
53
|
stopPrompt(s, 'Completed');
|
|
53
54
|
return stdout;
|
|
54
55
|
});
|
|
@@ -74,6 +75,13 @@ function getWorkspace() {
|
|
|
74
75
|
return JSON.parse(readFileSync('./system/sn-workspace.json').toString());
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
function handleOptions(program: any, options: Options, option: string) {
|
|
79
|
+
return (
|
|
80
|
+
shouldShowHelp(program, option) ||
|
|
81
|
+
((hasApplication() && options[option]) || showHelp(program))()
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
async function hasApplication() {
|
|
78
86
|
try {
|
|
79
87
|
const workspace: Workspace = await getWorkspace();
|
|
@@ -115,13 +123,21 @@ function introPrompt(msg: string) {
|
|
|
115
123
|
|
|
116
124
|
async function runSync() {
|
|
117
125
|
const s = startPrompts('Syncing', null);
|
|
118
|
-
return await execFile(getFilePath('sync.sh'), (stdout) => {
|
|
126
|
+
return await execFile(getFilePath('sync.sh'), (stdout: unknown) => {
|
|
119
127
|
stopPrompt(s, 'Sync completed');
|
|
120
128
|
outro('Completed');
|
|
121
129
|
return stdout;
|
|
122
130
|
});
|
|
123
131
|
}
|
|
124
132
|
|
|
133
|
+
function shouldShowHelp(program: any, option: string) {
|
|
134
|
+
return !option && showHelp(program);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function showHelp(program: any) {
|
|
138
|
+
return program.help();
|
|
139
|
+
}
|
|
140
|
+
|
|
125
141
|
function startPrompts(start: string, intro: string | null) {
|
|
126
142
|
intro && introPrompt(intro);
|
|
127
143
|
const s = spinner();
|