@servicenow/sdk-build-core 3.0.3 → 4.0.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.
Files changed (252) hide show
  1. package/dist/app.d.ts +25 -0
  2. package/dist/app.js +8 -0
  3. package/dist/app.js.map +1 -0
  4. package/dist/compiler.d.ts +60 -0
  5. package/dist/compiler.js +320 -0
  6. package/dist/compiler.js.map +1 -0
  7. package/dist/compression.d.ts +7 -0
  8. package/dist/compression.js +79 -0
  9. package/dist/compression.js.map +1 -0
  10. package/dist/crypto.d.ts +1 -0
  11. package/dist/crypto.js +9 -0
  12. package/dist/crypto.js.map +1 -0
  13. package/dist/diagnostic.d.ts +41 -0
  14. package/dist/diagnostic.js +130 -0
  15. package/dist/diagnostic.js.map +1 -0
  16. package/dist/{plugins/Diagnostic.d.ts → fluent-diagnostic.d.ts} +3 -2
  17. package/dist/fluent-diagnostic.js +23 -0
  18. package/dist/fluent-diagnostic.js.map +1 -0
  19. package/dist/fluent-directive.d.ts +8 -0
  20. package/dist/fluent-directive.js +54 -0
  21. package/dist/fluent-directive.js.map +1 -0
  22. package/dist/fluent-file.d.ts +5 -0
  23. package/dist/fluent-file.js +15 -0
  24. package/dist/fluent-file.js.map +1 -0
  25. package/dist/formatter.d.ts +11 -0
  26. package/dist/formatter.js +77 -0
  27. package/dist/formatter.js.map +1 -0
  28. package/dist/fs.d.ts +174 -0
  29. package/dist/fs.js +313 -0
  30. package/dist/fs.js.map +1 -0
  31. package/dist/guid.d.ts +2 -0
  32. package/dist/{GUID.js → guid.js} +3 -6
  33. package/dist/guid.js.map +1 -0
  34. package/dist/index.d.ts +19 -5
  35. package/dist/index.js +19 -5
  36. package/dist/index.js.map +1 -1
  37. package/dist/json.d.ts +5 -0
  38. package/dist/json.js +43 -0
  39. package/dist/json.js.map +1 -0
  40. package/dist/keys-registry.d.ts +64 -0
  41. package/dist/keys-registry.js +339 -0
  42. package/dist/keys-registry.js.map +1 -0
  43. package/dist/logger.d.ts +8 -0
  44. package/dist/logger.js +17 -0
  45. package/dist/logger.js.map +1 -0
  46. package/dist/now-config.d.ts +348 -0
  47. package/dist/now-config.js +283 -0
  48. package/dist/now-config.js.map +1 -0
  49. package/dist/path.d.ts +3 -0
  50. package/dist/path.js +12 -0
  51. package/dist/path.js.map +1 -0
  52. package/dist/plugins/cache.d.ts +20 -0
  53. package/dist/plugins/cache.js +46 -0
  54. package/dist/plugins/cache.js.map +1 -0
  55. package/dist/plugins/context.d.ts +85 -0
  56. package/dist/plugins/{Context.js → context.js} +1 -1
  57. package/dist/plugins/context.js.map +1 -0
  58. package/dist/plugins/database.d.ts +27 -0
  59. package/dist/plugins/database.js +102 -0
  60. package/dist/plugins/database.js.map +1 -0
  61. package/dist/plugins/file.d.ts +10 -0
  62. package/dist/plugins/{behaviors/Arranger.js → file.js} +1 -1
  63. package/dist/plugins/file.js.map +1 -0
  64. package/dist/plugins/index.d.ts +9 -5
  65. package/dist/plugins/index.js +9 -6
  66. package/dist/plugins/index.js.map +1 -1
  67. package/dist/plugins/plugin.d.ts +478 -0
  68. package/dist/plugins/plugin.js +533 -0
  69. package/dist/plugins/plugin.js.map +1 -0
  70. package/dist/plugins/product.d.ts +15 -0
  71. package/dist/plugins/product.js +38 -0
  72. package/dist/plugins/product.js.map +1 -0
  73. package/dist/plugins/project.d.ts +25 -0
  74. package/dist/plugins/{behaviors/Generator.js → project.js} +1 -1
  75. package/dist/plugins/project.js.map +1 -0
  76. package/dist/plugins/shape.d.ts +424 -0
  77. package/dist/plugins/shape.js +1181 -0
  78. package/dist/plugins/shape.js.map +1 -0
  79. package/dist/plugins/time.d.ts +12 -0
  80. package/dist/plugins/time.js +84 -0
  81. package/dist/plugins/time.js.map +1 -0
  82. package/dist/plugins/usage.d.ts +11 -0
  83. package/dist/plugins/usage.js +26 -0
  84. package/dist/plugins/usage.js.map +1 -0
  85. package/dist/prettier/config-loader.d.ts +13 -0
  86. package/dist/prettier/config-loader.js +105 -0
  87. package/dist/prettier/config-loader.js.map +1 -0
  88. package/dist/telemetry/index.d.ts +25 -0
  89. package/dist/telemetry/index.js +18 -0
  90. package/dist/telemetry/index.js.map +1 -0
  91. package/dist/typescript.d.ts +293 -0
  92. package/dist/typescript.js +454 -0
  93. package/dist/typescript.js.map +1 -0
  94. package/dist/util/get-file-type.d.ts +2 -0
  95. package/dist/util/get-file-type.js +13 -0
  96. package/dist/util/get-file-type.js.map +1 -0
  97. package/dist/util/index.d.ts +2 -6
  98. package/dist/util/index.js +2 -6
  99. package/dist/util/index.js.map +1 -1
  100. package/dist/util/{Scope.js → is-sn-scope.js} +1 -1
  101. package/dist/util/is-sn-scope.js.map +1 -0
  102. package/dist/xml.d.ts +24 -0
  103. package/dist/xml.js +71 -0
  104. package/dist/xml.js.map +1 -0
  105. package/now.config.schema.json +336 -0
  106. package/package.json +22 -12
  107. package/src/app.ts +33 -0
  108. package/src/compiler.ts +384 -0
  109. package/src/compression.ts +93 -0
  110. package/src/crypto.ts +5 -0
  111. package/src/diagnostic.ts +108 -0
  112. package/src/{plugins/Diagnostic.ts → fluent-diagnostic.ts} +3 -10
  113. package/src/fluent-directive.ts +63 -0
  114. package/src/fluent-file.ts +13 -0
  115. package/src/formatter.ts +58 -0
  116. package/src/fs.ts +438 -0
  117. package/src/{GUID.ts → guid.ts} +2 -6
  118. package/src/index.ts +19 -5
  119. package/src/json.ts +20 -0
  120. package/src/keys-registry.ts +384 -0
  121. package/src/logger.ts +20 -0
  122. package/src/now-config.ts +337 -0
  123. package/src/path.ts +9 -0
  124. package/src/plugins/cache.ts +45 -0
  125. package/src/plugins/context.ts +93 -0
  126. package/src/plugins/database.ts +121 -0
  127. package/src/plugins/file.ts +19 -0
  128. package/src/plugins/index.ts +9 -5
  129. package/src/plugins/plugin.ts +995 -0
  130. package/src/plugins/product.ts +44 -0
  131. package/src/plugins/project.ts +39 -0
  132. package/src/plugins/shape.ts +1532 -0
  133. package/src/plugins/time.ts +108 -0
  134. package/src/plugins/usage.ts +26 -0
  135. package/src/prettier/config-loader.ts +130 -0
  136. package/src/telemetry/index.ts +27 -0
  137. package/src/typescript.ts +502 -0
  138. package/src/util/get-file-type.ts +11 -0
  139. package/src/util/index.ts +2 -6
  140. package/src/xml.ts +86 -0
  141. package/dist/GUID.d.ts +0 -2
  142. package/dist/GUID.js.map +0 -1
  143. package/dist/IncludePaths.d.ts +0 -25
  144. package/dist/IncludePaths.js +0 -97
  145. package/dist/IncludePaths.js.map +0 -1
  146. package/dist/Keys.d.ts +0 -32
  147. package/dist/Keys.js +0 -245
  148. package/dist/Keys.js.map +0 -1
  149. package/dist/TypeScript.d.ts +0 -5
  150. package/dist/TypeScript.js +0 -58
  151. package/dist/TypeScript.js.map +0 -1
  152. package/dist/XML.d.ts +0 -32
  153. package/dist/XML.js +0 -83
  154. package/dist/XML.js.map +0 -1
  155. package/dist/plugins/Context.d.ts +0 -190
  156. package/dist/plugins/Context.js.map +0 -1
  157. package/dist/plugins/Diagnostic.js +0 -28
  158. package/dist/plugins/Diagnostic.js.map +0 -1
  159. package/dist/plugins/Plugin.d.ts +0 -175
  160. package/dist/plugins/Plugin.js +0 -15
  161. package/dist/plugins/Plugin.js.map +0 -1
  162. package/dist/plugins/behaviors/Arranger.d.ts +0 -26
  163. package/dist/plugins/behaviors/Arranger.js.map +0 -1
  164. package/dist/plugins/behaviors/Composer.d.ts +0 -102
  165. package/dist/plugins/behaviors/Composer.js +0 -15
  166. package/dist/plugins/behaviors/Composer.js.map +0 -1
  167. package/dist/plugins/behaviors/Diagnostics.d.ts +0 -7
  168. package/dist/plugins/behaviors/Diagnostics.js +0 -3
  169. package/dist/plugins/behaviors/Diagnostics.js.map +0 -1
  170. package/dist/plugins/behaviors/Generator.d.ts +0 -21
  171. package/dist/plugins/behaviors/Generator.js.map +0 -1
  172. package/dist/plugins/behaviors/OwnedTables.d.ts +0 -6
  173. package/dist/plugins/behaviors/OwnedTables.js +0 -3
  174. package/dist/plugins/behaviors/OwnedTables.js.map +0 -1
  175. package/dist/plugins/behaviors/PostProcessor.d.ts +0 -5
  176. package/dist/plugins/behaviors/PostProcessor.js +0 -3
  177. package/dist/plugins/behaviors/PostProcessor.js.map +0 -1
  178. package/dist/plugins/behaviors/Serializer.d.ts +0 -30
  179. package/dist/plugins/behaviors/Serializer.js +0 -3
  180. package/dist/plugins/behaviors/Serializer.js.map +0 -1
  181. package/dist/plugins/behaviors/Transformer.d.ts +0 -23
  182. package/dist/plugins/behaviors/Transformer.js +0 -3
  183. package/dist/plugins/behaviors/Transformer.js.map +0 -1
  184. package/dist/plugins/behaviors/extractors/Data.d.ts +0 -119
  185. package/dist/plugins/behaviors/extractors/Data.js +0 -244
  186. package/dist/plugins/behaviors/extractors/Data.js.map +0 -1
  187. package/dist/plugins/behaviors/extractors/Extractors.d.ts +0 -63
  188. package/dist/plugins/behaviors/extractors/Extractors.js +0 -3
  189. package/dist/plugins/behaviors/extractors/Extractors.js.map +0 -1
  190. package/dist/plugins/behaviors/extractors/index.d.ts +0 -2
  191. package/dist/plugins/behaviors/extractors/index.js +0 -19
  192. package/dist/plugins/behaviors/extractors/index.js.map +0 -1
  193. package/dist/plugins/behaviors/index.d.ts +0 -9
  194. package/dist/plugins/behaviors/index.js +0 -26
  195. package/dist/plugins/behaviors/index.js.map +0 -1
  196. package/dist/plugins/util/CallExpression.d.ts +0 -5
  197. package/dist/plugins/util/CallExpression.js +0 -88
  198. package/dist/plugins/util/CallExpression.js.map +0 -1
  199. package/dist/plugins/util/CodeTransformation.d.ts +0 -95
  200. package/dist/plugins/util/CodeTransformation.js +0 -624
  201. package/dist/plugins/util/CodeTransformation.js.map +0 -1
  202. package/dist/plugins/util/ObjectLiteral.d.ts +0 -9
  203. package/dist/plugins/util/ObjectLiteral.js +0 -37
  204. package/dist/plugins/util/ObjectLiteral.js.map +0 -1
  205. package/dist/plugins/util/index.d.ts +0 -3
  206. package/dist/plugins/util/index.js +0 -20
  207. package/dist/plugins/util/index.js.map +0 -1
  208. package/dist/util/Debug.d.ts +0 -4
  209. package/dist/util/Debug.js +0 -20
  210. package/dist/util/Debug.js.map +0 -1
  211. package/dist/util/Directive.d.ts +0 -16
  212. package/dist/util/Directive.js +0 -107
  213. package/dist/util/Directive.js.map +0 -1
  214. package/dist/util/RuntimeTableSchema.d.ts +0 -5
  215. package/dist/util/RuntimeTableSchema.js +0 -58
  216. package/dist/util/RuntimeTableSchema.js.map +0 -1
  217. package/dist/util/Scope.js.map +0 -1
  218. package/dist/util/Util.d.ts +0 -1
  219. package/dist/util/Util.js +0 -12
  220. package/dist/util/Util.js.map +0 -1
  221. package/dist/util/XMLUploadParser.d.ts +0 -22
  222. package/dist/util/XMLUploadParser.js +0 -67
  223. package/dist/util/XMLUploadParser.js.map +0 -1
  224. package/src/IncludePaths.ts +0 -122
  225. package/src/Keys.ts +0 -274
  226. package/src/TypeScript.ts +0 -65
  227. package/src/XML.ts +0 -98
  228. package/src/plugins/Context.ts +0 -239
  229. package/src/plugins/Plugin.ts +0 -278
  230. package/src/plugins/behaviors/Arranger.ts +0 -42
  231. package/src/plugins/behaviors/Composer.ts +0 -125
  232. package/src/plugins/behaviors/Diagnostics.ts +0 -12
  233. package/src/plugins/behaviors/Generator.ts +0 -31
  234. package/src/plugins/behaviors/OwnedTables.ts +0 -5
  235. package/src/plugins/behaviors/PostProcessor.ts +0 -6
  236. package/src/plugins/behaviors/Serializer.ts +0 -40
  237. package/src/plugins/behaviors/Transformer.ts +0 -32
  238. package/src/plugins/behaviors/extractors/Data.ts +0 -332
  239. package/src/plugins/behaviors/extractors/Extractors.ts +0 -73
  240. package/src/plugins/behaviors/extractors/index.ts +0 -2
  241. package/src/plugins/behaviors/index.ts +0 -9
  242. package/src/plugins/util/CallExpression.ts +0 -110
  243. package/src/plugins/util/CodeTransformation.ts +0 -731
  244. package/src/plugins/util/ObjectLiteral.ts +0 -37
  245. package/src/plugins/util/index.ts +0 -3
  246. package/src/util/Debug.ts +0 -24
  247. package/src/util/Directive.ts +0 -123
  248. package/src/util/RuntimeTableSchema.ts +0 -44
  249. package/src/util/Util.ts +0 -7
  250. package/src/util/XMLUploadParser.ts +0 -90
  251. /package/dist/util/{Scope.d.ts → is-sn-scope.d.ts} +0 -0
  252. /package/src/util/{Scope.ts → is-sn-scope.ts} +0 -0
