sn-typescript-util 1.4.2 → 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/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 updatedContent = template.replace(/@project/g, project);
14
- return await writeFile(file, updatedContent);
47
+ const data = template.replace(/@project/g, project);
48
+ return await writeFile(file, data);
15
49
  }
16
50
  async function doBuild() {
17
- const s = startPrompts('Installing configs', 'Build started');
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
- stopPrompt(s, 'Configs installed');
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/vancouver-application-development/page/build/applications/task/create-project.html';
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 = 'scripts/build') {
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(s, 'Sync completed');
171
- outro('Completed');
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.4.2",
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": "^8.0.1",
30
+ "execa": "^9.1.0",
31
31
  "typescript": "^5.4.5"
32
32
  },
33
33
  "devDependencies": {
34
- "@eslint/js": "^9.0.0",
34
+ "@eslint/js": "^9.3.0",
35
35
  "@types/commander": "^2.12.2",
36
- "bun-types": "^1.1.3",
37
- "eslint": "^9.0.0",
36
+ "bun-types": "^1.1.8",
37
+ "eslint": "^9.3.0",
38
38
  "prettier": "^3.2.5",
39
- "typescript-eslint": "^7.7.0"
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 updatedContent = template.replace(/@project/g, project);
18
- return await writeFile(file, updatedContent);
62
+ const data = template.replace(/@project/g, project);
63
+ return await writeFile(file, data);
19
64
  }
20
65
 
21
66
  async function doBuild() {
22
- const s = startPrompts('Installing configs', 'Build started');
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
- stopPrompt(s, 'Configs installed');
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/vancouver-application-development/page/build/applications/task/create-project.html',
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 = 'scripts/build') {
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(s, 'Sync completed');
199
- outro('Completed');
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
  );
@@ -0,0 +1,8 @@
1
+ interface BaseTable {
2
+ readonly sys_created_on?: Date;
3
+ readonly sys_created_by?: string;
4
+ readonly sys_id?: string;
5
+ readonly sys_mod_count?: number;
6
+ readonly sys_updated_by?: string;
7
+ readonly sys_updated_on?: Date;
8
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "es5",
3
+ "target": "@version",
4
4
  "outDir": "@project/src",
5
5
  "baseUrl": ".",
6
6
  "skipLibCheck": true