@servicenow/sdk-build-core 4.6.1 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/compiler.d.ts +2 -0
  2. package/dist/compiler.js +13 -7
  3. package/dist/compiler.js.map +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +1 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/now-config.d.ts +37 -0
  8. package/dist/now-config.js +9 -0
  9. package/dist/now-config.js.map +1 -1
  10. package/dist/package-inventory.d.ts +15 -0
  11. package/dist/package-inventory.js +59 -0
  12. package/dist/package-inventory.js.map +1 -0
  13. package/dist/plugins/context.d.ts +2 -2
  14. package/dist/plugins/index.d.ts +0 -1
  15. package/dist/plugins/index.js +0 -1
  16. package/dist/plugins/index.js.map +1 -1
  17. package/dist/plugins/plugin.d.ts +41 -53
  18. package/dist/plugins/plugin.js +502 -160
  19. package/dist/plugins/plugin.js.map +1 -1
  20. package/dist/plugins/shape.d.ts +13 -2
  21. package/dist/plugins/shape.js +96 -15
  22. package/dist/plugins/shape.js.map +1 -1
  23. package/dist/taxonomy.js +7 -2
  24. package/dist/taxonomy.js.map +1 -1
  25. package/dist/telemetry/clients/detect-agent.d.ts +4 -0
  26. package/dist/telemetry/clients/detect-agent.js +84 -0
  27. package/dist/telemetry/clients/detect-agent.js.map +1 -0
  28. package/dist/telemetry/clients/node-client.d.ts +2 -0
  29. package/dist/telemetry/clients/node-client.js +10 -9
  30. package/dist/telemetry/clients/node-client.js.map +1 -1
  31. package/dist/telemetry/index.d.ts +1 -1
  32. package/now.config.schema.json +19 -0
  33. package/package.json +9 -5
  34. package/src/compiler.ts +14 -7
  35. package/src/index.ts +1 -0
  36. package/src/now-config.ts +11 -0
  37. package/src/package-inventory.ts +75 -0
  38. package/src/plugins/context.ts +2 -2
  39. package/src/plugins/index.ts +0 -1
  40. package/src/plugins/plugin.ts +682 -228
  41. package/src/plugins/shape.ts +115 -24
  42. package/src/taxonomy.ts +8 -2
  43. package/src/telemetry/clients/detect-agent.ts +88 -0
  44. package/src/telemetry/clients/node-client.ts +12 -8
  45. package/src/telemetry/index.ts +1 -1
  46. package/dist/plugins/cache.d.ts +0 -15
  47. package/dist/plugins/cache.js +0 -22
  48. package/dist/plugins/cache.js.map +0 -1
  49. package/dist/plugins/usage.d.ts +0 -11
  50. package/dist/plugins/usage.js +0 -26
  51. package/dist/plugins/usage.js.map +0 -1
  52. package/src/plugins/cache.ts +0 -23
  53. package/src/plugins/usage.ts +0 -26
@@ -575,22 +575,26 @@ export abstract class StringShape extends Shape<string> {
575
575
  }
576
576
 
577
577
  static escapeSingleQuotes(str: string): string {
578
- return str.replaceAll('\\', '\\\\').replaceAll("'", "\\'")
578
+ // Escape \r last to avoid double-escaping the backslash we introduce
579
+ return str.replaceAll('\\', '\\\\').replaceAll("'", "\\'").replaceAll('\r', '\\r')
579
580
  }
580
581
 
581
582
  static escapeBackticks(str: string): string {
582
- return str.replace(/[`\\]|\${/g, (char) => {
583
- switch (char) {
584
- case '`':
585
- return '\\`'
586
- case '\\':
587
- return '\\' + char
588
- case '${':
589
- return '\\${'
590
- default:
591
- return char
592
- }
593
- })
583
+ // Escape \r last to avoid double-escaping the backslash we introduce
584
+ return str
585
+ .replace(/[`\\]|\${/g, (char) => {
586
+ switch (char) {
587
+ case '`':
588
+ return '\\`'
589
+ case '\\':
590
+ return '\\' + char
591
+ case '${':
592
+ return '\\${'
593
+ default:
594
+ return char
595
+ }
596
+ })
597
+ .replaceAll('\r', '\\r')
594
598
  }
595
599
 
