@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,478 @@
1
+ import { type SupportedKindName, type SupportedNode, type SupportedNodeByKindName, ts } from '../typescript';
2
+ import { type ObjectShape, type Record, type Shape, type ShapeClass, type StringShape } from './shape';
3
+ import type { File, OutputFile } from './file';
4
+ import { Database } from './database';
5
+ import type { Context as BaseContext } from './context';
6
+ type Context = Omit<BaseContext, 'keys'>;
7
+ export type Result<Value = unknown> = {
8
+ success: false;
9
+ } | {
10
+ success: true;
11
+ value: Value;
12
+ };
13
+ export type CommitResult = {
14
+ success: boolean;
15
+ };
16
+ export type CommitFunction = (shape: Shape, target: ts.Node, ...plugins: Plugin[]) => Promise<void>;
17
+ export type CommitContext = Context & {
18
+ commit: CommitFunction;
19
+ };
20
+ export type RecordContext = Context & {
21
+ readonly database: Database;
22
+ readonly descendants: Database;
23
+ };
24
+ export type Relationships = {
25
+ [table: string]: Relationship;
26
+ };
27
+ export type Relationship = {
28
+ /**
29
+ * Specifies how the tables are related:
30
+ *
31
+ * - String: Name of the reference field on the child table pointing to the parent (or
32
+ * vice versa for inverse relationships)
33
+ * - Object: Key-value pairs where keys are column names on the child table and values
34
+ * are the matching column names on the parent table (or vice versa for inverse
35
+ * relationships)
36
+ * - Function: Takes the parent and child records as arguments and returns a boolean to
37
+ * indicate whether the records are related or not (WARNING: Do not use this
38
+ * unless absolutely necessary as it can negatively impact performance)
39
+ */
40
+ via: string | {
41
+ [column: string]: string;
42
+ } | ((parent: Record, child: Record) => boolean);
43
+ /**
44
+ * When true, the relationship direction is reversed - the parent references the child
45
+ * instead of the child referencing the parent
46
+ */
47
+ inverse?: boolean;
48
+ /**
49
+ * When true, the related record is considered part of the same logical entity as its
50
+ * parent. These records should be processed together as a unit.
51
+ */
52
+ descendant?: boolean;
53
+ /**
54
+ * Nested relationships that define how this table relates to other tables
55
+ */
56
+ relationships?: Relationships;
57
+ };
58
+ export type CoalesceStrategy = [string, ...string[]] | ((properties: ObjectShape) => globalThis.Record<string, string | StringShape> | ObjectShape);
59
+ export type FileType = 'fluent' | 'module' | 'json' | 'unknown';
60
+ export type PluginConfig<Nodes extends SupportedKindName[] = SupportedKindName[], Shapes extends ShapeClass[] = ShapeClass[], Records extends string[] = string[]> = {
61
+ /**
62
+ * The name of the plugin. Must end with "Plugin" suffix. This name is used in metrics
63
+ * and error messages.
64
+ */
65
+ name: `${string}Plugin`;
66
+ /**
67
+ * The TypeScript AST nodes this plugin handles. Plugins that do not introduce new
68
+ * syntax should not need to define any handlers here.
69
+ */
70
+ nodes?: {
71
+ [I in keyof Nodes]: {
72
+ /**
73
+ * The TypeScript node kind to handle. Must be one of the hard-coded set
74
+ * of supported kinds in the Fluent DSL.
75
+ */
76
+ node: Nodes[I];
77
+ /**
78
+ * File types this handler should run on. These are based on the file
79
+ * extension. If not specified, it runs on all file types.
80
+ */
81
+ fileTypes?: FileType[];
82
+ /**
83
+ * Indicates whether this node should be parsed as an entry point during
84
+ * the top-level AST traversal to produce output. (Default: false)
85
+ */
86
+ entryPoint?: boolean;
87
+ /**
88
+ * Converts a TypeScript node to a shape.
89
+ *
90
+ * This is the initial transformation step when processing source code.
91
+ * The function receives a TypeScript node of the specified kind and
92
+ * returns a shape derived from it. That shape can then be handled later
93
+ * by shape transforms defined in this plugin or some other plugin.
94
+ *
95
+ * @param node - The TypeScript node to transform
96
+ * @param context - Context object with useful services and information
97
+ * @returns A result indicating whether the transformation was successful
98
+ * and, if so, the resulting shape
99
+ */
100
+ toShape?(node: SupportedNodeByKindName<Nodes[I]>, context: Context): Result<Shape> | Promise<Result<Shape>>;
101
+ };
102
+ };
103
+ /**
104
+ * The shapes this plugin handles. Each shape handler can implement the following:
105
+ *
106
+ * - Transform functions that turn shapes into records (toRecord)
107
+ * - Transform functions that turn shapes into more specialized subclasses of those shapes (toSubclass)
108
+ * - Commit functions that mutate TypeScript nodes to match shapes (commit)
109
+ * - Inspect functions that can examine shapes for diagnostic purposes (inspect)
110
+ */
111
+ shapes?: {
112
+ [I in keyof Shapes]: Shapes[I] extends ShapeClass<infer S> ? {
113
+ /**
114
+ * The shape class to handle.
115
+ */
116
+ shape: Shapes[I];
117
+ /**
118
+ * File types this handler should run on. These are based on the file
119
+ * extension. If not specified, it runs on all file types.
120
+ */
121
+ fileTypes?: FileType[];
122
+ /**
123
+ * Inspects a shape. Useful for validating the details of a shape created
124
+ * by another plugin and producing diagnostics.
125
+ *
126
+ * @param shape - The shape to inspect
127
+ * @param context - Context object with useful services and information
128
+ */
129
+ inspect?(shape: S, context: Context): void;
130
+ /**
131
+ * Transforms a shape into a more specific subclass. Plugins that introduce
132
+ * a shape which extends another shape should implement this. For example,
133
+ * many plugins implement support for entities based on call expressions,
134
+ * and therefore handle CallExpressionShape. Creating a subclass of that
135
+ * shape allows plugins to more easily handle their use case.
136
+ *
137
+ * NOTE: The shape returned by this function MUST be a subclass of the input
138
+ * shape. If it is not, an error will be thrown at runtime.
139
+ *
140
+ * @param shape - The shape to transform
141
+ * @param context - Context object with useful services and information
142
+ * @returns A result indicating whether the transformation was successful
143
+ * and, if so, an instance of the subclass
144
+ */
145
+ toSubclass?(shape: S, context: Context): Result<S>;
146
+ /**
147
+ * Transforms a shape into a record. Almost all plugins should implement
148
+ * this, as it is the fundamental transformation step in the process of
149
+ * turning Fluent code into ServiceNow records. These records will then
150
+ * be serialized into XML as part of a build, or merged with incoming
151
+ * records as part of bidirectional sync.
152
+ *
153
+ * @param shape - The shape to transform
154
+ * @param context - Context object with useful services and information
155
+ * @returns A result indicating whether the transformation was successful
156
+ * and, if so, the resulting record(s)
157
+ */
158
+ toRecord?(shape: S, context: Context): Result<Record> | Promise<Result<Record>>;
159
+ /**
160
+ * Mutates a target TypeScript node to match a given shape. Plugins that
161
+ * do not introduce new syntax should not need to implement this.
162
+ *
163
+ * NOTE: It is CRUCIAL that the commit function does not apply any changes
164
+ * to the target node other than what is absolutely necessary to match
165
+ * the shape. They should be "minimally invasive", preserving as much
166
+ * as possible of the original code, including comments and whitespace.
167
+ * Care must be taken to check if parts of the existing code are
168
+ * functionally equivalent to the incoming shape, even if they are not
169
+ * exactly the same.
170
+ *
171
+ * @param shape - The shape to commit
172
+ * @param target - The target TypeScript node to modify
173
+ * @param context - Context with useful services and information
174
+ * @returns A result indicating whether the commit was successful
175
+ */
176
+ commit?(shape: S, target: ts.Node, context: CommitContext): CommitResult | Promise<CommitResult>;
177
+ } : never;
178
+ };
179
+ /**
180
+ * The records this plugin handles. The keys of this object are the names of the tables to be
181
+ * handled, and the values are handlers which can implement the following:
182
+ *
183
+ * - Transform functions that turn records into shapes (toShape)
184
+ * - Transform functions that turn records into files (toFile)
185
+ * - Relationship mappings
186
+ * - Coalesce strategies
187
+ */
188
+ records?: {
189
+ [T in Records[number]]: {
190
+ /**
191
+ * Columns that compose the coalesce strategy for this table. If there is a strategy defined in
192
+ * the platform for this table, you must make sure this configuration matches it. If there isn't
193
+ * one defined in the platform, you can decide to either create a suitable one here or leave it
194
+ * undefined. Tables without coalesce strategies will rely on their GUIDs to determine identity.
195
+ *
196
+ * For advanced use cases where simple column-based coalesce strategies cannot be used, you may
197
+ * define a dynamic coalesce strategy by supplying a function that accepts the properties of a
198
+ * record and returns an object with the desired coalesce keys.
199
+ *
200
+ * Refer to CoalesceStrategies.java to find platform-defined coalesce strategies:
201
+ * https://code.devsnc.com/dev/glide/blob/master/glide/src/com/glide/script/coalesce/CoalesceStrategies.java
202
+ */
203
+ coalesce?: CoalesceStrategy;
204
+ /**
205
+ * You can think of the relationship between two tables as a parent-child relationship. Usually,
206
+ * the child references the parent via a foreign key. For example, sys_security_acl_role (child)
207
+ * references sys_security_acl (parent) via a reference column. This is the most basic type of
208
+ * relationship. In this case, the ACL plugin should handle the parent record and the children
209
+ * as part of the same entity. That's because the full definition of an ACL includes both the
210
+ * top-level sys_security_acl record AND the sys_security_acl_role M2M records which link it to
211
+ * its roles. This type of relationship, where a child record is part of a singular entity with
212
+ * its parent, is called a "descendant" relationship.
213
+ *
214
+ * sys_security_acl <- sys_security_acl_role (descendant relationship)
215
+ *
216
+ * Sometimes, relationships are the other way around, where the parent references the child. To
217
+ * continue the ACL example, sys_security_acl_role (parent) references sys_user_role (child) via
218
+ * a reference column. This is called an "inverse" relationship because it goes parent -> child
219
+ * instead of child -> parent. However, this would NOT be considered a "descendant" relationship
220
+ * because the role itself is not part of the ACL definition. The ACL and the role are related,
221
+ * but the role itself is its own separate entity.
222
+ *
223
+ * sys_security_acl_role <- sys_user_role (inverse non-descendant relationship)
224
+ *
225
+ * So far we've only explored relationships based on foreign keys (reference columns). In these
226
+ * cases your "via" would simply be the name of the reference column that connects them, either
227
+ * on the child table (normal relationship) or the parent (inverse relationship). However, it's
228
+ * also possible for two tables to be related by matching the values from one or more columns on
229
+ * both tables. For example, sys_db_object (parent) and sys_dictionary (child) are related by
230
+ * matching the "name" columns from each table. In other words, if a sys_db_object record has a
231
+ * value of "incident" in its "name" column, then any sys_dictionary records that also have the
232
+ * value "incident" in their "name" columns are its children. These children are also considered
233
+ * "descendants" because they are all part of the same table entity. In these cases, your "via"
234
+ * would be represented as key-value pairs instead of a single column name. The keys should be
235
+ * the names of columns on the child table, and the values should be the names of columns that
236
+ * should be matched on the parent table. (For "inverse" relationships, the key-value pairs are
237
+ * flipped.)
238
+ *
239
+ * sys_db_object <- sys_dictionary (descendant relationship by matching "name":"name")
240
+ */
241
+ relationships?: Relationships;
242
+ /**
243
+ * Transforms a record into a shape. Almost all plugins should implement this, as it is
244
+ * the fundamental transformation step in the process of turning ServiceNow records into
245
+ * Fluent code, or bidirectionally syncing changes to existing Fluent code.
246
+ *
247
+ * @param record - The record to transform
248
+ * @param context - Context with useful services and information
249
+ * @returns A result indicating whether the transformation was successful and, if so, the
250
+ * resulting shape
251
+ */
252
+ toShape?(record: Record, context: RecordContext): Result<Shape> | Promise<Result<Shape>>;
253
+ /**
254
+ * Transforms a database record into output file(s). Plugins should only implement this
255
+ * if the records they handle must be serialized to some specialized non-standard format.
256
+ * Records that follow the usual ServiceNow format do NOT need to be handled here. This
257
+ * transformation is the last step in the build process.
258
+ *
259
+ * @param record - The record to transform
260
+ * @param context - Context with useful services and information
261
+ * @returns A result indicating whether the transformation was successful and, if so, the
262
+ * resulting output file(s)
263
+ */
264
+ toFile?(record: Record, context: RecordContext): Result<OutputFile | OutputFile[]> | Promise<Result<OutputFile | OutputFile[]>>;
265
+ };
266
+ };
267
+ /**
268
+ * The files this plugin handles. Plugins that do not introduce new file types should not
269
+ * need to implement anything here.
270
+ */
271
+ files?: {
272
+ /**
273
+ * A regex pattern or predicate to apply to a file's path to determine if it should be handled by this plugin.
274
+ */
275
+ matcher?: RegExp | ((path: string, context: Context) => boolean | Promise<boolean>);
276
+ /**
277
+ * Indicates whether this file should be parsed as an entry point when generating output. (Default: false)
278
+ */
279
+ entryPoint?: boolean;
280
+ /**
281
+ * Transforms a file into record(s).
282
+ *
283
+ * @param file - The file to transform
284
+ * @param context - Context object with useful services and information
285
+ * @returns A result indicating whether the transformation was successful and, if so, the
286
+ * resulting record(s)
287
+ */
288
+ toRecord?(file: File, context: Context): Result<Record> | Promise<Result<Record>>;
289
+ }[];
290
+ };
291
+ type SearchableRelationships = {
292
+ [table: string]: Relationships;
293
+ };
294
+ export declare class Plugin {
295
+ private readonly config;
296
+ private readonly nodeToShapeCache;
297
+ private readonly shapeToSubclassCache;
298
+ private readonly shapeToRecordCache;
299
+ private readonly relationships;
300
+ private readonly references;
301
+ private constructor();
302
+ private parseRelationships;
303
+ /**
304
+ * Creates a new Fluent plugin from the provided configuration.
305
+ *
306
+ * Plugins are the primary mechanism for extending the Fluent DSL and providing support for
307
+ * new types of ServiceNow entities. Plugins implement handlers responsible for parsing and
308
+ * transforming Fluent code, ServiceNow records, and any other files that exist within a
309
+ * Fluent project.
310
+ *
311
+ * The build system orchestrates the plugins together to carry a project through all the
312
+ * stages of building and bidirectionally syncing a Fluent project, invoking each plugin's
313
+ * handlers at the appropriate points in the process, and providing the relevant inputs and
314
+ * context.
315
+ *
316
+ * During a regular build, the stages are:
317
+ *
318
+ * 1. Traverse the full AST of all the Fluent code, transforming each node into a shape
319
+ * 2. Transform each shape into a more specific subclass of that shape
320
+ * 3. Transform each subclassed shape into one or more ServiceNow records
321
+ * 4. Serialize each record into an output file
322
+ *
323
+ * During bidirectional sync, the stages are:
324
+ *
325
+ * 1. Perform stage 1 from the regular build process to get the existing shapes
326
+ * 2. Perform stage 2 from the regular build process to subclass those existing shapes
327
+ * 3. Perform stage 3 from the regular build process to get the existing records
328
+ * 4. Parse input files (usually XML from a ServiceNow instance) to get the incoming records
329
+ * 5. Merge the incoming records into the existing records so that all changes are reflected
330
+ * 6. Transform each merged record into a shape
331
+ * 7. Commit each shape to the Fluent AST, generating new nodes as needed
332
+ *
333
+ * @example
334
+ * // Stages of a regular build
335
+ * const CoolPlugin = Plugin.create({
336
+ * name: 'CoolPlugin',
337
+ * nodes: [
338
+ * {
339
+ * node: 'CallExpression',
340
+ * toShape(node) {
341
+ * // BUILD STAGE 1: A CallExpression node is transformed into a CallExpressionShape.
342
+ * }
343
+ * }
344
+ * ],
345
+ * shapes: [
346
+ * {
347
+ * shape: CallExpressionShape,
348
+ * toSubclass(shape) {
349
+ * // BUILD STAGE 2: The CallExpressionShape from stage 1 is transformed into a CoolShape.
350
+ * }
351
+ * },
352
+ * {
353
+ * shape: CoolShape,
354
+ * toRecord(shape) {
355
+ * // BUILD STAGE 3: The CoolShape from stage 2 is transformed into a cool_table record.
356
+ * }
357
+ * }
358
+ * ],
359
+ * records: {
360
+ * cool_table: {
361
+ * toFile(record) {
362
+ * // BUILD STAGE 4: The cool_table record from stage 3 is serialized into an output file.
363
+ * }
364
+ * }
365
+ * },
366
+ * })
367
+ *
368
+ * @example
369
+ * // Stages of bidirectional sync
370
+ * const CoolPlugin = Plugin.create({
371
+ * name: 'CoolPlugin',
372
+ * nodes: [
373
+ * {
374
+ * node: 'CallExpression',
375
+ * toShape(node) {
376
+ * // SYNC STAGE 1: An existing CallExpression node is transformed into a CallExpressionShape.
377
+ * }
378
+ * }
379
+ * ],
380
+ * shapes: [
381
+ * {
382
+ * shape: CallExpressionShape,
383
+ * toSubclass(shape) {
384
+ * // SYNC STAGE 2: The existing CallExpressionShape from stage 1 is transformed into a CoolShape
385
+ * },
386
+ * commit(shape, target) {
387
+ * // SYNC STAGE 7: The new CoolShape from stage 6, which now contains the changes from the
388
+ * // incoming cool_table record, is committed to the original CallExpression node.
389
+ * //
390
+ * // NOTES:
391
+ * // - Since CoolShape extends CallExpressionShape, and there is no commit function
392
+ * // for CoolShape, this commit function is used. If, for some reason, CoolShape
393
+ * // needed to be committed differently than other CallExpressionShapes, then this
394
+ * // plugin would need to implement a commit function for CoolShape.
395
+ * // - If the incoming cool_table record didn't already exist in the code, then the
396
+ * // build system would generate an arbitrary new node before passing it into this
397
+ * // commit function as the target. So the implementation should never assume that
398
+ * // the target is a CallExpression node.
399
+ * }
400
+ * },
401
+ * {
402
+ * shape: CoolShape,
403
+ * toRecord(shape) {
404
+ * // SYNC STAGE 3: The existing CoolShape from stage 2 is transformed into a cool_table record.
405
+ * }
406
+ * }
407
+ * ],
408
+ * files: [
409
+ * {
410
+ * extension: 'xml',
411
+ * toRecord(file) {
412
+ * // SYNC STAGE 4: An incoming XML file with changes is parsed into a cool_table record.
413
+ * }
414
+ * }
415
+ * ],
416
+ * records: {
417
+ * cool_table: {
418
+ * toShape(record) {
419
+ * // SYNC STAGE 6: After the incoming cool_table record from stage 4 is merged into the
420
+ * // existing one from stage 3, the merged record is transformed back into a CoolShape.
421
+ * }
422
+ * }
423
+ * },
424
+ * })
425
+ */
426
+ static create<const N extends SupportedKindName[], const S extends ShapeClass[]>(config: PluginConfig<N, S>): Plugin;
427
+ getName(): string;
428
+ getDescendants(parent: Record, database: Database): Record[];
429
+ getCoalesceStrategy(table: string): CoalesceStrategy | undefined;
430
+ getCoalesceTables(): string[];
431
+ getTables(relationships?: Relationships, tables?: string[]): Set<string>;
432
+ getReferenceColumns(table: string): {
433
+ [column: string]: string;
434
+ };
435
+ getRelationships(): SearchableRelationships;
436
+ flushCache(): void;
437
+ nodeToShape(node: SupportedNode, context: Omit<Context, 'self'>): Promise<Result<Shape>>;
438
+ commit(shape: Shape, target: ts.Node, context: Omit<CommitContext, 'self'>): Promise<CommitResult>;
439
+ shapeToSubclass<const S extends Shape>(shape: S, context: Omit<Context, 'self'>): Result<S>;
440
+ shapeToRecord(shape: Shape, context: Omit<Context, 'self'>): Promise<Result<Record>>;
441
+ private recordToShape0;
442
+ recordToShape({ record, database, context, }: {
443
+ record: Record;
444
+ database: Database;
445
+ context: Omit<Context, 'self'>;
446
+ }): Promise<Result<Shape>>;
447
+ recordsToShapes({ database, creatorOnly, changedOnly, mode, handledRecords, context, }: {
448
+ database: Database;
449
+ creatorOnly: boolean;
450
+ changedOnly?: boolean;
451
+ mode: 'explicit' | 'catch-all';
452
+ handledRecords: Database;
453
+ context: Omit<Context, 'self'>;
454
+ }): Promise<Result<Shape[]>>;
455
+ recordToFile(record: Record, context: Omit<RecordContext, 'self'>): Promise<Result<OutputFile | OutputFile[]>>;
456
+ recordsToFiles({ database, mode, handledGuids, context, }: {
457
+ database: Database;
458
+ mode: 'explicit' | 'catch-all';
459
+ handledGuids: Set<string>;
460
+ context: Omit<Context, 'self'>;
461
+ }): Promise<Result<OutputFile[]>>;
462
+ isEntryPoint(pathOrNode: string | SupportedNode, context: Omit<Context, 'self'>): Promise<boolean>;
463
+ fileToRecord(file: File, context: Omit<Context, 'self'>): Promise<Result<Record>>;
464
+ inspect(shape: Shape, context: Context): void;
465
+ }
466
+ export declare class Plugins {
467
+ private readonly plugins;
468
+ constructor(plugins: Plugin[]);
469
+ toArray(): Plugin[];
470
+ add(plugin: Plugin): void;
471
+ getCoalesceStrategy(table: string): CoalesceStrategy | undefined;
472
+ getCoalesceTables(): Set<string>;
473
+ getReferenceColumns(table: string): {
474
+ [column: string]: string;
475
+ };
476
+ isEntryPoint(pathOrNode: string | SupportedNode, context: Omit<Context, 'self'>): Promise<boolean>;
477
+ }
478
+ export {};