sn-typescript-util 1.4.2 → 1.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/README.md +2 -2
- package/bin/snts.js +88 -11
- package/bun.lockb +0 -0
- package/package.json +6 -6
- package/scripts/snts.ts +97 -11
- package/scripts/templates/base-table.ts +8 -0
- package/scripts/templates/tsconfig.json +1 -1
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Using TypeScript, the CLI provides an enhanced developer workflow.
|
|
|
29
29
|
|
|
30
30
|
- [Node.js](https://nodejs.org/)
|
|
31
31
|
- [ServiceNow Extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ServiceNow.now-vscode)
|
|
32
|
-
- An [imported application](https://docs.servicenow.com/bundle/
|
|
32
|
+
- An [imported application](https://docs.servicenow.com/bundle/washingtondc-application-development/page/build/applications/task/vscode-import-application.html) in VS Code
|
|
33
33
|
|
|
34
34
|
**[Back to top](#table-of-contents)**
|
|
35
35
|
|
|
@@ -59,7 +59,7 @@ After installation & setup, simply run the TypeScript compiler `--watch` command
|
|
|
59
59
|
tsc --watch
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
The TypeScript will get transpiled to ES5 (or other ECMAScript target) and moved to the `src` directory. Then changes are ready to sync with the target instance using the ServiceNow Extension for VS Code.
|
|
63
63
|
|
|
64
64
|
**[Back to top](#table-of-contents)**
|
|
65
65
|
|
package/bin/snts.js
CHANGED
|
@@ -3,21 +3,63 @@ import { $ } from 'execa';
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { execFile } from 'node:child_process';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
|
-
import { bold, cyan, gray, magenta, red } from 'colorette';
|
|
9
|
-
import { intro, outro, spinner } from '@clack/prompts';
|
|
8
|
+
import { bold, cyan, gray, green, magenta, red } from 'colorette';
|
|
9
|
+
import { confirm, intro, outro, select, spinner } from '@clack/prompts';
|
|
10
|
+
async function addFile(sourcefile, sourceDir, targetFile, targetDir, message) {
|
|
11
|
+
if (await confirmFile(message)) {
|
|
12
|
+
const file = await getTargetPath(targetFile, targetDir);
|
|
13
|
+
const filePath = getFilePath(sourcefile, sourceDir);
|
|
14
|
+
createFile(file, filePath);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function addInterfaceFile() {
|
|
18
|
+
return await addFile(
|
|
19
|
+
'base-table.ts',
|
|
20
|
+
'scripts/templates',
|
|
21
|
+
'BaseTable.ts',
|
|
22
|
+
'ts/Types',
|
|
23
|
+
`${getConstants().confirmInterfaceMsg}`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
async function addPrettierFile() {
|
|
27
|
+
return await addFile(
|
|
28
|
+
'.prettierrc.json',
|
|
29
|
+
'scripts/templates',
|
|
30
|
+
'.prettierrc.json',
|
|
31
|
+
null,
|
|
32
|
+
`${getConstants().confirmPrettierMsg}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
async function confirmFile(msg) {
|
|
36
|
+
return await confirm({
|
|
37
|
+
message: `${msg}`
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async function createFile(file, path) {
|
|
41
|
+
const template = readFileSync(path, 'utf8');
|
|
42
|
+
return await writeFile(file, template);
|
|
43
|
+
}
|
|
10
44
|
async function createTemplate(file, path) {
|
|
11
45
|
const project = await getProject();
|
|
12
46
|
const template = readFileSync(path, 'utf8');
|
|
13
|
-
const
|
|
14
|
-
return await writeFile(file,
|
|
47
|
+
const data = template.replace(/@project/g, project);
|
|
48
|
+
return await writeFile(file, data);
|
|
15
49
|
}
|
|
16
50
|
async function doBuild() {
|
|
17
|
-
|
|
51
|
+
introPrompt(`${bold(magenta(getConstants().projectName))}: Build`);
|
|
52
|
+
const esVersion = await getConfigTypes();
|
|
53
|
+
await addInterfaceFile();
|
|
54
|
+
await addPrettierFile();
|
|
55
|
+
await initGitRepo();
|
|
56
|
+
const s = startPrompts('Installing config(s)', null);
|
|
18
57
|
const filePath = getFilePath('tsconfig.json', 'scripts/templates');
|
|
19
58
|
await createTemplate('tsconfig.json', filePath);
|
|
20
|
-
|
|
59
|
+
const template = readFileSync('tsconfig.json', 'utf8');
|
|
60
|
+
const data = template.replace(/@version/g, esVersion);
|
|
61
|
+
await writeFile('tsconfig.json', data);
|
|
62
|
+
stopPrompt(s, `The ${cyan('tsconfig.json')} file was bootstrapped.`);
|
|
21
63
|
runSync();
|
|
22
64
|
}
|
|
23
65
|
async function doClean() {
|
|
@@ -43,16 +85,37 @@ async function doSync() {
|
|
|
43
85
|
return stdout;
|
|
44
86
|
});
|
|
45
87
|
}
|
|
88
|
+
function getConfigTargets() {
|
|
89
|
+
return [
|
|
90
|
+
{ value: 'es5', label: 'ES5', hint: 'recommended' },
|
|
91
|
+
{ value: 'es6', label: 'ES2015', hint: 'ES6' },
|
|
92
|
+
{ value: 'es2021', label: 'ES2021' }
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
async function getConfigTypes() {
|
|
96
|
+
return select({
|
|
97
|
+
message: 'Please pick a ECMAScript target.',
|
|
98
|
+
options: getConfigTargets()
|
|
99
|
+
});
|
|
100
|
+
}
|
|
46
101
|
function getConstants() {
|
|
47
102
|
let Constants;
|
|
48
103
|
(function (Constants) {
|
|
49
104
|
Constants['projectName'] = 'SN TypeScript Util';
|
|
50
105
|
Constants['projectDescription'] =
|
|
51
106
|
'is a TS utility for ServiceNow developers using VS Code.';
|
|
107
|
+
Constants[
|
|
108
|
+
(Constants['confirmInterfaceMsg'] =
|
|
109
|
+
`Add a ${cyan('BaseTable.ts')} interface with global default fields?`)
|
|
110
|
+
] = 'confirmInterfaceMsg';
|
|
111
|
+
Constants[
|
|
112
|
+
(Constants['confirmPrettierMsg'] =
|
|
113
|
+
`Add a ${cyan('.prettierrc.json')} default config?`)
|
|
114
|
+
] = 'confirmPrettierMsg';
|
|
52
115
|
Constants['errorMsg'] =
|
|
53
116
|
'No active application detected. Please create a project with the ServiceNow Extension for VS Code.';
|
|
54
117
|
Constants['docsUrl'] =
|
|
55
|
-
'https://docs.servicenow.com/bundle/
|
|
118
|
+
'https://docs.servicenow.com/bundle/washingtondc-application-development/page/build/applications/task/create-project.html';
|
|
56
119
|
Constants['buildOption'] =
|
|
57
120
|
'Build project utility files & package dependencies';
|
|
58
121
|
Constants['compileOption'] =
|
|
@@ -76,7 +139,7 @@ function getErrorMsg() {
|
|
|
76
139
|
const msg = `${constants.errorMsg}\n\n${constants.docsUrl}`;
|
|
77
140
|
return console.error(bold(red(msg)));
|
|
78
141
|
}
|
|
79
|
-
function getFilePath(file, dir
|
|
142
|
+
function getFilePath(file, dir) {
|
|
80
143
|
const fileName = fileURLToPath(import.meta.url);
|
|
81
144
|
const dirName = path.dirname(fileName);
|
|
82
145
|
return `${path.join(dirName, `../${dir}`)}/${file}`;
|
|
@@ -110,6 +173,12 @@ async function getProject() {
|
|
|
110
173
|
const workspace = await getWorkspace();
|
|
111
174
|
return workspace.ACTIVE_APPLICATION;
|
|
112
175
|
}
|
|
176
|
+
async function getTargetPath(file, dir) {
|
|
177
|
+
const project = await getProject();
|
|
178
|
+
const path = dir ? `${project}/${dir}/` : '.';
|
|
179
|
+
dir && !existsSync(path) && mkdirSync(path, { recursive: true });
|
|
180
|
+
return `${path}/${file}`;
|
|
181
|
+
}
|
|
113
182
|
async function getVersion() {
|
|
114
183
|
const info = await getPackageInfo();
|
|
115
184
|
return info.version;
|
|
@@ -157,6 +226,10 @@ async function init() {
|
|
|
157
226
|
program.usage(cyan('[options]'));
|
|
158
227
|
return doOptions(program);
|
|
159
228
|
}
|
|
229
|
+
async function initGitRepo() {
|
|
230
|
+
const msg = `Initialize a new git repository?`;
|
|
231
|
+
return (await confirmFile(msg)) && (await $`git init`);
|
|
232
|
+
}
|
|
160
233
|
function introPrompt(msg) {
|
|
161
234
|
return intro(msg);
|
|
162
235
|
}
|
|
@@ -165,10 +238,14 @@ function parseOptions(program) {
|
|
|
165
238
|
return options && Object.keys(program.opts()).toString();
|
|
166
239
|
}
|
|
167
240
|
async function runSync() {
|
|
241
|
+
const project = await getProject();
|
|
168
242
|
const s = startPrompts('Syncing', null);
|
|
169
243
|
return await execFile(getFilePath('sync.sh', 'scripts/build'), (stdout) => {
|
|
170
|
-
stopPrompt(
|
|
171
|
-
|
|
244
|
+
stopPrompt(
|
|
245
|
+
s,
|
|
246
|
+
`TypeScript files constructed in the ${cyan(project + '/ts')} directory.`
|
|
247
|
+
);
|
|
248
|
+
outro(`${green('Done!')}`);
|
|
172
249
|
return stdout;
|
|
173
250
|
});
|
|
174
251
|
}
|
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
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "A TypeScript utility for ServiceNow developers using VS Code",
|
|
5
5
|
"bin": {
|
|
6
6
|
"snts": "bin/snts.js"
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"@clack/prompts": "^0.7.0",
|
|
28
28
|
"colorette": "^2.0.20",
|
|
29
29
|
"commander": "^12.0.0",
|
|
30
|
-
"execa": "^
|
|
30
|
+
"execa": "^9.1.0",
|
|
31
31
|
"typescript": "^5.4.5"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@eslint/js": "^9.
|
|
34
|
+
"@eslint/js": "^9.3.0",
|
|
35
35
|
"@types/commander": "^2.12.2",
|
|
36
|
-
"bun-types": "^1.1.
|
|
37
|
-
"eslint": "^9.
|
|
36
|
+
"bun-types": "^1.1.8",
|
|
37
|
+
"eslint": "^9.3.0",
|
|
38
38
|
"prettier": "^3.2.5",
|
|
39
|
-
"typescript-eslint": "^7.
|
|
39
|
+
"typescript-eslint": "^7.9.0"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/scripts/snts.ts
CHANGED
|
@@ -4,25 +4,78 @@ import { $ } from 'execa';
|
|
|
4
4
|
import { Command } from 'commander';
|
|
5
5
|
import { execFile } from 'node:child_process';
|
|
6
6
|
import path from 'path';
|
|
7
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
|
-
import { bold, cyan, gray, magenta, red } from 'colorette';
|
|
10
|
-
import { intro, outro, spinner } from '@clack/prompts';
|
|
9
|
+
import { bold, cyan, gray, green, magenta, red } from 'colorette';
|
|
10
|
+
import { confirm, intro, outro, select, spinner } from '@clack/prompts';
|
|
11
11
|
import { Options } from './types/options.js';
|
|
12
12
|
import { Workspace } from './types/workspace.js';
|
|
13
13
|
|
|
14
|
+
async function addFile(
|
|
15
|
+
sourcefile: string,
|
|
16
|
+
sourceDir: string,
|
|
17
|
+
targetFile: string,
|
|
18
|
+
targetDir: string | any,
|
|
19
|
+
message: string
|
|
20
|
+
) {
|
|
21
|
+
if (await confirmFile(message)) {
|
|
22
|
+
const file = await getTargetPath(targetFile, targetDir);
|
|
23
|
+
const filePath = getFilePath(sourcefile, sourceDir);
|
|
24
|
+
createFile(file, filePath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function addInterfaceFile() {
|
|
29
|
+
return await addFile(
|
|
30
|
+
'base-table.ts',
|
|
31
|
+
'scripts/templates',
|
|
32
|
+
'BaseTable.ts',
|
|
33
|
+
'ts/Types',
|
|
34
|
+
`${getConstants().confirmInterfaceMsg}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function addPrettierFile() {
|
|
39
|
+
return await addFile(
|
|
40
|
+
'.prettierrc.json',
|
|
41
|
+
'scripts/templates',
|
|
42
|
+
'.prettierrc.json',
|
|
43
|
+
null,
|
|
44
|
+
`${getConstants().confirmPrettierMsg}`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function confirmFile(msg: string) {
|
|
49
|
+
return await confirm({
|
|
50
|
+
message: `${msg}`
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function createFile(file: string, path: string): Promise<void> {
|
|
55
|
+
const template = readFileSync(path, 'utf8');
|
|
56
|
+
return await writeFile(file, template);
|
|
57
|
+
}
|
|
58
|
+
|
|
14
59
|
async function createTemplate(file: string, path: string): Promise<void> {
|
|
15
60
|
const project = await getProject();
|
|
16
61
|
const template = readFileSync(path, 'utf8');
|
|
17
|
-
const
|
|
18
|
-
return await writeFile(file,
|
|
62
|
+
const data = template.replace(/@project/g, project);
|
|
63
|
+
return await writeFile(file, data);
|
|
19
64
|
}
|
|
20
65
|
|
|
21
66
|
async function doBuild() {
|
|
22
|
-
|
|
67
|
+
introPrompt(`${bold(magenta(getConstants().projectName))}: Build`);
|
|
68
|
+
const esVersion: any = await getConfigTypes();
|
|
69
|
+
await addInterfaceFile();
|
|
70
|
+
await addPrettierFile();
|
|
71
|
+
await initGitRepo();
|
|
72
|
+
const s = startPrompts('Installing config(s)', null);
|
|
23
73
|
const filePath = getFilePath('tsconfig.json', 'scripts/templates');
|
|
24
74
|
await createTemplate('tsconfig.json', filePath);
|
|
25
|
-
|
|
75
|
+
const template = readFileSync('tsconfig.json', 'utf8');
|
|
76
|
+
const data = template.replace(/@version/g, esVersion);
|
|
77
|
+
await writeFile('tsconfig.json', data);
|
|
78
|
+
stopPrompt(s, `The ${cyan('tsconfig.json')} file was bootstrapped.`);
|
|
26
79
|
runSync();
|
|
27
80
|
}
|
|
28
81
|
|
|
@@ -56,12 +109,29 @@ async function doSync() {
|
|
|
56
109
|
);
|
|
57
110
|
}
|
|
58
111
|
|
|
112
|
+
function getConfigTargets() {
|
|
113
|
+
return [
|
|
114
|
+
{ value: 'es5', label: 'ES5', hint: 'recommended' },
|
|
115
|
+
{ value: 'es6', label: 'ES2015', hint: 'ES6' },
|
|
116
|
+
{ value: 'es2021', label: 'ES2021' }
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function getConfigTypes() {
|
|
121
|
+
return select({
|
|
122
|
+
message: 'Please pick a ECMAScript target.',
|
|
123
|
+
options: getConfigTargets()
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
59
127
|
function getConstants() {
|
|
60
128
|
enum Constants {
|
|
61
129
|
projectName = 'SN TypeScript Util',
|
|
62
130
|
projectDescription = 'is a TS utility for ServiceNow developers using VS Code.',
|
|
131
|
+
confirmInterfaceMsg = `Add a ${cyan('BaseTable.ts')} interface with global default fields?`,
|
|
132
|
+
confirmPrettierMsg = `Add a ${cyan('.prettierrc.json')} default config?`,
|
|
63
133
|
errorMsg = 'No active application detected. Please create a project with the ServiceNow Extension for VS Code.',
|
|
64
|
-
docsUrl = 'https://docs.servicenow.com/bundle/
|
|
134
|
+
docsUrl = 'https://docs.servicenow.com/bundle/washingtondc-application-development/page/build/applications/task/create-project.html',
|
|
65
135
|
buildOption = 'Build project utility files & package dependencies',
|
|
66
136
|
compileOption = 'Compile TypeScript files to JavaScript & move to src',
|
|
67
137
|
helpOption = 'Display help for command',
|
|
@@ -85,7 +155,7 @@ function getErrorMsg() {
|
|
|
85
155
|
return console.error(bold(red(msg)));
|
|
86
156
|
}
|
|
87
157
|
|
|
88
|
-
function getFilePath(file: string, dir: string
|
|
158
|
+
function getFilePath(file: string, dir: string) {
|
|
89
159
|
const fileName = fileURLToPath(import.meta.url);
|
|
90
160
|
const dirName = path.dirname(fileName);
|
|
91
161
|
return `${path.join(dirName, `../${dir}`)}/${file}`;
|
|
@@ -123,6 +193,13 @@ async function getProject() {
|
|
|
123
193
|
return workspace.ACTIVE_APPLICATION;
|
|
124
194
|
}
|
|
125
195
|
|
|
196
|
+
async function getTargetPath(file: string, dir: string) {
|
|
197
|
+
const project = await getProject();
|
|
198
|
+
const path = dir ? `${project}/${dir}/` : '.';
|
|
199
|
+
dir && !existsSync(path) && mkdirSync(path, { recursive: true });
|
|
200
|
+
return `${path}/${file}`;
|
|
201
|
+
}
|
|
202
|
+
|
|
126
203
|
async function getVersion() {
|
|
127
204
|
const info = await getPackageInfo();
|
|
128
205
|
return info.version;
|
|
@@ -181,6 +258,11 @@ async function init() {
|
|
|
181
258
|
return doOptions(program);
|
|
182
259
|
}
|
|
183
260
|
|
|
261
|
+
async function initGitRepo() {
|
|
262
|
+
const msg = `Initialize a new git repository?`;
|
|
263
|
+
return (await confirmFile(msg)) && (await $`git init`);
|
|
264
|
+
}
|
|
265
|
+
|
|
184
266
|
function introPrompt(msg: string) {
|
|
185
267
|
return intro(msg);
|
|
186
268
|
}
|
|
@@ -191,12 +273,16 @@ function parseOptions(program: Command) {
|
|
|
191
273
|
}
|
|
192
274
|
|
|
193
275
|
async function runSync() {
|
|
276
|
+
const project = await getProject();
|
|
194
277
|
const s = startPrompts('Syncing', null);
|
|
195
278
|
return await execFile(
|
|
196
279
|
getFilePath('sync.sh', 'scripts/build'),
|
|
197
280
|
(stdout: unknown) => {
|
|
198
|
-
stopPrompt(
|
|
199
|
-
|
|
281
|
+
stopPrompt(
|
|
282
|
+
s,
|
|
283
|
+
`TypeScript files constructed in the ${cyan(project + '/ts')} directory.`
|
|
284
|
+
);
|
|
285
|
+
outro(`${green('Done!')}`);
|
|
200
286
|
return stdout;
|
|
201
287
|
}
|
|
202
288
|
);
|