node-autotask 0.25.0 → 0.27.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 (49) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/MCP_TOOL_CATALOG.json +1063 -30
  3. package/MCP_TOOL_MANIFEST.md +82 -24
  4. package/N8N_MCP_MANIFEST.json +39 -8
  5. package/N8N_MCP_MANIFEST.md +9 -8
  6. package/README.md +11 -9
  7. package/capabilities.json +16956 -10596
  8. package/capabilities.schema.json +125 -0
  9. package/dist/capabilities.cjs +2 -2
  10. package/dist/capabilities.js +1 -1
  11. package/dist/{chunk-VUGZKP33.js → chunk-42ZUISDH.js} +997 -136
  12. package/dist/{chunk-WBMRACCV.cjs → chunk-5CC7LGNM.cjs} +16955 -10595
  13. package/dist/{chunk-Z5L7Q33V.cjs → chunk-5GGCSRT4.cjs} +947 -493
  14. package/dist/{chunk-EFR2XWRX.js → chunk-F7FVOXPQ.js} +16955 -10595
  15. package/dist/{chunk-XUB3S6AM.js → chunk-GURC52J7.js} +26 -2
  16. package/dist/{chunk-FKJ77K6Z.cjs → chunk-UHTZLUDE.cjs} +159 -135
  17. package/dist/{chunk-6PIJ6AZG.js → chunk-ZGTFVZL5.js} +478 -24
  18. package/dist/{chunk-2H7YI54B.cjs → chunk-ZJ4ONAQF.cjs} +1084 -223
  19. package/dist/{index-CZ94y401.d.ts → index-BIWy9m-a.d.ts} +414 -49
  20. package/dist/{index-C0OwQhon.d.cts → index-D4XYtn4s.d.cts} +414 -49
  21. package/dist/{index-BVtycq-6.d.cts → index-DQ9NgraW.d.cts} +322 -1
  22. package/dist/{index-BVtycq-6.d.ts → index-DQ9NgraW.d.ts} +322 -1
  23. package/dist/index.cjs +46 -24
  24. package/dist/index.d.cts +11 -5
  25. package/dist/index.d.ts +11 -5
  26. package/dist/index.js +28 -6
  27. package/dist/operations/index.cjs +147 -120
  28. package/dist/operations/index.d.cts +136 -7
  29. package/dist/operations/index.d.ts +136 -7
  30. package/dist/operations/index.js +33 -6
  31. package/dist/pool.cjs +42 -9
  32. package/dist/pool.d.cts +14 -3
  33. package/dist/pool.d.ts +14 -3
  34. package/dist/pool.js +38 -5
  35. package/dist/resources/index.cjs +21 -5
  36. package/dist/resources/index.d.cts +2 -2
  37. package/dist/resources/index.d.ts +2 -2
  38. package/dist/resources/index.js +20 -4
  39. package/dist/types/index.cjs +1 -1
  40. package/dist/types/index.d.cts +1 -1
  41. package/dist/types/index.d.ts +1 -1
  42. package/dist/types/index.js +1 -1
  43. package/docs/API.md +207 -9
  44. package/examples/mcp/schemas.ts +16 -7
  45. package/package.json +3 -3
  46. /package/dist/{chunk-FLB2X6O5.cjs → chunk-IXF7AKOJ.cjs} +0 -0
  47. /package/dist/{chunk-DMMMWO6A.js → chunk-RMG55JTF.js} +0 -0
  48. /package/dist/{chunk-IDPB4N2Q.cjs → chunk-SDYRQFGL.cjs} +0 -0
  49. /package/dist/{chunk-UPQIUWOS.js → chunk-WLTLB2ND.js} +0 -0
@@ -1,7 +1,7 @@
1
- import { a as AutotaskClient, ea as BlindSurfaceInfo, eb as RelationshipResource, ec as BlindSurfaceInventory, ed as BlindSurfaceRow, ee as CreateBlockerKind, ef as CreateGuidanceReport, Z as ZoneName, eg as FieldCacheKind, i as AutotaskConfigError } from '../index-C0OwQhon.cjs';
2
- export { eh as FIELD_CACHE_KINDS } from '../index-C0OwQhon.cjs';
3
- import { I as Identifier, cG as EmptyReasonInfo, dI as PickListValue, a as FilterCondition } from '../index-BVtycq-6.cjs';
4
- export { hp as PICKLIST_VALUE_NOT_SERVED_NOTE } from '../index-BVtycq-6.cjs';
1
+ import { a as AutotaskClient, es as BlindSurfaceInfo, et as RelationshipResource, eu as BlindSurfaceInventory, ev as BlindSurfaceRow, ew as CreateGuidanceRow, ex as CreateBlockerKind, ey as CreateGuidanceReport, Z as ZoneName, ez as FieldCacheKind, j as AutotaskConfigError } from '../index-D4XYtn4s.cjs';
2
+ export { eA as FIELD_CACHE_KINDS } from '../index-D4XYtn4s.cjs';
3
+ import { I as Identifier, cO as EmptyReasonInfo, e4 as PickListValue, a as FilterCondition } from '../index-DQ9NgraW.cjs';
4
+ export { hV as PICKLIST_VALUE_NOT_SERVED_NOTE } from '../index-DQ9NgraW.cjs';
5
5
  import { CapabilityRecord } from '../capabilities.cjs';
6
6
 
7
7
  /**
@@ -423,6 +423,69 @@ interface ProbeReachabilityResult {
423
423
  */
424
424
  declare function probeReachability(client: AutotaskClient, opts?: ProbeReachabilityOptions): Promise<ProbeReachabilityResult>;
425
425
 