@@ -0,0 +1,58 @@
1
+ import * as typescriptPrettierPlugin from 'prettier/plugins/typescript.js'
2
+ import * as estreePrettierPlugin from 'prettier/plugins/estree.js'
3
+ import { format } from 'prettier/standalone'
4
+ import type { FileSystem } from './fs'
5
+ import { path } from './path'
6
+ import type { Options } from 'prettier'
7
+ import { resolveConfig } from './prettier/config-loader'
8
+ import { JSON5 } from './json'
9
+
10
+ export class Formatter {
11
+ private readonly cache: Map<string, Options | null> = new Map()
12
+
13
+ constructor(private readonly fs: FileSystem) {}
14
+
15
+ public resetCache(): void {
16
+ this.cache.clear()
17
+ }
18
+
19
+ public async format(text: string, filePath: string): Promise<string> {
20
+ let config = await resolveConfig(filePath, this.fs, this.cache)
21
+
22
+ if (!config) {
23
+ config = {
24
+ trailingComma: 'es5',
25
+ singleQuote: true,
26
+ printWidth: 120,
27
+ tabWidth: 4,
28
+ semi: false,
29
+ }
30
+ }
31
+
32
+ const ext = path.extname(filePath)
33
+ if (ext === '.json') {
34
+ return this.formatJson(text, config)
35
+ }
36
+
37
+ return this.formatTypescript(text, config)
38
+ }
39
+
40
+ public async formatTypescript(text: string, options: Options): Promise<string> {
41
+ return format(sanitizeText(text), {
42
+ plugins: [typescriptPrettierPlugin, estreePrettierPlugin],
43
+ parser: 'typescript',
44
+ ...options,
45
+ })
46
+ }
47
+
48
+ public formatJson(jsonText: string, options: Options): string {
49
+ return JSON.stringify(JSON5.parse(jsonText), null, options.tabWidth ?? 2)
50
+ }
51
+ }
52
+
53
+ /**
54
+ * LS & PS characters are not supported by prettier, so replacing them with space
55
+ */
56
+ function sanitizeText(fileText: string): string {
57
+ return fileText.replace(/[\u2028\u2029]/g, ' ')
58
+ }
package/src/fs.ts ADDED
@@ -0,0 +1,438 @@
1
+ import { path } from './path'
2
+ import noop from 'lodash/noop'
3
+ import { ts } from './typescript'
4
+ import * as fg from 'fast-glob'
5
+ import { Writable, Readable } from 'readable-stream'
6
+
7
+ /**
8
+ * A file system API based on a subset of the `fs` module from Node.js.
9
+ */
10
+ export interface FileSystem {
11
+ /**
12
+ * Synchronously deletes the file or directory at the provided path.
13
+ */
14
+ rmSync(path: string, options?: { recursive?: boolean; force?: boolean }): void
15
+
16
+ /**
17
+ * Synchronously retrieves the status of the file or directory at the provided path.
18
+ */
19
+ statSync(path: string): FileSystem.Stats
20
+
21
+ /**
22
+ * Synchronously retrieves the status of the file or directory at the provided path. Does
23
+ * not dereference symbolic links.
24
+ */
25
+ lstatSync(path: string): FileSystem.Stats
26
+
27
+ /**
28
+ * Synchronously computes the canonical path by resolving `.`, `..` and symbolic links.
29
+ */
30
+ realpathSync(path: string): string
31
+
32
+ /**
33
+ * Synchronously creates a directory at the provided path.
34
+ *
35
+ * If `options.recursive` is `true`, the full path will be created including any missing
36
+ * parent directories, and the path of the first directory created will be returned.
37
+ * Otherwise, returns `undefined`.
38
+ */
39
+ mkdirSync(path: string): void
40
+ mkdirSync(path: string, options: { recursive: true }): string | undefined
41
+ mkdirSync(path: string, options?: { recursive: boolean }): string | undefined
42
+
43
+ /**
44
+ * Synchronously renames the file or directory at the old path to the new path.
45
+ */
46
+ renameSync(oldPath: string, newPath: string): void
47
+
48
+ /**
49
+ * Synchronously reads the contents of the directory at the provided path.
50
+ *
51
+ * If `options.withFileTypes` is `true`, returns the contents as an array of `Entry`
52
+ * objects. Otherwise, returns the contents as an array of strings containing the names
53
+ * of each entry.
54
+ */
55
+ readdirSync(path: string): string[]
56
+ readdirSync(path: string, options: { withFileTypes: true }): FileSystem.Entry[]
57
+ readdirSync(path: string, options?: { withFileTypes: boolean }): string[] | FileSystem.Entry[]
58
+
59
+ /**
60
+ * Synchronously reads the contents of the file at the provided path.
61
+ *
62
+ * If `options.encoding` is provided, the contents will be returned as a string. Otherwise,
63
+ * the contents will be returned as a `Buffer`.
64
+ */
65
+ readFileSync(path: string, options?: { flag: 'r' }): Buffer
66
+ readFileSync(path: string, options: { encoding: FileSystem.Encoding; flag?: 'r' }): string
67
+ readFileSync(path: string, options?: { encoding?: FileSystem.Encoding; flag?: 'r' }): string | Buffer
68
+
69
+ /**
70
+ * Synchronously writes the provided content to the file at the provided path.
71
+ */
72
+ writeFileSync(
73
+ path: string,
74
+ content: string | NodeJS.ArrayBufferView,
75
+ options?: { encoding: FileSystem.Encoding }
76
+ ): void
77
+
78
+ /**
79
+ * Synchronously copies the file at the source path to the destination path.
80
+ */
81
+ copyFileSync(srcPath: string, destPath: string): void
82
+
83
+ /**
84
+ * Synchronously checks if the file or directory at the provided path is accessible. If it
85
+ * is accessible, the method does nothing. If it is not accessible, an error is thrown.
86
+ */
87
+ accessSync(path: string): void
88
+ }
89
+
90
+ export namespace FileSystem {
91
+ export type Entry = {
92
+ name: string
93
+ isFile(): boolean
94
+ isDirectory(): boolean
95
+ isSymbolicLink(): boolean
96
+ isCharacterDevice(): boolean
97
+ isBlockDevice(): boolean
98
+ isSocket(): boolean
99
+ isFIFO(): boolean
100
+ }
101
+
102
+ export type Stats = {
103
+ isFile(): boolean
104
+ isDirectory(): boolean
105
+ isSymbolicLink(): boolean
106
+ isCharacterDevice(): boolean
107
+ isBlockDevice(): boolean
108
+ isSocket(): boolean
109
+ isFIFO(): boolean
110
+ }
111
+
112
+ export type Encoding = 'utf-8' | 'binary'
113
+
114
+ /**
115
+ * Synchronously copies the file or directory at the source path to the destination
116
+ * path. If the source path is a directory, only its contents will be copied, not the
117
+ * directory itself. If the source path is a file, the destination path cannot be a
118
+ * directory.
119
+ *
120
+ * If `options.filter` is provided, only entries for which the filter returns `true`
121
+ * will be copied.
122
+ */
123
+ export function copySync(
124
+ fs: FileSystem,
125
+ srcPath: string,
126
+ destPath: string,
127
+ options?: {
128
+ filter(src: string): boolean
129
+ }
130
+ ) {
131
+ if (fs.statSync(srcPath).isDirectory()) {
132
+ fs.readdirSync(srcPath, { withFileTypes: true })
133
+ .filter((file) => options?.filter(file.name) ?? true)
134
+ .forEach((file) => copySync(fs, path.join(srcPath, file.name), path.join(destPath, file.name), options))
135
+ } else {
136
+ if (!FileSystem.existsSync(fs, path.dirname(destPath))) {
137
+ fs.mkdirSync(path.dirname(destPath), { recursive: true })
138
+ }
139
+ fs.copyFileSync(srcPath, destPath)
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Synchronously checks if the file or directory at the provided path exists.
145
+ */
146
+ export function existsSync(fs: FileSystem, path: string): boolean {
147
+ try {
148
+ fs.accessSync(path)
149
+ return true
150
+ } catch {
151
+ return false
152
+ }
153
+ }
154
+
155
+ /*
156
+ * Ensures that a directory exists synchronously.
157
+ * If the directory does not exist, it will be created recursively.
158
+ *
159
+ * @param fs - The file system object.
160
+ * @param path - The path of the directory to ensure.
161
+ */
162
+ export function ensureDirSync(fs: FileSystem, path: string) {
163
+ if (!existsSync(fs, path)) {
164
+ fs.mkdirSync(path, { recursive: true })
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Provides an implementation of a write stream for FileSystems that don't
170
+ * have one natively. Buffers all chunks in memory until finalized.
171
+ */
172
+ export function createWriteStream(fs: FileSystem, path: string): Writable {
173
+ if ('createWriteStream' in fs && typeof fs.createWriteStream === 'function') {
174
+ return fs.createWriteStream(path)
175
+ }
176
+
177
+ const stream = new Writable()
178
+
179
+ // who needs streams when you have infinite memory?
180
+ const buffer: Uint8Array[] = []
181
+ stream._write = (chunk, _encoding, callback) => {
182
+ buffer.push(chunk)
183
+ callback()
184
+ }
185
+
186
+ stream._writev = (chunks, callback) => {
187
+ for (const { chunk, encoding } of chunks) {
188
+ stream._write(chunk, encoding, noop)
189
+ }
190
+ callback()
191
+ }
192
+
193
+ stream._final = (callback) => {
194
+ const totalSize = buffer.reduce((result, array) => result + array.length, 0)
195
+ const merged = new Uint8Array(totalSize)
196
+ let offset = 0
197
+ buffer.forEach((array) => {
198
+ merged.set(array, offset)
199
+ offset += array.length
200
+ })
201
+
202
+ fs.writeFileSync(path, Buffer.from(merged.buffer))
203
+ buffer.length = 0
204
+ callback()
205
+ }
206
+
207
+ return stream
208
+ }
209
+
210
+ /**
211
+ * Provides an implementation of a read stream for FileSystems that don't
212
+ * have one natively. Reads the entire content as a single chunk.
213
+ */
214
+ export function createReadStream(fs: FileSystem, path: string): Readable {
215
+ if ('createReadStream' in fs && typeof fs.createReadStream === 'function') {
216
+ return fs.createReadStream(path)
217
+ }
218
+
219
+ const stream = new Readable()
220
+
221
+ stream._read = () => {
222
+ stream.push(fs.readFileSync(path))
223
+ stream.push(null)
224
+ }
225
+
226
+ return stream
227
+ }
228
+
229
+ export function traverseDirectory(
230
+ fs: FileSystem,
231
+ dir: string,
232
+ options: {
233
+ extensions?: string[]
234
+ ignore_extensions?: string[] | undefined
235
+ visitor: (filePath: string) => void
236
+ }
237
+ ) {
238
+ if (!FileSystem.existsSync(fs, dir)) {
239
+ return
240
+ }
241
+
242
+ const files = fs.readdirSync(dir, { withFileTypes: true })
243
+ const { extensions, ignore_extensions, visitor } = options || {}
244
+
245
+ for (const file of files) {
246
+ const filePath = path.resolve(dir, file.name)
247
+ if (file.isDirectory()) {
248
+ traverseDirectory(fs, filePath, options)
249
+ } else if (
250
+ ignore_extensions &&
251
+ ignore_extensions.find((e) => filePath.toLocaleLowerCase().endsWith(e.toLocaleLowerCase()))
252
+ ) {
253
+ //skip
254
+ } else if (
255
+ !extensions ||
256
+ extensions.length === 0 ||
257
+ extensions.some((e) => filePath.toLocaleLowerCase().endsWith(e.toLocaleLowerCase()))
258
+ ) {
259
+ visitor(filePath)
260
+ }
261
+ }
262
+ }
263
+ }
264
+
265
+ export class TsMorphFileSystemWrapper implements ts.FileSystemHost {
266
+ static ENOENT = 'ENOENT'
267
+
268
+ constructor(private readonly fs: FileSystem) {}
269
+
270
+ deleteSync(path: string): void {
271
+ try {
272
+ this.fs.rmSync(path, { recursive: true })
273
+ } catch (err) {
274
+ // It is required to throw this specific subclass of error in order for ts-morph to work properly
275
+ throw this.#getFileNotFoundErrorIfNecessary(err, path)
276
+ }
277
+ }
278
+
279
+ readFileSync(path: string, encoding: FileSystem.Encoding = 'utf-8'): string {
280
+ try {
281
+ return this.fs.readFileSync(path, { encoding })
282
+ } catch (err) {
283
+ // It is required to throw this specific subclass of error in order for ts-morph to work properly
284
+ throw this.#getFileNotFoundErrorIfNecessary(err, path)
285
+ }
286
+ }
287
+
288
+ writeFileSync(path: string, text: string): void {
289
+ this.fs.writeFileSync(path, text)
290
+ }
291
+
292
+ mkdirSync(path: string): void {
293
+ this.fs.mkdirSync(path, { recursive: true })
294
+ }
295
+
296
+ moveSync(srcPath: string, destPath: string): void {
297
+ this.fs.renameSync(srcPath, destPath)
298
+ }
299
+
300
+ copySync(srcPath: string, destPath: string): void {
301
+ this.fs.copyFileSync(srcPath, destPath)
302
+ }
303
+
304
+ fileExistsSync(path: string): boolean {
305
+ return FileSystem.existsSync(this.fs, path)
306
+ }
307
+
308
+ directoryExistsSync(path: string): boolean {
309
+ return this.fileExistsSync(path)
310
+ }
311
+
312
+ readDirSync(dir: string): ts.RuntimeDirEntry[] {
313
+ try {
314
+ const entries = this.fs.readdirSync(dir, { withFileTypes: true }).map((entry) => {
315
+ return {
316
+ name: entry.name,
317
+ isFile: entry.isFile(),
318
+ isDirectory: entry.isDirectory(),
319
+ isSymlink: entry.isSymbolicLink(),
320
+ }
321
+ })
322
+
323
+ for (const entry of entries) {
324
+ entry.name = path.join(dir, entry.name)
325
+ if (entry.isSymlink) {
326
+ try {
327
+ const info = this.fs.statSync(entry.name)
328
+ if (info != null) {
329
+ entry.isDirectory = info.isDirectory()
330
+ entry.isFile = info.isFile()
331
+ }
332
+ } catch {
333
+ // Ignore
334
+ }
335
+ }
336
+ }
337
+
338
+ return entries
339
+ } catch (err) {
340
+ // It is required to throw this specific subclass of error in order for ts-morph to work properly
341
+ throw this.#getDirectoryNotFoundErrorIfNecessary(err, dir)
342
+ }
343
+ }
344
+
345
+ globSync(patterns: string[], opts?: fg.Options): string[] {
346
+ return fg.sync(
347
+ patterns.map((pattern) => (this.fileExistsSync(pattern) ? fg.convertPathToPattern(pattern) : pattern)),
348
+ {
349
+ absolute: true,
350
+ cwd: this.getCurrentDirectory(),
351
+ ...opts,
352
+ fs: {
353
+ readdir: this.fs.readdirSync.bind(this.fs),
354
+ readdirSync: this.fs.readdirSync.bind(this.fs),
355
+ stat: this.fs.statSync.bind(this.fs),
356
+ statSync: this.fs.statSync.bind(this.fs),
357
+ lstat: this.fs.lstatSync.bind(this.fs),
358
+ lstatSync: this.fs.lstatSync.bind(this.fs),
359
+ } as unknown as fg.FileSystemAdapter, // TODO: There are probably some compatibility issues here that will cause subtle bugs
360
+ }
361
+ )
362
+ }
363
+
364
+ realpathSync(path: string): string {
365
+ return this.fs.realpathSync(path)
366
+ }
367
+
368
+ getCurrentDirectory(): string {
369
+ return path.resolve()
370
+ }
371
+
372
+ isCaseSensitive(): boolean {
373
+ return false // TODO: Should we try to do something more sophisticated here?
374
+ }
375
+
376
+ async delete(path: string): Promise<void> {
377
+ this.deleteSync(path)
378
+ }
379
+
380
+ async readFile(path: string, encoding?: FileSystem.Encoding): Promise<string> {
381
+ return this.readFileSync(path, encoding)
382
+ }
383
+
384
+ async writeFile(path: string, text: string): Promise<void> {
385
+ this.writeFileSync(path, text)
386
+ }
387
+
388
+ async mkdir(path: string): Promise<void> {
389
+ this.mkdirSync(path)
390
+ }
391
+
392
+ async move(srcPath: string, destPath: string): Promise<void> {
393
+ this.moveSync(srcPath, destPath)
394
+ }
395
+
396
+ async copy(srcPath: string, destPath: string): Promise<void> {
397
+ this.copySync(srcPath, destPath)
398
+ }
399
+
400
+ async fileExists(path: string): Promise<boolean> {
401
+ return this.fileExistsSync(path)
402
+ }
403
+
404
+ async directoryExists(path: string): Promise<boolean> {
405
+ return this.directoryExistsSync(path)
406
+ }
407
+
408
+ async glob(patterns: string[]): Promise<string[]> {
409
+ return this.globSync(patterns)
410
+ }
411
+
412
+ /**
413
+ * Returns a specific subclass of error when a directory is not found which is
414
+ * required for ts-morph to work properly.
415
+ */
416
+ #getDirectoryNotFoundErrorIfNecessary(err: any, path: string) {
417
+ return this.#isNotExistsError(err) ? new ts.DirectoryNotFoundError(path) : err
418
+ }
419
+
420
+ /**
421
+ * Returns a specific subclass of error when a file is not found which is required
422
+ * for ts-morph to work properly.
423
+ */
424
+ #getFileNotFoundErrorIfNecessary(err: any, path: string) {
425
+ return this.#isNotExistsError(err) ? new ts.FileNotFoundError(path) : err
426
+ }
427
+
428
+ /**
429
+ * Checks if the error is a "not exists" error. This is copied directly from one
430
+ * of ts-morph's internal `FileSystemHost` implementations.
431
+ */
432
+ #isNotExistsError(err: any) {
433
+ return (
434
+ (err != null && err.code === TsMorphFileSystemWrapper.ENOENT) ||
435
+ (err != null && err?.constructor?.name === 'NotFound')
436
+ )
437
+ }
438
+ }
@@ -1,4 +1,4 @@
1
- import { crypto } from '@servicenow/sdk-project'
1
+ import { crypto } from './crypto'
2
2
 
3
3
  export function GUID() {
4
4
  return crypto.randomUUID().replaceAll('-', '')
@@ -7,10 +7,6 @@ export function GUID() {
7
7
  // Matches a hex string exactly 32 characters long
8
8
  const snIDRegex = /^[a-f0-9]{32}$/i
9
9
 
10
- export function isGUID(guid: string | number): guid is string {
11
- if (typeof guid !== 'string') {
12
- return false
13
- }
14
-
10
+ export function isGUID(guid: string): boolean {
15
11
  return snIDRegex.test(guid)
16
12
  }
package/src/index.ts CHANGED
@@ -1,7 +1,21 @@
1
1
  export * from './util'
2
- export * from './TypeScript'
3
- export * from './XML'
2
+ export * from './xml'
4
3
  export * from './plugins'
5
- export * from './GUID'
6
- export * from './Keys'
7
- export * from './IncludePaths'
4
+ export * from './guid'
5
+ export * from './keys-registry'
6
+ export * from './fluent-diagnostic'
7
+ export * from './fluent-directive'
8
+ export * from './fluent-file'
9
+ export * from './now-config'
10
+ export * from './compiler'
11
+ export * from './diagnostic'
12
+ export * from './app'
13
+ export * from './json'
14
+ export * from './logger'
15
+ export * from './fs'
16
+ export * from './path'
17
+ export * from './typescript'
18
+ export * from './crypto'
19
+ export * from './compression'
20
+ export * from './formatter'
21
+ export * from './telemetry'
package/src/json.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { path as pathModule } from './path'
2
+ import type { FileSystem } from './fs'
3
+ import { Compiler } from './compiler'
4
+
5
+ import * as JSON5 from 'json5'
6
+ export { JSON5 }
7
+
8
+ export function readJson(path: string, filename: string, fsOrCompiler: FileSystem | Compiler) {
9
+ const filePath = pathModule.resolve(path, filename)
10
+
11
+ try {
12
+ return JSON5.parse(
13
+ fsOrCompiler instanceof Compiler
14
+ ? fsOrCompiler.getSourceFileOrThrow(filePath).getFullText()
15
+ : fsOrCompiler.readFileSync(filePath, { encoding: 'utf-8' })
16
+ )
17
+ } catch (e) {
18
+ throw new Error(`Failed to parse JSON file: ${filePath} (Reason: ${e instanceof Error ? e.message : e})`)
19
+ }
20
+ }