596
600
  static escapeCdataTags(str: string): string {
@@ -611,7 +615,7 @@ export class StringLiteralShape extends StringShape {
611
615
  }
612
616
 
613
617
  override getCode(): string {
614
- return this.includes('\n')
618
+ return this.literalText.includes('\n')
615
619
  ? `\`${StringShape.escapeBackticks(this.literalText)}\``
616
620
  : `'${StringShape.escapeSingleQuotes(this.literalText)}'`
617
621
  }
@@ -914,6 +918,7 @@ function assignWithoutOverwriting(target: NonNullable<object>, source: unknown)
914
918
  type ObjectPropertyOptions = {
915
919
  nonDefaultsOnly?: boolean
916
920
  resolve?: boolean
921
+ keys?: string[]
917
922
  }
918
923
 
919
924
  export class ObjectShape extends Shape<globalThis.Record<string, unknown>> {
@@ -958,14 +963,16 @@ export class ObjectShape extends Shape<globalThis.Record<string, unknown>> {
958
963
  properties({
959
964
  nonDefaultsOnly = false,
960
965
  resolve = true,
966
+ keys = undefined,
961
967
  }: ObjectPropertyOptions = {}): globalThis.Record<string, Shape> {
962
968
  const result: globalThis.Record<string, Shape> = {}
969
+ const selectedKeys = keys ?? Object.keys(this.setProperties)
963
970
 
964
971
  if (nonDefaultsOnly) {
965
972
  // Only include properties that differ from defaults
966
- for (const k in this.setProperties) {
973
+ for (const k of selectedKeys) {
967
974
  const v = this.setProperties[k]
968
- if (v && v.isDefined() && !v.equals(this.getDefault(k))) {
975
+ if (v?.isDefined() && !v.equals(this.getDefault(k))) {
969
976
  result[k] = resolve && v.isResolvable() ? v.resolve() : v
970
977
  }
971
978
  }
@@ -973,14 +980,15 @@ export class ObjectShape extends Shape<globalThis.Record<string, unknown>> {
973
980
  }
974
981
 
975
982
  // Iterate set properties first to preserve ordering
976
- for (const k in this.setProperties) {
983
+ for (const k of selectedKeys) {
977
984
  const v = this.setProperties[k]
978
985
  if (v) {
979
986
  result[k] = resolve && v.isResolvable() ? v.resolve() : v
980
987
  }
981
988
  }
982
989
 
983
- for (const k in this.defaultProperties) {
990
+ const defaultKeys = keys ?? Object.keys(this.defaultProperties)
991
+ for (const k of defaultKeys) {
984
992
  if (!this.setProperties[k] || this.setProperties[k].isUndefined()) {
985
993
  const v = this.defaultProperties[k]
986
994
  if (v) {
@@ -999,7 +1007,7 @@ export class ObjectShape extends Shape<globalThis.Record<string, unknown>> {
999
1007
  get(propertyOrPath: string | [string, ...string[]], resolve = true): Shape {
1000
1008
  const [property, next, ...rest] = typeof propertyOrPath === 'string' ? [propertyOrPath] : propertyOrPath
1001
1009
  const propertyAliases = [property, ...this.getAliases(property)]
1002
- const properties = this.properties({ resolve })
1010
+ const properties = this.properties({ resolve, keys: propertyAliases })
1003
1011
  const match = propertyAliases.find((p) => p in properties)
1004
1012
  const value = match !== undefined ? properties[match] : undefined
1005
1013
  return (
@@ -1048,7 +1056,7 @@ export class ObjectShape extends Shape<globalThis.Record<string, unknown>> {
1048
1056
  properties = typeof properties === 'string' ? [properties] : properties
1049
1057
  const regex = new RegExp(`^(${properties.join('|')})$`)
1050
1058
  return Object.fromEntries(
1051
- this.entries(options)
1059
+ this.entries({ ...options, keys: properties })
1052
1060
  .filter(([k]) => regex.test(k))
1053
1061
  .map(([k, v]) => [k, v])
1054
1062
  )
@@ -1348,17 +1356,62 @@ function getDefaultCategoryFromTable(table: string): InstallCategory {
1348
1356
  }
1349
1357
 
1350
1358
  function getInstallCategoryFromInstallMethod(installMethod: string): InstallCategory {
1351
- return installMethod === 'demo' ? 'unload.demo' : 'unload'
1359
+ if (installMethod === 'demo') {
1360
+ return 'unload.demo'
1361
+ }
1362
+ if (installMethod === 'once') {
1363
+ return 'apply_once'
1364
+ }
1365
+ if (installMethod === 'first install') {
1366
+ return 'unload'
1367
+ }
1368
+ throw new Error(`Invalid installMethod: '${installMethod}'. Expected 'demo', 'first install', or 'once'.`)
1369
+ }
1370
+
1371
+ export function getInstallCategoryFromPath(filePath: string): InstallCategory | undefined {
1372
+ const segments = filePath.split(/[/\\]/)
1373
+ if (segments.includes('unload.demo')) {
1374
+ return 'unload.demo'
1375
+ }
1376
+ if (segments.includes('unload')) {
1377
+ return 'unload'
1378
+ }
1379
+ if (segments.includes('apply_once')) {
1380
+ return 'apply_once'
1381
+ }
1382
+ return undefined
1383
+ }
1384
+
1385
+ function isFile(source: Source): source is { path: string; content: string } {
1386
+ return typeof source === 'object' && source !== null && 'path' in source && 'content' in source
1352
1387
  }
1353
1388
 
1354
1389
  export function getInstallCategory(source: Source, table: string): InstallCategory {
1355
1390
  let installCategory: InstallCategory = getDefaultCategoryFromTable(table)
1391
+
1392
+ // Check for $meta.installMethod in Fluent code (build direction)
1356
1393
  if (source instanceof CallExpressionShape) {
1357
1394
  const installMethod = source.getArgument(0).ifObject()?.get(['$meta', 'installMethod']).ifString()?.getValue()
1358
1395
  if (installMethod) {
1359
1396
  installCategory = getInstallCategoryFromInstallMethod(installMethod)
1360
1397
  }
1361
1398
  }
1399
+ // Check for source directory in XML file path (transform direction)
1400
+ else if (isFile(source)) {
1401
+ const categoryFromPath = getInstallCategoryFromPath(source.path)
1402
+ if (categoryFromPath) {
1403
+ installCategory = categoryFromPath
1404
+ }
1405
+ }
1406
+ // Check for source directory from Product's original file path
1407
+ else if (source instanceof Product) {
1408
+ const filePath = source.getOriginalFilePath()
1409
+ const categoryFromPath = getInstallCategoryFromPath(filePath)
1410
+ if (categoryFromPath) {
1411
+ installCategory = categoryFromPath
1412
+ }
1413
+ }
1414
+
1362
1415
  return installCategory
1363
1416
  }
1364
1417
 
@@ -1369,6 +1422,8 @@ export class Record extends ObjectShape {
1369
1422
  private readonly related: Record[] = []
1370
1423
  private readonly action: Action
1371
1424
  private readonly installCategory: InstallCategory
1425
+ private fieldAccessTracker: Set<string> | undefined
1426
+ private overrideKeys: Set<string> | undefined
1372
1427
 
1373
1428
  constructor({
1374
1429
  source,
@@ -1413,6 +1468,29 @@ export class Record extends ObjectShape {
1413
1468
  return Record.isDeleteAction(this.getAction())
1414
1469
  }
1415
1470
 
1471
+ startTracking(): void {
1472
+ this.fieldAccessTracker = new Set()
1473
+ }
1474
+
1475
+ getTrackedFields(): Set<string> {
1476
+ return this.fieldAccessTracker ?? new Set()
1477
+ }
1478
+
1479
+ withOverrideKeys(keys: Set<string>): this {
1480
+ this.overrideKeys = keys
1481
+ return this
1482
+ }
1483
+
1484
+ getOverrideKeys(): Set<string> | undefined {
1485
+ return this.overrideKeys
1486
+ }
1487
+
1488
+ override get(propertyOrPath: string | [string, ...string[]], resolve = true): Shape {
1489
+ const property = typeof propertyOrPath === 'string' ? propertyOrPath : propertyOrPath[0]
1490
+ this.fieldAccessTracker?.add(property)
1491
+ return super.get(propertyOrPath, resolve)
1492
+ }
1493
+
1416
1494
  // getUpdateName(): string {
1417
1495
  // // TODO: Provide a way to override this for non-standard coalesce strategies, or
1418
1496
  // // just hard-code the very short list of special cases from UpdateName.java
@@ -1428,7 +1506,8 @@ export class Record extends ObjectShape {
1428
1506
  /**
1429
1507
  * Returns the direct related records (one level deep only).
1430
1508
  * Does not include nested descendants.
1431
- * @deprecated Use `flat()` instead.
1509
+ * @deprecated Prefer `flat()` for read-only traversal of all descendants. Avoid `getRelated()`
1510
+ * unless you need the immediate-children relationship to reconstruct nested `.with()` chains.
1432
1511
  */
1433
1512
  getRelated(): Record[] {
1434
1513
  return this.related
@@ -1447,7 +1526,8 @@ export class Record extends ObjectShape {
1447
1526
  }
1448
1527
 
1449
1528
  override merge(other: NonNullable<object>): Record {
1450
- return new Record({
1529
+ const otherKeys = other instanceof Record ? other.overrideKeys : undefined
1530
+ const merged = new Record({
1451
1531
  source: this.getSource(),
1452
1532
  id: this.getId(),
1453
1533
  action: other instanceof Record ? other.getAction() : this.getAction(),
@@ -1456,6 +1536,10 @@ export class Record extends ObjectShape {
1456
1536
  })
1457
1537
  .setCreator(this.getCreator())
1458
1538
  .with(...this.related)
1539
+ if (this.overrideKeys || otherKeys) {
1540
+ merged.withOverrideKeys(new Set([...(this.overrideKeys ?? []), ...(otherKeys ?? [])]))
1541
+ }
1542
+ return merged
1459
1543
  }
1460
1544
 
1461
1545
  override equals(other: unknown): boolean {
@@ -1497,6 +1581,7 @@ export type ResolvedCoalesceKeys = globalThis.Record<string, string>
1497
1581
  export class RecordId extends StringShape {
1498
1582
  private readonly table: string
1499
1583
  private readonly guid: string | (() => string)
1584
+ private resolvedGuid: string | undefined
1500
1585
  private readonly keys: CoalesceKeys | undefined
1501
1586
  private readonly nowIdKey: string | number | undefined
1502
1587
 
@@ -1577,7 +1662,13 @@ export class RecordId extends StringShape {
1577
1662
  }
1578
1663
 
1579
1664
  override getValue(): string {
1580
- return typeof this.guid === 'string' ? this.guid : this.guid()
1665
+ if (typeof this.guid === 'string') {
1666
+ return this.guid
1667
+ }
1668
+ if (!this.resolvedGuid) {
1669
+ this.resolvedGuid = this.guid()
1670
+ }
1671
+ return this.resolvedGuid
1581
1672
  }
1582
1673
 
1583
1674
  override equals(other: unknown): boolean {
package/src/taxonomy.ts CHANGED
@@ -3,7 +3,6 @@ import kebabCase from 'lodash/kebabCase'
3
3
 
4
4
  const TableNames = {
5
5
  // Automation tables
6
- SYS_ALIAS: 'sys_alias',
7
6
  SYS_HUB_ACTION_TYPE_DEFINITION: 'sys_hub_action_type_definition',
8
7
  SYS_HUB_TRIGGER_DEFINITION: 'sys_hub_trigger_definition',
9
8
  SYS_HUB_FLOW: 'sys_hub_flow',
@@ -219,6 +218,11 @@ const TableNames = {
219
218
  SYS_UX_PAGE_REGISTRY: 'sys_ux_page_registry',
220
219
  SYS_TEMPLATE: 'sys_template',
221
220
  SYSRULE_VIEW: 'sysrule_view',
221
+
222
+ //Connection & Credential Aliases
223
+ SYS_ALIAS: 'sys_alias',
224
+ SYS_ALIAS_TEMPLATES: 'sys_alias_templates',
225
+ SYS_RETRY_POLICY: 'sys_retry_policy',
222
226
  }
223
227
 
224
228
  // String format: one or more path segments separated by '/' (e.g., 'server-development/business-rule' or 'integration/outbound/rest-api')
@@ -231,7 +235,9 @@ const taxonomyMapping = z
231
235
  [TableNames.SYS_HUB_ACTION_TYPE_DEFINITION]: taxonomyItem.default('automation/action'),
232
236
  [TableNames.SYS_HUB_TRIGGER_DEFINITION]: taxonomyItem.default('automation/trigger'),
233
237
  [TableNames.SYS_PD_ACTIVITY_DEFINITION]: taxonomyItem.default('automation/activity-definition'),
234
- [TableNames.SYS_ALIAS]: taxonomyItem.default('automation/workflow-activity'),
238
+ [TableNames.SYS_ALIAS]: taxonomyItem.default('automation/connection-credential-aliases'),
239
+ [TableNames.SYS_ALIAS_TEMPLATES]: taxonomyItem.default('automation/connection-credential-aliases'),
240
+ [TableNames.SYS_RETRY_POLICY]: taxonomyItem.default('automation/connection-credential-aliases'),
235
241
  [TableNames.SYS_DECISION]: taxonomyItem.default('automation/decision-table'),
236
242
  [TableNames.SYSEVENT_EMAIL_TEMPLATE]: taxonomyItem.default('automation/email-template'),
237
243
  [TableNames.SYSEVENT_EMAIL_ACTION]: taxonomyItem.default('automation/notification'),
@@ -0,0 +1,88 @@
1
+ import { path } from '../../path'
2
+
3
+ type Env = NodeJS.ProcessEnv
4
+
5
+ /**
6
+ * Checks whether any directory segment of `fullPath` matches `name`
7
+ * (case-insensitive). Matches both the bare name and the `.app` bundle variant
8
+ * so it handles macOS (`/Applications/Cursor.app/...`) and Windows
9
+ * (`C:\Users\u\AppData\Local\Programs\cursor\...`) without the false positives
10
+ * that a plain substring check would produce on paths like `/home/cursor-fan/`.
11
+ */
12
+ function pathHasSegment(fullPath: string, name: string): boolean {
13
+ const target = name.toLowerCase()
14
+ const targetApp = `${target}.app`
15
+ // pathe normalizes Windows separators to `/`, so a single split works on both platforms.
16
+ return path
17
+ .normalize(fullPath)
18
+ .split('/')
19
+ .some((segment) => {
20
+ const lower = segment.toLowerCase()
21
+ return lower === target || lower === targetApp
22
+ })
23
+ }
24
+
25
+ export function detectCodingAgent(env: Env): string | undefined {
26
+ if (env['CLAUDECODE']) {
27
+ return 'claudecode'
28
+ }
29
+ if (env['GEMINI_CLI']) {
30
+ return 'gemini'
31
+ }
32
+ if (env['CODEX_CI']) {
33
+ return 'codex'
34
+ }
35
+ if (env['CLINE_ACTIVE'] === 'true' || env['CLINE_WRAPPER_PATH']) {
36
+ return 'cline'
37
+ }
38
+ if (env['KIRO_SESSION_ID']) {
39
+ return 'kiro'
40
+ }
41
+ return undefined
42
+ }
43
+
44
+ export function detectIde(env: Env, platform: NodeJS.Platform): string | undefined {
45
+ if (env['TERM_PROGRAM'] === 'kiro') {
46
+ return 'kiro'
47
+ }
48
+ if (env['ZED_TERM'] === 'true' || env['TERM_PROGRAM'] === 'zed') {
49
+ return 'zed'
50
+ }
51
+ if (env['TERMINAL_EMULATOR'] === 'JetBrains-JediTerm') {
52
+ return 'jetbrains'
53
+ }
54
+
55
+ // Real paths on macOS are e.g. `/Applications/Cursor.app/Contents/...`
56
+ // and on Windows `C:\Users\...\Programs\cursor\...`. Match on a directory
57
+ // segment (case-insensitive, with optional `.app` suffix) rather than a
58
+ // raw substring so that user dir names containing 'cursor' / 'windsurf'
59
+ // don't produce false positives.
60
+ const askpassPath = env['VSCODE_GIT_ASKPASS_NODE']
61
+ if (askpassPath) {
62
+ if (pathHasSegment(askpassPath, 'cursor')) {
63
+ return 'cursor'
64
+ }
65
+ if (pathHasSegment(askpassPath, 'windsurf')) {
66
+ return 'windsurf'
67
+ }
68
+ }
69
+
70
+ if (platform === 'darwin') {
71
+ const bundleId = env['__CFBundleIdentifier']?.toLowerCase()
72
+ if (bundleId?.includes('cursor')) {
73
+ return 'cursor'
74
+ }
75
+ if (bundleId?.includes('windsurf')) {
76
+ return 'windsurf'
77
+ }
78
+ if (bundleId === 'com.microsoft.vscode') {
79
+ return 'vscode'
80
+ }
81
+ }
82
+
83
+ if (env['VSCODE_PID'] || env['VSCODE_IPC_HOOK'] || env['VSCODE_INJECTION'] || env['TERM_PROGRAM'] === 'vscode') {
84
+ return 'vscode'
85
+ }
86
+
87
+ return undefined
88
+ }
@@ -2,6 +2,7 @@ import * as os from 'os'
2
2
  import ciInfo from 'ci-info'
3
3
  import type { TelemetryEventData, InstanceSettings } from '../types'
4
4
  import { AbstractAppSeeClient } from './abstract-client'
5
+ import { detectCodingAgent, detectIde } from './detect-agent'
5
6
 
6
7
  export class NodeTelemetryClient extends AbstractAppSeeClient {
7
8
  constructor(
@@ -40,13 +41,16 @@ export class NodeTelemetryClient extends AbstractAppSeeClient {
40
41
  }
41
42
 
42
43
  override getDefaultDataValues() {
43
- const codingAgentData: TelemetryEventData<{ codingAgent?: string }> = {}
44
- if (process.env['GEMINI_CLI']) {
45
- codingAgentData.codingAgent = 'gemini'
46
- } else if (process.env['CLAUDECODE']) {
47
- codingAgentData.codingAgent = 'claudecode'
48
- } else if (process.env['CODEX_CI']) {
49
- codingAgentData.codingAgent = 'codex'
44
+ const env = process.env
45
+ const agentData: TelemetryEventData<{ codingAgent?: string; ide?: string }> = {}
46
+
47
+ const codingAgent = detectCodingAgent(env)
48
+ if (codingAgent) {
49
+ agentData.codingAgent = codingAgent
50
+ }
51
+ const ide = detectIde(env, process.platform)
52
+ if (ide) {
53
+ agentData.ide = ide
50
54
  }
51
55
 
52
56
  return {
@@ -54,7 +58,7 @@ export class NodeTelemetryClient extends AbstractAppSeeClient {
54
58
  version: this.sdkVersion || 'unknown',
55
59
  nodeVersion: process.version,
56
60
  clientName: this.clientName,
57
- ...codingAgentData,
61
+ ...agentData,
58
62
  ...this.applyCITelemetry(),
59
63
  }
60
64
  }
@@ -1,2 +1,2 @@
1
- export type { Telemetry, TelemetryEvent } from './types'
1
+ export type { Telemetry, TelemetryEvent, TelemetryEventData } from './types'
2
2
  export { TelemetryFactory } from './factory'
@@ -1,15 +0,0 @@
1
- type CacheEntry<V> = {
2
- success: true;
3
- value: V;
4
- } | {
5
- success: false;
6
- error: unknown;
7
- };
8
- export declare class Cache<K extends object, V> {
9
- private cache;
10
- get(key: K): CacheEntry<V> | undefined;
11
- put<const T extends V>(key: K, value: T): T;
12
- error<const T>(key: K, error: T): T;
13
- clear(): void;
14
- }
15
- export {};
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Cache = void 0;
4
- class Cache {
5
- cache = new WeakMap();
6
- get(key) {
7
- return this.cache.get(key);
8
- }
9
- put(key, value) {
10
- this.cache.set(key, { success: true, value });
11
- return value;
12
- }
13
- error(key, error) {
14
- this.cache.set(key, { success: false, error });
15
- return error;
16
- }
17
- clear() {
18
- this.cache = new WeakMap();
19
- }
20
- }
21
- exports.Cache = Cache;
22
- //# sourceMappingURL=cache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/plugins/cache.ts"],"names":[],"mappings":";;;AAEA,MAAa,KAAK;IACN,KAAK,GAAG,IAAI,OAAO,EAAoB,CAAA;IAE/C,GAAG,CAAC,GAAM;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;IAED,GAAG,CAAoB,GAAM,EAAE,KAAQ;QACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC7C,OAAO,KAAK,CAAA;IAChB,CAAC;IAED,KAAK,CAAU,GAAM,EAAE,KAAQ;QAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;QAC9C,OAAO,KAAK,CAAA;IAChB,CAAC;IAED,KAAK;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,EAAE,CAAA;IAC9B,CAAC;CACJ;AApBD,sBAoBC"}
@@ -1,11 +0,0 @@
1
- import type { Plugin, Shape, File, ts } from '..';
2
- export declare class PluginUsageTracker {
3
- private readonly trackedSources;
4
- private readonly shapeCountPerPlugin;
5
- clearPluginShapeUsage(): void;
6
- addPluginShapeUsage(plugin: Plugin, source: ts.Node | Shape | File): void;
7
- getShapeCountPerPlugin(): {
8
- plugin: string;
9
- count: number;
10
- }[];
11
- }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PluginUsageTracker = void 0;
4
- class PluginUsageTracker {
5
- trackedSources = new Set();
6
- shapeCountPerPlugin = new Map();
7
- clearPluginShapeUsage() {
8
- this.trackedSources.clear();
9
- this.shapeCountPerPlugin.clear();
10
- }
11
- addPluginShapeUsage(plugin, source) {
12
- if (!this.trackedSources.has(source)) {
13
- this.trackedSources.add(source);
14
- const existingCount = this.shapeCountPerPlugin.get(plugin) ?? 0;
15
- this.shapeCountPerPlugin.set(plugin, existingCount + 1);
16
- }
17
- }
18
- getShapeCountPerPlugin() {
19
- return [...this.shapeCountPerPlugin.entries()].map(([plugin, count]) => ({
20
- plugin: plugin.getName().replace(/Plugin$/, ''), //Report just the names 'ACL', 'Record', etc for existing metrics compatibility
21
- count,
22
- }));
23
- }
24
- }
25
- exports.PluginUsageTracker = PluginUsageTracker;
26
- //# sourceMappingURL=usage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/plugins/usage.ts"],"names":[],"mappings":";;;AAEA,MAAa,kBAAkB;IACV,cAAc,GAAgC,IAAI,GAAG,EAAE,CAAA;IACvD,mBAAmB,GAAwB,IAAI,GAAG,EAAE,CAAA;IAErE,qBAAqB;QACjB,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAA;IACpC,CAAC;IAED,mBAAmB,CAAC,MAAc,EAAE,MAA8B;QAC9D,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAC/D,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,CAAC,CAAC,CAAA;QAC3D,CAAC;IACL,CAAC;IAED,sBAAsB;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACrE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,+EAA+E;YAChI,KAAK;SACR,CAAC,CAAC,CAAA;IACP,CAAC;CACJ;AAvBD,gDAuBC"}
@@ -1,23 +0,0 @@
1
- type CacheEntry<V> = { success: true; value: V } | { success: false; error: unknown }
2
-
3
- export class Cache<K extends object, V> {
4
- private cache = new WeakMap<K, CacheEntry<V>>()
5
-
6
- get(key: K): CacheEntry<V> | undefined {
7
- return this.cache.get(key)
8
- }
9
-
10
- put<const T extends V>(key: K, value: T): T {
11
- this.cache.set(key, { success: true, value })
12
- return value
13
- }
14
-
15
- error<const T>(key: K, error: T): T {
16
- this.cache.set(key, { success: false, error })
17
- return error
18
- }
19
-
20
- clear(): void {
21
- this.cache = new WeakMap()
22
- }
23
- }
@@ -1,26 +0,0 @@
1
- import type { Plugin, Shape, File, ts } from '..'
2
-
3
- export class PluginUsageTracker {
4
- private readonly trackedSources: Set<ts.Node | Shape | File> = new Set()
5
- private readonly shapeCountPerPlugin: Map<Plugin, number> = new Map()
6
-
7
- clearPluginShapeUsage() {
8
- this.trackedSources.clear()
9
- this.shapeCountPerPlugin.clear()
10
- }
11
-
12
- addPluginShapeUsage(plugin: Plugin, source: ts.Node | Shape | File) {
13
- if (!this.trackedSources.has(source)) {
14
- this.trackedSources.add(source)
15
- const existingCount = this.shapeCountPerPlugin.get(plugin) ?? 0
16
- this.shapeCountPerPlugin.set(plugin, existingCount + 1)
17
- }
18
- }
19
-
20
- getShapeCountPerPlugin() {
21
- return [...this.shapeCountPerPlugin.entries()].map(([plugin, count]) => ({
22
- plugin: plugin.getName().replace(/Plugin$/, ''), //Report just the names 'ACL', 'Record', etc for existing metrics compatibility
23
- count,
24
- }))
25
- }
26
- }