426
+ /**
427
+ * `effectiveRequiredFields` — the ONE precedence rule for "what does a create
428
+ * really require" (issue #219 N4).
429
+ *
430
+ * Three sources answer that question, at three different coverages, and the
431
+ * SDK used to leave the choice to each caller:
432
+ * 1. `createGuidance.liveProvenPrefix` — the fields a live create actually
433
+ * demanded, in vendor-demand order (92 rows; the widest evidence);
434
+ * 2. `zoneFacts.createRequiredSet` — the hand-authored zone set (6
435
+ * resources);
436
+ * 3. the vendor field catalog's `isRequired` — the spec opinion (wrong for
437
+ * 68 of the 75 resources that carry a proven prefix).
438
+ *
439
+ * The order is FIXED and stated: live-proven > zone > spec, with the source
440
+ * named on the result (`from`). Both plan shapes stay where they are; this
441
+ * helper is the only place in the SDK that compares them.
442
+ *
443
+ * Value-conditioned prefixes: a prefix proven for one picklist value (e.g.
444
+ * `contracts.create`'s type-1 `estimatedRevenue`/`estimatedHours`/
445
+ * `estimatedCost`) is still returned whole with `from: 'live-proven'` — the
446
+ * condition itself lives on the create-guidance row (`blocker.message` +
447
+ * `vendorEvidence`), which a caller must read before treating the list as
448
+ * unconditional. Never flatten a conditioned row into "all these fields are
449
+ * always required"; the row's evidence is the qualifier.
450
+ */
451
+
452
+ /** Which source the returned field set came from (the precedence order). */
453
+ type RequiredFieldsSource = 'live-proven' | 'zone' | 'spec';
454
+ /** The effective required set + the source it came from. */
455
+ interface EffectiveRequiredFields {
456
+ /** The required field names, in the source's own order (vendor-demand order for a live-proven prefix). */
457
+ fields: string[];
458
+ /** `live-proven` (createGuidance.liveProvenPrefix) > `zone` (createRequiredSet) > `spec` (vendor isRequired). */
459
+ from: RequiredFieldsSource;
460
+ }
461
+ /** The plan zone-fact shape this helper reads (both shapes stay plan-owned). */
462
+ interface RequiredFieldsZoneFacts {
463
+ createRequiredSet?: string[];
464
+ createGuidance?: Pick<CreateGuidanceRow, 'liveProvenPrefix' | 'unproven'> | null;
465
+ }
466
+ /** The spec-side record this helper reads (the vendor field catalog's projection). */
467
+ interface RequiredFieldsRecord {
468
+ /** The vendor `isRequired` field names (the narrowest source). */
469
+ requiredFields?: readonly string[] | null;
470
+ }
471
+ /**
472
+ * Resolve the effective create-required set for one resource.
473
+ *
474
+ * ```ts
475
+ * import { effectiveRequiredFields } from 'node-autotask/operations';
476
+ * const eff = effectiveRequiredFields(
477
+ * { requiredFields: vendorRequiredNames }, // from operations.fieldCatalog
478
+ * RELATIONSHIP_MAP.contacts.zoneFacts, // the plan zone facts
479
+ * );
480
+ * // contacts: { fields: ['firstName', 'lastName', 'companyID', 'isActive'], from: 'live-proven' }
481
+ * ```
482
+ *
483
+ * An empty or absent higher source falls through to the next one; with no
484
+ * source at all the result is `{ fields: [], from: 'spec' }` — the name of the
485
+ * source is always stated, never a bare list.
486
+ */
487
+ declare function effectiveRequiredFields(record?: RequiredFieldsRecord | null, zoneFacts?: RequiredFieldsZoneFacts | null): EffectiveRequiredFields;
488
+
426
489
  /** The closed blocker-kind set (the gate re-derives it; unknown kind → CONFIG_ERROR). */
427
490
  /**
428
491
  * The closed blocker-kind set served by `operations.createGuidance`.
@@ -432,6 +495,15 @@ declare function probeReachability(client: AutotaskClient, opts?: ProbeReachabil
432
495
  * rather than forcing those rows into a misfitting class.
433
496
  */
434
497
  declare const CREATE_BLOCKER_KINDS: readonly CreateBlockerKind[];
498
+ /** One served create-guidance row: the plan row plus the effective required set (issue #219 N4). */
499
+ interface ServedCreateGuidanceRow extends CreateGuidanceRow {
500
+ /** The effective create-required set + the source it came from (`live-proven` > `zone` > `spec`). Read `blocker`/`vendorEvidence` before treating a value-conditioned prefix as unconditional. */
501
+ requiredFields: EffectiveRequiredFields;
502
+ }
503
+ /** The served report (the plan report with the effective required set on every row). */
504
+ interface ServedCreateGuidanceReport extends Omit<CreateGuidanceReport, 'rows'> {
505
+ rows: ServedCreateGuidanceRow[];
506
+ }
435
507
  /** The optional filter bag for `operations.createGuidance`. */
