sn-typescript-util 1.4.1 → 1.5.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.
- package/README.md +1 -1
- package/bin/snts.js +83 -11
- package/bun.lockb +0 -0
- package/package.json +6 -6
- package/scripts/snts.ts +91 -11
- package/scripts/templates/base-table.ts +8 -0
- package/scripts/templates/tsconfig.json +1 -1
- package/tsconfig.json +3 -2
- package/.eslintrc.yml +0 -4
package/README.md
CHANGED
|
@@ -181,7 +181,7 @@ Inside of the application directory (after the build), the project structure wil
|
|
|
181
181
|
│ │ └── Dashboard.link.ts
|
|
182
182
|
│ │ └── Dashboard.script.ts
|
|
183
183
|
│ └── Types/
|
|
184
|
-
│ └──
|
|
184
|
+
│ └── BaseTable.ts
|
|
185
185
|
│ └── User.ts
|
|
186
186
|
├── .eslintrc
|
|
187
187
|
└── app.config.json
|
package/bin/snts.js
CHANGED
|
@@ -3,21 +3,62 @@ 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
|
+
const s = startPrompts('Installing config(s)', null);
|
|
18
56
|
const filePath = getFilePath('tsconfig.json', 'scripts/templates');
|
|
19
57
|
await createTemplate('tsconfig.json', filePath);
|
|
20
|
-
|
|
58
|
+
const template = readFileSync('tsconfig.json', 'utf8');
|
|
59
|
+
const data = template.replace(/@version/g, esVersion);
|
|
60
|
+
await writeFile('tsconfig.json', data);
|
|
61
|
+
stopPrompt(s, `The ${cyan('tsconfig.json')} file was bootstrapped.`);
|
|
21
62
|
runSync();
|
|
22
63
|
}
|
|
23
64
|
async function doClean() {
|
|
@@ -43,16 +84,37 @@ async function doSync() {
|
|
|
43
84
|
return stdout;
|
|
44
85
|
});
|
|
45
86
|
}
|
|
87
|
+
function getConfigTargets() {
|
|
88
|
+
return [
|
|
89
|
+
{ value: 'es5', label: 'ES5', hint: 'recommended' },
|
|
90
|
+
{ value: 'es6', label: 'ES2015', hint: 'ES6' },
|
|
91
|
+
{ value: 'es2021', label: 'ES2021' }
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
async function getConfigTypes() {
|
|
95
|
+
return select({
|
|
96
|
+
message: 'Please pick a ECMAScript target.',
|
|
97
|
+
options: getConfigTargets()
|
|
98
|
+
});
|
|
99
|
+
}
|
|
46
100
|
function getConstants() {
|
|
47
101
|
let Constants;
|
|
48
102
|
(function (Constants) {
|
|
49
103
|
Constants['projectName'] = 'SN TypeScript Util';
|
|
50
104
|
Constants['projectDescription'] =
|
|
51
105
|
'is a TS utility for ServiceNow developers using VS Code.';
|
|
106
|
+
Constants[
|
|
107
|
+
(Constants['confirmInterfaceMsg'] =
|
|
108
|
+
`Add a ${cyan('BaseTable.ts')} interface with global default fields?`)
|
|
109
|
+
] = 'confirmInterfaceMsg';
|
|
110
|
+
Constants[
|
|
111
|
+
(Constants['confirmPrettierMsg'] =
|
|
112
|
+
`Add a ${cyan('.prettierrc.json')} default config?`)
|
|
113
|
+
] = 'confirmPrettierMsg';
|
|
52
114
|
Constants['errorMsg'] =
|
|
53
115
|
'No active application detected. Please create a project with the ServiceNow Extension for VS Code.';
|
|
54
116
|
Constants['docsUrl'] =
|
|
55
|
-
'https://docs.servicenow.com/bundle/
|
|
117
|
+
'https://docs.servicenow.com/bundle/washingtondc-application-development/page/build/applications/task/create-project.html';
|
|
56
118
|
Constants['buildOption'] =
|
|
57
119
|
'Build project utility files & package dependencies';
|
|
58
120
|
Constants['compileOption'] =
|
|
@@ -76,7 +138,7 @@ function getErrorMsg() {
|
|
|
76
138
|
const msg = `${constants.errorMsg}\n\n${constants.docsUrl}`;
|
|
77
139
|
return console.error(bold(red(msg)));
|
|
78
140
|
}
|
|
79
|
-
function getFilePath(file, dir
|
|
141
|
+
function getFilePath(file, dir) {
|
|
80
142
|
const fileName = fileURLToPath(import.meta.url);
|
|
81
143
|
const dirName = path.dirname(fileName);
|
|
82
144
|
return `${path.join(dirName, `../${dir}`)}/${file}`;
|
|
@@ -110,6 +172,12 @@ async function getProject() {
|
|
|
110
172
|
const workspace = await getWorkspace();
|
|
111
173
|
return workspace.ACTIVE_APPLICATION;
|
|
112
174
|
}
|
|
175
|
+
async function getTargetPath(file, dir) {
|
|
176
|
+
const project = await getProject();
|
|
177
|
+
const path = dir ? `${project}/${dir}/` : '.';
|
|
178
|
+
dir && !existsSync(path) && mkdirSync(path, { recursive: true });
|
|
179
|
+
return `${path}/${file}`;
|
|
180
|
+
}
|
|
113
181
|
async function getVersion() {
|
|
114
182
|
const info = await getPackageInfo();
|
|
115
183
|
return info.version;
|
|
@@ -165,10 +233,14 @@ function parseOptions(program) {
|
|
|
165
233
|
return options && Object.keys(program.opts()).toString();
|
|
166
234
|
}
|
|
167
235
|
async function runSync() {
|
|
236
|
+
const project = await getProject();
|
|
168
237
|
const s = startPrompts('Syncing', null);
|
|
169
238
|
return await execFile(getFilePath('sync.sh', 'scripts/build'), (stdout) => {
|
|
170
|
-
stopPrompt(
|
|
171
|
-
|
|
239
|
+
stopPrompt(
|
|
240
|
+
s,
|
|
241
|
+
`TypeScript files constructed in the ${cyan(project + '/ts')} directory.`
|
|
242
|
+
);
|
|
243
|
+
outro(`${green('Done!')}`);
|
|
172
244
|
return stdout;
|
|
173
245
|
});
|
|
174
246
|
}
|
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.0",
|
|
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,77 @@ 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
|
+
const s = startPrompts('Installing config(s)', null);
|
|
23
72
|
const filePath = getFilePath('tsconfig.json', 'scripts/templates');
|
|
24
73
|
await createTemplate('tsconfig.json', filePath);
|
|
25
|
-
|
|
74
|
+
const template = readFileSync('tsconfig.json', 'utf8');
|
|
75
|
+
const data = template.replace(/@version/g, esVersion);
|
|
76
|
+
await writeFile('tsconfig.json', data);
|
|
77
|
+
stopPrompt(s, `The ${cyan('tsconfig.json')} file was bootstrapped.`);
|
|
26
78
|
runSync();
|
|
27
79
|
}
|
|
28
80
|
|
|
@@ -56,12 +108,29 @@ async function doSync() {
|
|
|
56
108
|
);
|
|
57
109
|
}
|
|
58
110
|
|
|
111
|
+
function getConfigTargets() {
|
|
112
|
+
return [
|
|
113
|
+
{ value: 'es5', label: 'ES5', hint: 'recommended' },
|
|
114
|
+
{ value: 'es6', label: 'ES2015', hint: 'ES6' },
|
|
115
|
+
{ value: 'es2021', label: 'ES2021' }
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function getConfigTypes() {
|
|
120
|
+
return select({
|
|
121
|
+
message: 'Please pick a ECMAScript target.',
|
|
122
|
+
options: getConfigTargets()
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
59
126
|
function getConstants() {
|
|
60
127
|
enum Constants {
|
|
61
128
|
projectName = 'SN TypeScript Util',
|
|
62
129
|
projectDescription = 'is a TS utility for ServiceNow developers using VS Code.',
|
|
130
|
+
confirmInterfaceMsg = `Add a ${cyan('BaseTable.ts')} interface with global default fields?`,
|
|
131
|
+
confirmPrettierMsg = `Add a ${cyan('.prettierrc.json')} default config?`,
|
|
63
132
|
errorMsg = 'No active application detected. Please create a project with the ServiceNow Extension for VS Code.',
|
|
64
|
-
docsUrl = 'https://docs.servicenow.com/bundle/
|
|
133
|
+
docsUrl = 'https://docs.servicenow.com/bundle/washingtondc-application-development/page/build/applications/task/create-project.html',
|
|
65
134
|
buildOption = 'Build project utility files & package dependencies',
|
|
66
135
|
compileOption = 'Compile TypeScript files to JavaScript & move to src',
|
|
67
136
|
helpOption = 'Display help for command',
|
|
@@ -85,7 +154,7 @@ function getErrorMsg() {
|
|
|
85
154
|
return console.error(bold(red(msg)));
|
|
86
155
|
}
|
|
87
156
|
|
|
88
|
-
function getFilePath(file: string, dir: string
|
|
157
|
+
function getFilePath(file: string, dir: string) {
|
|
89
158
|
const fileName = fileURLToPath(import.meta.url);
|
|
90
159
|
const dirName = path.dirname(fileName);
|
|
91
160
|
return `${path.join(dirName, `../${dir}`)}/${file}`;
|
|
@@ -123,6 +192,13 @@ async function getProject() {
|
|
|
123
192
|
return workspace.ACTIVE_APPLICATION;
|
|
124
193
|
}
|
|
125
194
|
|
|
195
|
+
async function getTargetPath(file: string, dir: string) {
|
|
196
|
+
const project = await getProject();
|
|
197
|
+
const path = dir ? `${project}/${dir}/` : '.';
|
|
198
|
+
dir && !existsSync(path) && mkdirSync(path, { recursive: true });
|
|
199
|
+
return `${path}/${file}`;
|
|
200
|
+
}
|
|
201
|
+
|
|
126
202
|
async function getVersion() {
|
|
127
203
|
const info = await getPackageInfo();
|
|
128
204
|
return info.version;
|
|
@@ -191,12 +267,16 @@ function parseOptions(program: Command) {
|
|
|
191
267
|
}
|
|
192
268
|
|
|
193
269
|
async function runSync() {
|
|
270
|
+
const project = await getProject();
|
|
194
271
|
const s = startPrompts('Syncing', null);
|
|
195
272
|
return await execFile(
|
|
196
273
|
getFilePath('sync.sh', 'scripts/build'),
|
|
197
274
|
(stdout: unknown) => {
|
|
198
|
-
stopPrompt(
|
|
199
|
-
|
|
275
|
+
stopPrompt(
|
|
276
|
+
s,
|
|
277
|
+
`TypeScript files constructed in the ${cyan(project + '/ts')} directory.`
|
|
278
|
+
);
|
|
279
|
+
outro(`${green('Done!')}`);
|
|
200
280
|
return stdout;
|
|
201
281
|
}
|
|
202
282
|
);
|
package/tsconfig.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"
|
|
3
|
+
"esModuleInterop": true,
|
|
4
4
|
"module": "NodeNext",
|
|
5
5
|
"noImplicitAny": true,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
6
|
"outDir": "bin",
|
|
8
7
|
"resolveJsonModule": true,
|
|
9
8
|
"skipLibCheck": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"target": "ESNext",
|
|
10
11
|
"types": ["bun-types"]
|
|
11
12
|
},
|
|
12
13
|
"include": ["scripts"]
|
package/.eslintrc.yml
DELETED