436
508
  interface CreateGuidanceOptions {
437
509
  /** The plan resource keys — narrows the row set. Unknown key → typed RESOURCE_UNKNOWN (zero wire). */
@@ -453,7 +525,7 @@ interface CreateGuidanceOptions {
453
525
  * @param client The wired client (unused — the served data is plan-pinned; the parameter exists so the op rides the invoke holder like every other operation).
454
526
  * @param opts The optional filter bag ({ resources?, kind? }).
455
527
  */
456
- declare function createGuidance(client: AutotaskClient, opts?: CreateGuidanceOptions): Promise<CreateGuidanceReport>;
528
+ declare function createGuidance(client: AutotaskClient, opts?: CreateGuidanceOptions): Promise<ServedCreateGuidanceReport>;
457
529
 
458
530
  /** entity (plan resource key) -> ExecuteCommand `Code` + id parameter name. */
459
531
  declare const ENTITIES: {
@@ -517,6 +589,34 @@ interface UiLinkResult {
517
589
  /** Zero-wire meta op: build the deep link from the client's live REST base (or an explicit `host`). */
518
590
  declare function uiLink(client: AutotaskClient, input: UiLinkInput): Promise<UiLinkResult>;
519
591
 
592
+ /**
593
+ * Every entity name the registry resolves, mapped to its plan resource key.
594
+ * Derived from `apiEntity` (+ the singular entity-name alias) — never
595
+ * hand-written, so a plan resource lands here the moment it is generated.
596
+ */
597
+ declare const ENTITY_TYPE_TO_RESOURCE: Readonly<Record<string, string>>;
598
+ /**
599
+ * Resolve a vendor `referenceEntityType` to the plan resource key a caller
600
+ * would enumerate (the same derivation the field-catalog row serves as
601
+ * `targetResource`).
602
+ *
603
+ * ```ts
604
+ * import { resourceForEntityType } from 'node-autotask/operations';
605
+ * resourceForEntityType('CompanyLocation'); // 'company_locations'
606
+ * resourceForEntityType('Queue'); // null — the plan has no queue entity
607
+ * ```
608
+ *
609
+ * `null` means "the plan carries no resource for this vendor entity name" —
610
+ * it never guesses a near match. A blank/absent name resolves to `null`.
611
+ */
612
+ declare function resourceForEntityType(entityType: string | null | undefined): string | null;
613
+ /**
614
+ * True when `resource` is a plan resource with a read path (`query` or `get`) —
615
+ * the `targetEnumerable` half of the field-catalog row. A null/unknown key is
616
+ * false (a reference the plan cannot enumerate).
617
+ */
618
+ declare function isEnumerableResource(resource: string | null | undefined): boolean;
619
+
520
620
  /** The pinned wire cap: `resources × include` above it is refused
521
621
  * pre-request (CONFIG_ERROR naming the computed cost and the cap) —
522
622
  * refused, never truncated. */
@@ -539,15 +639,38 @@ interface FieldCatalogFieldRow {
539
639
  type: string;
540
640
  isRequired: boolean;
541
641
  isReadOnly: boolean;
542
- isQueryable: boolean;
642
+ /** The vendor `isQueryable` flag — ABSENT on a UDF row: the vendor reports UDFs as queryable, but a filter on a UDF name is accepted only with the `udf: true` marker, so the row states the mechanism in `filterable` instead of a boolean the vendor contradicts (issue #219 N7). */
643
+ isQueryable?: boolean;
543
644
  isPickList: boolean;
645
+ /** Present exactly on a UDF row: the filter mechanism a consumer must send to filter on this name (`udf: true` in the filter condition) — never infer plain filterability from the vendor's `isQueryable` (issue #219 N7). */
646
+ filterable?: 'udf-marker';
647
+ /** The write shape for an object/array field: `merge` (a sent subset is merged — `userDefinedFields` is the proven case) or `replace-all` (the vendor's full-model PUT replaces the collection). Absent on scalar fields (issue #219 N7). */
648
+ writeShape?: 'merge' | 'replace-all';
544
649
  /** The vendor `length` bound (null when the catalog names none). */
545
650
  maxLength: number | null;
546
651
  /** The referenced entity type for reference fields ('' when none). */
547
652
  referenceEntityType: string;
653
+ /** The plan resource key the referenced entity names (`resourceForEntityType`), or `null` when the plan carries no such resource — the key a caller enumerates valid ids with (issue #219 N1). Never a remedy or an enumeration hint. */
654
+ targetResource: string | null;
655
+ /** True exactly when `targetResource` is a plan resource with a `query`/`get` read path (issue #219 N1) — always served, so a reference the vendor names but the plan cannot enumerate reads `false`, never `undefined`. */
656
+ targetEnumerable: boolean;
657
+ /** Present exactly when the plan declares this field DERIVED for the resource (issue #219 N8): the vendor overwrites or inherits the value, so a submitted one is not authoritative. Distinct from `isReadOnly` (never write at all) — a derived field can be absent from that list and still be recomputed. */
658
+ derived?: DerivationRule;
548
659
  /** The vendor's exposed picklist VALUES, verbatim (present exactly when the `labels` opt is `true` and the vendor exposed values for this picklist field — the vendor-walled and non-picklist rows carry none). */
549
660
  picklistValues?: PickListValue[];
550
661
  }
662
+ /** The derivation rule of one field (issue #219 N8) — a closed plan token, served without the field name it decorates. */
663
+ interface DerivationRule {
664
+ /** elapsed(<start>,<end>) (recomputed from those timestamps) | parent (inherited from the parent record) | mirror(<field>) (the vendor copies that field) | external (written by another entity's op — writableRoute names it). */
665
+ rule: string;
666
+ /** The op that actually writes the value (the external rule names it — billing_item_approval_levels.create for a time entry's approval level). */
667
+ writableRoute?: string;
668
+ }
669
+ /** One declared derived field of a resource (issue #219 N8) — the declaration the plan pins. */
670
+ interface FieldDerivation extends DerivationRule {
671
+ /** The vendor field name. */
672
+ field: string;
673
+ }
551
674
  /** One per-resource fault (partial failures are typed PER ROW — never all-or-nothing). */
552
675
  interface FieldCatalogRowError {
553
676
  code: string;
@@ -561,8 +684,14 @@ interface FieldCatalogRow {
561
684
  apiEntity: string;
562
685
  /** True when the plan carries a `getUdfInfo` row for the resource (the vendor defines a UDF catalog endpoint for every entity resource — the catalog may answer an empty list). */
563
686
  udfCapable: boolean;
687
+ /** The filter mechanism for a UDF name — present exactly when `udfCapable`: a filter on a UDF name is accepted only with the vendor's `udf: true` marker (a plain filter is refused), so the row states the marker rather than leaving a consumer to read the UDF rows' `isQueryable` (issue #219 N7). */
688
+ udfFilter?: 'udf-marker';
689
+ /** The write shape of a record's `userDefinedFields` collection — present exactly when `udfCapable`: the vendor MERGES a sent list, so a subset is correct (issue #219 N7). */
690
+ udfWriteShape?: 'merge';
564
691
  /** The entity information model (present exactly when `info` was included and fetched). */
565
692
  info?: Record<string, unknown> | null;
693
+ /** The plan's derived-field declaration for this resource (issue #219 N8) — present exactly when the plan declares any, in plan order; the same list the create guidance row and the describe channel serve. Read it before treating a submitted field value as authoritative. */
694
+ derivedFields?: FieldDerivation[];
566
695
  /** The projected standard-field catalog (present exactly when `fields` was included and fetched; when the `fields` opt is given, only the matching rows — the requested names absent here land in `unmatchedFields`). */
567
696
  fields?: FieldCatalogFieldRow[];
568
697
  /** The requested `fields`-filter names absent from this resource's fields catalog (in request order); `[]` when no filter is given, when the row carries no fields catalog (an `info`/`udf`-only include or a row error), or when nothing was missing. Reported, never an error. */
@@ -938,4 +1067,4 @@ declare function invokeWrite(client: AutotaskClient, operation: string, args?: r
938
1067
  */
939
1068
  declare function invokeDelete(client: AutotaskClient, operation: string, args?: readonly unknown[] | Record<string, unknown>, opts?: InvokeOptions): Promise<unknown>;
940
1069
 
941
- export { AGGREGATE_DATE_BUCKETS, AGGREGATE_DEFAULT_LIMIT, AGGREGATE_DEFAULT_TOP, AGGREGATE_TOP_MAX, type AggregateGroup, type AggregateOptions, type AggregateResult, BLIND_SURFACE_KINDS, type BlindSurfaceKind, type BlindSurfaceOptions, BlindSurfaceRow, CREATE_BLOCKER_KINDS, type CreateGuidanceOptions, type DateBucket, EXPAND_RESOURCE_NAMES_MAX_IDS, type ExpandResourceNameRow, type ExpandResourceNamesOptions, type ExpandResourceNamesResult, FETCH_BY_IDS_CHUNK_SIZE, FETCH_BY_IDS_MAX_ITEMS, FETCH_MANY_MAX_ITEMS, FIELD_CATALOG_HONESTY_NOTE, type FetchByIdsOptions, type FetchManyItem, type FetchManyItemError, type FetchManyItemResult, type FetchManyOptions, type FetchManyResult, FieldCacheKind, type FieldCatalogFieldRow, type FieldCatalogOptions, type FieldCatalogResult, type FieldCatalogRow, type FieldCatalogRowError, INVOKE_OPTION_KEYS, type InvokeMode, type InvokeOptions, MAX_FIELD_CATALOG_WIRE, PARAMS_BAG_KEYS, type ProbeReachabilityOptions, type ProbeReachabilityResult, type ProbeSurfaceRow, RECOVERY_CONFIRM, RECOVERY_DEFAULT_LIMIT, RECOVERY_MAX_LIMIT, type RecoveryDeleteBoundary, type RecoveryInput, type RecoveryMatch, type RecoveryOptions, type RecoveryResult, type ResolveAnyOptions, type ResolveAnyResourceOutcome, type ResolveAnyResult, type SearchAcrossResourcesOptions, type SearchAcrossResourcesResult, type SearchAcrossResourcesRow, UI_LINK_ENTITIES, type UiLinkEntity, type UiLinkInput, type UiLinkResult, WORKFLOW_RESOURCES, aggregate, blindSurfaces, buildUiLink, createGuidance, dateBucketLabel, expandResourceNames, fetchByIds, fetchMany, fieldCatalog, foldFlattenedOpts, invoke, invokeDelete, invokeRead, invokeWrite, needsConfirmation, probeReachability, recovery, relationshipMap, resolveAny, searchAcrossResources, uiLink, unknownKeysRefusal, validateDispatchArgs, validateFetchManyItems, validateInvokeOptions, validateParamsBag };
1070
+ export { AGGREGATE_DATE_BUCKETS, AGGREGATE_DEFAULT_LIMIT, AGGREGATE_DEFAULT_TOP, AGGREGATE_TOP_MAX, type AggregateGroup, type AggregateOptions, type AggregateResult, BLIND_SURFACE_KINDS, type BlindSurfaceKind, type BlindSurfaceOptions, BlindSurfaceRow, CREATE_BLOCKER_KINDS, type CreateGuidanceOptions, type DateBucket, type DerivationRule, ENTITY_TYPE_TO_RESOURCE, EXPAND_RESOURCE_NAMES_MAX_IDS, type EffectiveRequiredFields, type ExpandResourceNameRow, type ExpandResourceNamesOptions, type ExpandResourceNamesResult, FETCH_BY_IDS_CHUNK_SIZE, FETCH_BY_IDS_MAX_ITEMS, FETCH_MANY_MAX_ITEMS, FIELD_CATALOG_HONESTY_NOTE, type FetchByIdsOptions, type FetchManyItem, type FetchManyItemError, type FetchManyItemResult, type FetchManyOptions, type FetchManyResult, FieldCacheKind, type FieldCatalogFieldRow, type FieldCatalogOptions, type FieldCatalogResult, type FieldCatalogRow, type FieldCatalogRowError, type FieldDerivation, INVOKE_OPTION_KEYS, type InvokeMode, type InvokeOptions, MAX_FIELD_CATALOG_WIRE, PARAMS_BAG_KEYS, type ProbeReachabilityOptions, type ProbeReachabilityResult, type ProbeSurfaceRow, RECOVERY_CONFIRM, RECOVERY_DEFAULT_LIMIT, RECOVERY_MAX_LIMIT, type RecoveryDeleteBoundary, type RecoveryInput, type RecoveryMatch, type RecoveryOptions, type RecoveryResult, type RequiredFieldsRecord, type RequiredFieldsSource, type RequiredFieldsZoneFacts, type ResolveAnyOptions, type ResolveAnyResourceOutcome, type ResolveAnyResult, type SearchAcrossResourcesOptions, type SearchAcrossResourcesResult, type SearchAcrossResourcesRow, type ServedCreateGuidanceReport, type ServedCreateGuidanceRow, UI_LINK_ENTITIES, type UiLinkEntity, type UiLinkInput, type UiLinkResult, WORKFLOW_RESOURCES, aggregate, blindSurfaces, buildUiLink, createGuidance, dateBucketLabel, effectiveRequiredFields, expandResourceNames, fetchByIds, fetchMany, fieldCatalog, foldFlattenedOpts, invoke, invokeDelete, invokeRead, invokeWrite, isEnumerableResource, needsConfirmation, probeReachability, recovery, relationshipMap, resolveAny, resourceForEntityType, searchAcrossResources, uiLink, unknownKeysRefusal, validateDispatchArgs, validateFetchManyItems, validateInvokeOptions, validateParamsBag };
@@ -1,7 +1,7 @@
1
- import { a as AutotaskClient, ea as BlindSurfaceInfo, eb as RelationshipResource, ec as BlindSurfaceInventory, ed as BlindSurfaceRow, ee as CreateBlockerKind, ef as CreateGuidanceReport, Z as ZoneName, eg as FieldCacheKind, i as AutotaskConfigError } from '../index-CZ94y401.js';
2
- export { eh as FIELD_CACHE_KINDS } from '../index-CZ94y401.js';
3
- import { I as Identifier, cG as EmptyReasonInfo, dI as PickListValue, a as FilterCondition } from '../index-BVtycq-6.js';
4
- export { hp as PICKLIST_VALUE_NOT_SERVED_NOTE } from '../index-BVtycq-6.js';
1
+ import { a as AutotaskClient, es as BlindSurfaceInfo, et as RelationshipResource, eu as BlindSurfaceInventory, ev as BlindSurfaceRow, ew as CreateGuidanceRow, ex as CreateBlockerKind, ey as CreateGuidanceReport, Z as ZoneName, ez as FieldCacheKind, j as AutotaskConfigError } from '../index-BIWy9m-a.js';
2
+ export { eA as FIELD_CACHE_KINDS } from '../index-BIWy9m-a.js';
3
+ import { I as Identifier, cO as EmptyReasonInfo, e4 as PickListValue, a as FilterCondition } from '../index-DQ9NgraW.js';
4
+ export { hV as PICKLIST_VALUE_NOT_SERVED_NOTE } from '../index-DQ9NgraW.js';
5
5
  import { CapabilityRecord } from '../capabilities.js';
6
6
 
7
7
  /**
@@ -423,6 +423,69 @@ interface ProbeReachabilityResult {
423
423
  */
424
424
  declare function probeReachability(client: AutotaskClient, opts?: ProbeReachabilityOptions): Promise<ProbeReachabilityResult>;
425
425
 
426
+ /**
427
+ * `effectiveRequiredFields` — the ONE precedence rule for "what does a create
428
+ * really require" (issue #219 N4).
429
+ *
430
+ * Three sources answer that question, at three different coverages, and the
431
+ * SDK used to leave the choice to each caller:
432
+ * 1. `createGuidance.liveProvenPrefix` — the fields a live create actually
433
+ * demanded, in vendor-demand order (92 rows; the widest evidence);
434
+ * 2. `zoneFacts.createRequiredSet` — the hand-authored zone set (6
435
+ * resources);
436
+ * 3. the vendor field catalog's `isRequired` — the spec opinion (wrong for
437
+ * 68 of the 75 resources that carry a proven prefix).
438
+ *
439
+ * The order is FIXED and stated: live-proven > zone > spec, with the source
440
+ * named on the result (`from`). Both plan shapes stay where they are; this
441
+ * helper is the only place in the SDK that compares them.
442
+ *
443
+ * Value-conditioned prefixes: a prefix proven for one picklist value (e.g.
444
+ * `contracts.create`'s type-1 `estimatedRevenue`/`estimatedHours`/
445
+ * `estimatedCost`) is still returned whole with `from: 'live-proven'` — the
446
+ * condition itself lives on the create-guidance row (`blocker.message` +
447
+ * `vendorEvidence`), which a caller must read before treating the list as
448
+ * unconditional. Never flatten a conditioned row into "all these fields are
449
+ * always required"; the row's evidence is the qualifier.
450
+ */
451
+
452
+ /** Which source the returned field set came from (the precedence order). */
453
+ type RequiredFieldsSource = 'live-proven' | 'zone' | 'spec';
454
+ /** The effective required set + the source it came from. */
455
+ interface EffectiveRequiredFields {
456
+ /** The required field names, in the source's own order (vendor-demand order for a live-proven prefix). */
457
+ fields: string[];
458
+ /** `live-proven` (createGuidance.liveProvenPrefix) > `zone` (createRequiredSet) > `spec` (vendor isRequired). */
459
+ from: RequiredFieldsSource;
460
+ }
461
+ /** The plan zone-fact shape this helper reads (both shapes stay plan-owned). */
462
+ interface RequiredFieldsZoneFacts {
463
+ createRequiredSet?: string[];
464
+ createGuidance?: Pick<CreateGuidanceRow, 'liveProvenPrefix' | 'unproven'> | null;
465
+ }
466
+ /** The spec-side record this helper reads (the vendor field catalog's projection). */
467
+ interface RequiredFieldsRecord {
468
+ /** The vendor `isRequired` field names (the narrowest source). */
469
+ requiredFields?: readonly string[] | null;
470
+ }
471
+ /**
472
+ * Resolve the effective create-required set for one resource.
473
+ *
474
+ * ```ts
475
+ * import { effectiveRequiredFields } from 'node-autotask/operations';
476
+ * const eff = effectiveRequiredFields(
477
+ * { requiredFields: vendorRequiredNames }, // from operations.fieldCatalog
478
+ * RELATIONSHIP_MAP.contacts.zoneFacts, // the plan zone facts
479
+ * );
480
+ * // contacts: { fields: ['firstName', 'lastName', 'companyID', 'isActive'], from: 'live-proven' }
481
+ * ```
482
+ *
483
+ * An empty or absent higher source falls through to the next one; with no
484
+ * source at all the result is `{ fields: [], from: 'spec' }` — the name of the
485
+ * source is always stated, never a bare list.
486
+ */
487
+ declare function effectiveRequiredFields(record?: RequiredFieldsRecord | null, zoneFacts?: RequiredFieldsZoneFacts | null): EffectiveRequiredFields;
488
+
426
489
  /** The closed blocker-kind set (the gate re-derives it; unknown kind → CONFIG_ERROR). */
427
490
  /**
428
491
  * The closed blocker-kind set served by `operations.createGuidance`.
@@ -432,6 +495,15 @@ declare function probeReachability(client: AutotaskClient, opts?: ProbeReachabil
432
495
  * rather than forcing those rows into a misfitting class.
433
496
  */
434
497
  declare const CREATE_BLOCKER_KINDS: readonly CreateBlockerKind[];
498
+ /** One served create-guidance row: the plan row plus the effective required set (issue #219 N4). */
499
+ interface ServedCreateGuidanceRow extends CreateGuidanceRow {
500
+ /** The effective create-required set + the source it came from (`live-proven` > `zone` > `spec`). Read `blocker`/`vendorEvidence` before treating a value-conditioned prefix as unconditional. */
501
+ requiredFields: EffectiveRequiredFields;
502
+ }
503
+ /** The served report (the plan report with the effective required set on every row). */
504
+ interface ServedCreateGuidanceReport extends Omit<CreateGuidanceReport, 'rows'> {
505
+ rows: ServedCreateGuidanceRow[];
506
+ }
435
507
  /** The optional filter bag for `operations.createGuidance`. */
436
508
  interface CreateGuidanceOptions {
437
509
  /** The plan resource keys — narrows the row set. Unknown key → typed RESOURCE_UNKNOWN (zero wire). */
@@ -453,7 +525,7 @@ interface CreateGuidanceOptions {
453
525
  * @param client The wired client (unused — the served data is plan-pinned; the parameter exists so the op rides the invoke holder like every other operation).
454
526
  * @param opts The optional filter bag ({ resources?, kind? }).
455
527
  */
456
- declare function createGuidance(client: AutotaskClient, opts?: CreateGuidanceOptions): Promise<CreateGuidanceReport>;
528
+ declare function createGuidance(client: AutotaskClient, opts?: CreateGuidanceOptions): Promise<ServedCreateGuidanceReport>;
457
529
 
458
530
  /** entity (plan resource key) -> ExecuteCommand `Code` + id parameter name. */
459
531
  declare const ENTITIES: {
@@ -517,6 +589,34 @@ interface UiLinkResult {
517
589
  /** Zero-wire meta op: build the deep link from the client's live REST base (or an explicit `host`). */
518
590
  declare function uiLink(client: AutotaskClient, input: UiLinkInput): Promise<UiLinkResult>;
519
591
 
592
+ /**
593
+ * Every entity name the registry resolves, mapped to its plan resource key.
594
+ * Derived from `apiEntity` (+ the singular entity-name alias) — never
595
+ * hand-written, so a plan resource lands here the moment it is generated.
596
+ */
597
+ declare const ENTITY_TYPE_TO_RESOURCE: Readonly<Record<string, string>>;
598
+ /**
599
+ * Resolve a vendor `referenceEntityType` to the plan resource key a caller
600
+ * would enumerate (the same derivation the field-catalog row serves as
601
+ * `targetResource`).
602
+ *
603
+ * ```ts
604
+ * import { resourceForEntityType } from 'node-autotask/operations';
605
+ * resourceForEntityType('CompanyLocation'); // 'company_locations'
606
+ * resourceForEntityType('Queue'); // null — the plan has no queue entity
607
+ * ```
608
+ *
609
+ * `null` means "the plan carries no resource for this vendor entity name" —
610
+ * it never guesses a near match. A blank/absent name resolves to `null`.
611
+ */
612
+ declare function resourceForEntityType(entityType: string | null | undefined): string | null;
613
+ /**
614
+ * True when `resource` is a plan resource with a read path (`query` or `get`) —
615
+ * the `targetEnumerable` half of the field-catalog row. A null/unknown key is
616
+ * false (a reference the plan cannot enumerate).
617
+ */
618
+ declare function isEnumerableResource(resource: string | null | undefined): boolean;
619
+
520
620
  /** The pinned wire cap: `resources × include` above it is refused
521
621
  * pre-request (CONFIG_ERROR naming the computed cost and the cap) —
522
622
  * refused, never truncated. */
@@ -539,15 +639,38 @@ interface FieldCatalogFieldRow {
539
639
  type: string;
540
640
  isRequired: boolean;
541
641
  isReadOnly: boolean;
542
- isQueryable: boolean;
642
+ /** The vendor `isQueryable` flag — ABSENT on a UDF row: the vendor reports UDFs as queryable, but a filter on a UDF name is accepted only with the `udf: true` marker, so the row states the mechanism in `filterable` instead of a boolean the vendor contradicts (issue #219 N7). */
643
+ isQueryable?: boolean;
543
644
  isPickList: boolean;
645
+ /** Present exactly on a UDF row: the filter mechanism a consumer must send to filter on this name (`udf: true` in the filter condition) — never infer plain filterability from the vendor's `isQueryable` (issue #219 N7). */
646
+ filterable?: 'udf-marker';
647
+ /** The write shape for an object/array field: `merge` (a sent subset is merged — `userDefinedFields` is the proven case) or `replace-all` (the vendor's full-model PUT replaces the collection). Absent on scalar fields (issue #219 N7). */
648
+ writeShape?: 'merge' | 'replace-all';
544
649
  /** The vendor `length` bound (null when the catalog names none). */
545
650
  maxLength: number | null;
546
651
  /** The referenced entity type for reference fields ('' when none). */
547
652
  referenceEntityType: string;
653
+ /** The plan resource key the referenced entity names (`resourceForEntityType`), or `null` when the plan carries no such resource — the key a caller enumerates valid ids with (issue #219 N1). Never a remedy or an enumeration hint. */
654
+ targetResource: string | null;
655
+ /** True exactly when `targetResource` is a plan resource with a `query`/`get` read path (issue #219 N1) — always served, so a reference the vendor names but the plan cannot enumerate reads `false`, never `undefined`. */
656
+ targetEnumerable: boolean;
657
+ /** Present exactly when the plan declares this field DERIVED for the resource (issue #219 N8): the vendor overwrites or inherits the value, so a submitted one is not authoritative. Distinct from `isReadOnly` (never write at all) — a derived field can be absent from that list and still be recomputed. */
658
+ derived?: DerivationRule;
548
659
  /** The vendor's exposed picklist VALUES, verbatim (present exactly when the `labels` opt is `true` and the vendor exposed values for this picklist field — the vendor-walled and non-picklist rows carry none). */
549
660
  picklistValues?: PickListValue[];
550
661
  }
662
+ /** The derivation rule of one field (issue #219 N8) — a closed plan token, served without the field name it decorates. */
663
+ interface DerivationRule {
664
+ /** elapsed(<start>,<end>) (recomputed from those timestamps) | parent (inherited from the parent record) | mirror(<field>) (the vendor copies that field) | external (written by another entity's op — writableRoute names it). */
665
+ rule: string;
666
+ /** The op that actually writes the value (the external rule names it — billing_item_approval_levels.create for a time entry's approval level). */
667
+ writableRoute?: string;
668
+ }
669
+ /** One declared derived field of a resource (issue #219 N8) — the declaration the plan pins. */
670
+ interface FieldDerivation extends DerivationRule {
671
+ /** The vendor field name. */
672
+ field: string;
673
+ }
551
674
  /** One per-resource fault (partial failures are typed PER ROW — never all-or-nothing). */
552
675
  interface FieldCatalogRowError {
553
676
  code: string;
@@ -561,8 +684,14 @@ interface FieldCatalogRow {
561
684
  apiEntity: string;
562
685
  /** True when the plan carries a `getUdfInfo` row for the resource (the vendor defines a UDF catalog endpoint for every entity resource — the catalog may answer an empty list). */
563
686
  udfCapable: boolean;
687
+ /** The filter mechanism for a UDF name — present exactly when `udfCapable`: a filter on a UDF name is accepted only with the vendor's `udf: true` marker (a plain filter is refused), so the row states the marker rather than leaving a consumer to read the UDF rows' `isQueryable` (issue #219 N7). */
688
+ udfFilter?: 'udf-marker';
689
+ /** The write shape of a record's `userDefinedFields` collection — present exactly when `udfCapable`: the vendor MERGES a sent list, so a subset is correct (issue #219 N7). */
690
+ udfWriteShape?: 'merge';
564
691
  /** The entity information model (present exactly when `info` was included and fetched). */
565
692
  info?: Record<string, unknown> | null;
693
+ /** The plan's derived-field declaration for this resource (issue #219 N8) — present exactly when the plan declares any, in plan order; the same list the create guidance row and the describe channel serve. Read it before treating a submitted field value as authoritative. */
694
+ derivedFields?: FieldDerivation[];
566
695
  /** The projected standard-field catalog (present exactly when `fields` was included and fetched; when the `fields` opt is given, only the matching rows — the requested names absent here land in `unmatchedFields`). */
567
696
  fields?: FieldCatalogFieldRow[];
568
697
  /** The requested `fields`-filter names absent from this resource's fields catalog (in request order); `[]` when no filter is given, when the row carries no fields catalog (an `info`/`udf`-only include or a row error), or when nothing was missing. Reported, never an error. */
@@ -938,4 +1067,4 @@ declare function invokeWrite(client: AutotaskClient, operation: string, args?: r
938
1067
  */
939
1068
  declare function invokeDelete(client: AutotaskClient, operation: string, args?: readonly unknown[] | Record<string, unknown>, opts?: InvokeOptions): Promise<unknown>;
940
1069
 
941
- export { AGGREGATE_DATE_BUCKETS, AGGREGATE_DEFAULT_LIMIT, AGGREGATE_DEFAULT_TOP, AGGREGATE_TOP_MAX, type AggregateGroup, type AggregateOptions, type AggregateResult, BLIND_SURFACE_KINDS, type BlindSurfaceKind, type BlindSurfaceOptions, BlindSurfaceRow, CREATE_BLOCKER_KINDS, type CreateGuidanceOptions, type DateBucket, EXPAND_RESOURCE_NAMES_MAX_IDS, type ExpandResourceNameRow, type ExpandResourceNamesOptions, type ExpandResourceNamesResult, FETCH_BY_IDS_CHUNK_SIZE, FETCH_BY_IDS_MAX_ITEMS, FETCH_MANY_MAX_ITEMS, FIELD_CATALOG_HONESTY_NOTE, type FetchByIdsOptions, type FetchManyItem, type FetchManyItemError, type FetchManyItemResult, type FetchManyOptions, type FetchManyResult, FieldCacheKind, type FieldCatalogFieldRow, type FieldCatalogOptions, type FieldCatalogResult, type FieldCatalogRow, type FieldCatalogRowError, INVOKE_OPTION_KEYS, type InvokeMode, type InvokeOptions, MAX_FIELD_CATALOG_WIRE, PARAMS_BAG_KEYS, type ProbeReachabilityOptions, type ProbeReachabilityResult, type ProbeSurfaceRow, RECOVERY_CONFIRM, RECOVERY_DEFAULT_LIMIT, RECOVERY_MAX_LIMIT, type RecoveryDeleteBoundary, type RecoveryInput, type RecoveryMatch, type RecoveryOptions, type RecoveryResult, type ResolveAnyOptions, type ResolveAnyResourceOutcome, type ResolveAnyResult, type SearchAcrossResourcesOptions, type SearchAcrossResourcesResult, type SearchAcrossResourcesRow, UI_LINK_ENTITIES, type UiLinkEntity, type UiLinkInput, type UiLinkResult, WORKFLOW_RESOURCES, aggregate, blindSurfaces, buildUiLink, createGuidance, dateBucketLabel, expandResourceNames, fetchByIds, fetchMany, fieldCatalog, foldFlattenedOpts, invoke, invokeDelete, invokeRead, invokeWrite, needsConfirmation, probeReachability, recovery, relationshipMap, resolveAny, searchAcrossResources, uiLink, unknownKeysRefusal, validateDispatchArgs, validateFetchManyItems, validateInvokeOptions, validateParamsBag };
1070
+ export { AGGREGATE_DATE_BUCKETS, AGGREGATE_DEFAULT_LIMIT, AGGREGATE_DEFAULT_TOP, AGGREGATE_TOP_MAX, type AggregateGroup, type AggregateOptions, type AggregateResult, BLIND_SURFACE_KINDS, type BlindSurfaceKind, type BlindSurfaceOptions, BlindSurfaceRow, CREATE_BLOCKER_KINDS, type CreateGuidanceOptions, type DateBucket, type DerivationRule, ENTITY_TYPE_TO_RESOURCE, EXPAND_RESOURCE_NAMES_MAX_IDS, type EffectiveRequiredFields, type ExpandResourceNameRow, type ExpandResourceNamesOptions, type ExpandResourceNamesResult, FETCH_BY_IDS_CHUNK_SIZE, FETCH_BY_IDS_MAX_ITEMS, FETCH_MANY_MAX_ITEMS, FIELD_CATALOG_HONESTY_NOTE, type FetchByIdsOptions, type FetchManyItem, type FetchManyItemError, type FetchManyItemResult, type FetchManyOptions, type FetchManyResult, FieldCacheKind, type FieldCatalogFieldRow, type FieldCatalogOptions, type FieldCatalogResult, type FieldCatalogRow, type FieldCatalogRowError, type FieldDerivation, INVOKE_OPTION_KEYS, type InvokeMode, type InvokeOptions, MAX_FIELD_CATALOG_WIRE, PARAMS_BAG_KEYS, type ProbeReachabilityOptions, type ProbeReachabilityResult, type ProbeSurfaceRow, RECOVERY_CONFIRM, RECOVERY_DEFAULT_LIMIT, RECOVERY_MAX_LIMIT, type RecoveryDeleteBoundary, type RecoveryInput, type RecoveryMatch, type RecoveryOptions, type RecoveryResult, type RequiredFieldsRecord, type RequiredFieldsSource, type RequiredFieldsZoneFacts, type ResolveAnyOptions, type ResolveAnyResourceOutcome, type ResolveAnyResult, type SearchAcrossResourcesOptions, type SearchAcrossResourcesResult, type SearchAcrossResourcesRow, type ServedCreateGuidanceReport, type ServedCreateGuidanceRow, UI_LINK_ENTITIES, type UiLinkEntity, type UiLinkInput, type UiLinkResult, WORKFLOW_RESOURCES, aggregate, blindSurfaces, buildUiLink, createGuidance, dateBucketLabel, effectiveRequiredFields, expandResourceNames, fetchByIds, fetchMany, fieldCatalog, foldFlattenedOpts, invoke, invokeDelete, invokeRead, invokeWrite, isEnumerableResource, needsConfirmation, probeReachability, recovery, relationshipMap, resolveAny, resourceForEntityType, searchAcrossResources, uiLink, unknownKeysRefusal, validateDispatchArgs, validateFetchManyItems, validateInvokeOptions, validateParamsBag };
@@ -7,6 +7,7 @@ import {
7
7
  ConfirmationRequiredError,
8
8
  DELETE_BOUNDARY_NOTES,
9
9
  DeleteBoundaryError,
10
+ ENTITY_TYPE_TO_RESOURCE,
10
11
  EXPAND_RESOURCE_NAMES_MAX_IDS,
11
12
  FETCH_BY_IDS_CHUNK_SIZE,
12
13
  FETCH_BY_IDS_MAX_ITEMS,
@@ -35,15 +36,17 @@ import {
35
36
  fetchMany,
36
37
  fieldCatalog,
37
38
  isAutotaskError,
39
+ isEnumerableResource,
38
40
  isRecord,
39
41
  parseIdentifier,
42
+ resourceForEntityType,
40
43
  uiLink,
41
44
  validateFetchManyItems,
42
45
  validateQueryFieldNames
43
- } from "../chunk-VUGZKP33.js";
46
+ } from "../chunk-42ZUISDH.js";
44
47
  import {
45
48
  CAPABILITIES
46
- } from "../chunk-EFR2XWRX.js";
49
+ } from "../chunk-F7FVOXPQ.js";
47
50
 
48
51
  // src/operations/searchAcrossResources.ts
49
52
  var DEFAULT_LIMIT = 25;
@@ -609,6 +612,20 @@ async function probeReachability(client, opts) {
609
612
  return { results, wireUsed, cap, truncated: false };
610
613
  }
611
614
 
615
+ // src/operations/requiredFields.ts
616
+ function effectiveRequiredFields(record, zoneFacts) {
617
+ const prefix = zoneFacts?.createGuidance?.liveProvenPrefix;
618
+ if (Array.isArray(prefix) && prefix.length > 0) {
619
+ return { fields: [...prefix], from: "live-proven" };
620
+ }
621
+ const zoneSet = zoneFacts?.createRequiredSet;
622
+ if (Array.isArray(zoneSet) && zoneSet.length > 0) {
623
+ return { fields: [...zoneSet], from: "zone" };
624
+ }
625
+ const spec = record?.requiredFields;
626
+ return { fields: Array.isArray(spec) ? [...spec] : [], from: "spec" };
627
+ }
628
+
612
629
  // src/operations/createGuidance.ts
613
630
  var CREATE_BLOCKER_KINDS = [
614
631
  "ok",
@@ -628,7 +645,13 @@ async function createGuidance(client, opts) {
628
645
  "createGuidance: opts must be an object { resources?: string[], kind?: CreateBlockerKind }"
629
646
  );
630
647
  }
631
- let rows = CREATE_GUIDANCE.rows;
648
+ let servedRows = CREATE_GUIDANCE.rows.map((row) => ({
649
+ ...row,
650
+ // Issue #219 N4: one precedence rule, stated on every row (live-proven >
651
+ // zone > spec). The spec set is not available here (it is a LIVE read) —
652
+ // the helper is handed the plan's two shapes and names the source.
653
+ requiredFields: effectiveRequiredFields(void 0, RELATIONSHIP_MAP[row.resource]?.zoneFacts ?? null)
654
+ }));
632
655
  if (opts?.resources !== void 0) {
633
656
  if (!Array.isArray(opts.resources) || opts.resources.length === 0) {
634
657
  throw new AutotaskConfigError("createGuidance: opts.resources must be a non-empty string[] of plan resource keys");
@@ -651,7 +674,7 @@ async function createGuidance(client, opts) {
651
674
  }
652
675
  wanted.add(key);
653
676
  }
654
- rows = rows.filter((row) => wanted.has(row.resource));
677
+ servedRows = servedRows.filter((row) => wanted.has(row.resource));
655
678
  }
656
679
  if (opts?.kind !== void 0) {
657
680
  if (!CREATE_BLOCKER_KINDS.includes(opts.kind)) {
@@ -659,13 +682,13 @@ async function createGuidance(client, opts) {
659
682
  `createGuidance: unknown kind "${String(opts.kind)}" \u2014 the valid kinds are: ${CREATE_BLOCKER_KINDS.join(", ")}`
660
683
  );
661
684
  }
662
- rows = rows.filter((row) => row.blocker?.kind === opts.kind);
685
+ servedRows = servedRows.filter((row) => row.blocker?.kind === opts.kind);
663
686
  }
664
687
  return {
665
688
  zone: CREATE_GUIDANCE.zone,
666
689
  label: CREATE_GUIDANCE.label,
667
690
  verifiedAt: CREATE_GUIDANCE.verifiedAt,
668
- rows,
691
+ rows: servedRows,
669
692
  counts: CREATE_GUIDANCE.counts
670
693
  };
671
694
  }
@@ -1384,6 +1407,7 @@ export {
1384
1407
  AGGREGATE_TOP_MAX,
1385
1408
  BLIND_SURFACE_KINDS,
1386
1409
  CREATE_BLOCKER_KINDS,
1410
+ ENTITY_TYPE_TO_RESOURCE,
1387
1411
  EXPAND_RESOURCE_NAMES_MAX_IDS,
1388
1412
  FETCH_BY_IDS_CHUNK_SIZE,
1389
1413
  FETCH_BY_IDS_MAX_ITEMS,
@@ -1404,6 +1428,7 @@ export {
1404
1428
  buildUiLink,
1405
1429
  createGuidance,
1406
1430
  dateBucketLabel,
1431
+ effectiveRequiredFields,
1407
1432
  expandResourceNames,
1408
1433
  fetchByIds,
1409
1434
  fetchMany,
@@ -1413,11 +1438,13 @@ export {
1413
1438
  invokeDelete,
1414
1439
  invokeRead,
1415
1440
  invokeWrite,
1441
+ isEnumerableResource,
1416
1442
  needsConfirmation,
1417
1443
  probeReachability,
1418
1444
  recovery,
1419
1445
  relationshipMap,
1420
1446
  resolveAny,
1447
+ resourceForEntityType,
1421
1448
  searchAcrossResources,
1422
1449
  uiLink,
1423
1450
  unknownKeysRefusal,
package/dist/pool.cjs CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkFKJ77K6Zcjs = require('./chunk-FKJ77K6Z.cjs');
4
- require('./chunk-Z5L7Q33V.cjs');
3
+ var _chunkUHTZLUDEcjs = require('./chunk-UHTZLUDE.cjs');
4
+ require('./chunk-5GGCSRT4.cjs');
5
5
 
6
6
 
7
7
 
8
- var _chunk2H7YI54Bcjs = require('./chunk-2H7YI54B.cjs');
9
- require('./chunk-WBMRACCV.cjs');
8
+
9
+ var _chunkZJ4ONAQFcjs = require('./chunk-ZJ4ONAQF.cjs');
10
+ require('./chunk-5CC7LGNM.cjs');
10
11
 
11
12
  // src/pool.ts
12
13
  var _crypto = require('crypto');
@@ -31,20 +32,44 @@ function cacheSignature(config) {
31
32
  function createClientPool(options = {}) {
32
33
  const maxSize = _nullishCoalesce(options.maxSize, () => ( 128));
33
34
  if (!Number.isInteger(maxSize) || maxSize < 1) {
34
- throw new (0, _chunk2H7YI54Bcjs.AutotaskConfigError)(
35
+ throw new (0, _chunkZJ4ONAQFcjs.AutotaskConfigError)(
35
36
  `ClientPool maxSize must be a positive integer (got ${String(options.maxSize)})`
36
37
  );
37
38
  }
38
39
  const idleTtlMs = options.idleTtlMs;
39
40
  if (idleTtlMs !== void 0 && (!Number.isInteger(idleTtlMs) || idleTtlMs < 1)) {
40
- throw new (0, _chunk2H7YI54Bcjs.AutotaskConfigError)(
41
+ throw new (0, _chunkZJ4ONAQFcjs.AutotaskConfigError)(
41
42
  `ClientPool idleTtlMs must be a positive integer (got ${String(idleTtlMs)})`
42
43
  );
43
44
  }
44
- const factory = _nullishCoalesce(options.factory, () => ( ((config) => new (0, _chunkFKJ77K6Zcjs.AutotaskClient)(config))));
45
+ const factory = _nullishCoalesce(options.factory, () => ( ((config) => new (0, _chunkUHTZLUDEcjs.AutotaskClient)(config))));
46
+ const sharedReadCache = options.sharedReadCache !== false;
45
47
  const entries = /* @__PURE__ */ new Map();
48
+ const readCaches = /* @__PURE__ */ new Map();
49
+ function sharedCacheFor(key, config) {
50
+ if (!sharedReadCache) return void 0;
51
+ const existing = readCaches.get(key);
52
+ if (existing !== void 0) {
53
+ readCaches.delete(key);
54
+ readCaches.set(key, existing);
55
+ return existing;
56
+ }
57
+ const created = _chunkZJ4ONAQFcjs.buildReadCache.call(void 0, config);
58
+ if (created === void 0) return void 0;
59
+ readCaches.set(key, created);
60
+ while (readCaches.size > maxSize) {
61
+ const oldest = readCaches.keys().next().value;
62
+ if (oldest === void 0) break;
63
+ readCaches.delete(oldest);
64
+ }
65
+ return created;
66
+ }
67
+ function withSharedCache(config, store) {
68
+ if (store === void 0 || config.cache === false) return config;
69
+ return { ...config, cache: { ..._nullishCoalesce(config.cache, () => ( {})), store } };
70
+ }
46
71
  function keyFor(config) {
47
- const resolved = _chunk2H7YI54Bcjs.resolveCredentials.call(void 0, config);
72
+ const resolved = _chunkZJ4ONAQFcjs.resolveCredentials.call(void 0, config);
48
73
  const tuple = [
49
74
  resolved.userName,
50
75
  resolved.apiIntegrationCode,
@@ -80,7 +105,14 @@ function createClientPool(options = {}) {
80
105
  const oldest = entries.keys().next().value;
81
106
  if (oldest !== void 0) entries.delete(oldest);
82
107
  }
83
- const created = { client: factory(config), usedAt: now, cacheSig: cacheSignature(config), warned: false };
108
+ const store = sharedCacheFor(key, config);
109
+ const created = {
110
+ client: factory(withSharedCache(config, store)),
111
+ usedAt: now,
112
+ cacheSig: cacheSignature(config),
113
+ // the CALLER's settings — the injected store is pool plumbing
114
+ warned: false
115
+ };
84
116
  entries.set(key, created);
85
117
  return created.client;
86
118
  },
@@ -89,6 +121,7 @@ function createClientPool(options = {}) {
89
121
  },
90
122
  clear() {
91
123
  entries.clear();
124
+ readCaches.clear();
92
125
  },
93
126
  get size() {
94
127
  return entries.size;