@datadog/apps-frontend 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/src/_chunks/{chunk-2ZECSTB4.js → chunk-D43RPVCF.js} +2 -2
- package/dist/src/_chunks/chunk-DETZPDFA.js +7 -0
- package/dist/src/_chunks/chunk-DETZPDFA.js.map +7 -0
- package/dist/src/_chunks/chunk-EYBITW7J.js +7 -0
- package/dist/src/_chunks/chunk-EYBITW7J.js.map +7 -0
- package/dist/src/_chunks/chunk-OEPH347K.js +7 -0
- package/dist/src/_chunks/{chunk-G2SXTUX4.js.map → chunk-OEPH347K.js.map} +3 -3
- package/dist/src/_chunks/{chunk-627KNBXP.js → chunk-XSHCFEOH.js} +2 -2
- package/dist/src/_chunks/chunk-XSHCFEOH.js.map +7 -0
- package/dist/src/deep-links/react/index.js +1 -1
- package/dist/src/druids/react/index.js +1 -1
- package/dist/src/embedding/react/index.js +1 -1
- package/dist/src/inputs/published-definition.d.ts +39 -8
- package/dist/src/inputs/react/index.js +1 -1
- package/dist/src/inputs/schemas/generated/consumers/dashboard.d.ts +35 -0
- package/dist/src/inputs/schemas/generated/consumers/index.d.ts +15 -0
- package/dist/src/inputs/schemas/generated/consumers/notebook.d.ts +36 -0
- package/dist/src/inputs/schemas/generated/consumers/service-panel.d.ts +15 -0
- package/dist/src/inputs/schemas/generated/consumers/theme.d.ts +15 -0
- package/dist/src/inputs/schemas/index.d.ts +1 -20
- package/dist/src/inputs/schemas/index.js +1 -1
- package/dist/src/inputs/types.d.ts +19 -7
- package/package.json +5 -2
- package/dist/src/_chunks/chunk-627KNBXP.js.map +0 -7
- package/dist/src/_chunks/chunk-G2SXTUX4.js +0 -7
- package/dist/src/_chunks/chunk-PA4Z7DNH.js +0 -7
- package/dist/src/_chunks/chunk-PA4Z7DNH.js.map +0 -7
- package/dist/src/_chunks/chunk-QOXXZE7D.js +0 -7
- package/dist/src/_chunks/chunk-QOXXZE7D.js.map +0 -7
- package/dist/src/inputs/schemas/dashboard.d.ts +0 -30
- package/dist/src/inputs/schemas/theme.d.ts +0 -15
- /package/dist/src/_chunks/{chunk-2ZECSTB4.js.map → chunk-D43RPVCF.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0.
|
|
2
|
+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
|
|
3
|
+
* Copyright 2019-Present Datadog, Inc.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import{A as s,E as d,F as C,G as p,H as A,I,J as h,K as S,r as u,s as l}from"./chunk-LEEYMNMO.js";var x=["datadog.idp.homepage","datadog.idp.service-panel","datadog.idp.self-service","datadog.app-builder","datadog.appsec","datadog.notebook","datadog.dashboard"];function F(e,n,t){let o=Object.create(null),a=n;for(let[r,i]of Object.entries(e.fields))o[r]=i.kind==="value"?a[r]:Object.freeze({invoke:a[r]});return C(e,Object.freeze(o),t)}function b(e,n){let t=Object.create(null);for(let o of n)t[o]=e[o];return t}function D(e,n){if(e.kind!==n.kind)return!1;if(e.kind==="value"&&n.kind==="value")return e.schema===n.schema;if(e.kind==="function"&&n.kind==="function"){let t=Object.keys(e.inputs),o=Object.keys(n.inputs);return!(t.length!==o.length||e.result!==n.result||t.some(a=>!Object.prototype.hasOwnProperty.call(n.inputs,a)||e.inputs[a]!==n.inputs[a]))}return!1}function L(e,n){let t=Object.create(null);for(let[o,a]of Object.entries(e.fields))t[o]=a;for(let o of n)for(let[a,r]of Object.entries(o.extraInputs)){if(Object.prototype.hasOwnProperty.call(e.fields,a))throw new Error(`"${e.identifier}" v${o.contract.version} declares extra input "${a}", which already names a field of v${e.version}.`);let i=Object.prototype.hasOwnProperty.call(t,a)?t[a]:void 0;if(i&&!D(i,r))throw new Error(`"${e.identifier}" extra input "${a}" is declared with conflicting schemas by more than one older version.`);t[a]=r}return Object.freeze(t)}function R(e,...n){let t=new Set([e.version]);for(let r of n){if(r.contract.identifier!==e.identifier)throw new Error(`Older version "${r.contract.identifier}" v${r.contract.version} must share identifier "${e.identifier}" with its latest contract.`);if(r.contract.version>=e.version)throw new Error(`Older version "${e.identifier}" v${r.contract.version} must be older than latest v${e.version}.`);if(t.has(r.contract.version))throw new Error(`"${e.identifier}" declares version ${r.contract.version} more than once.`);t.add(r.contract.version)}let o=L(e,n),a=Object.keys(e.fields);return Object.freeze({identifier:e.identifier,latest:e,olderVersions:Object.freeze([...n]),fields:o,buildModules(r,i){let f=r,m=b(f,a),O=[F(e,m,i)];for(let c of n){let E=c.convert(m,b(f,Object.keys(c.extraInputs)));O.push(F(c.contract,E,i))}return Object.freeze(O)}})}var y=new WeakSet,V=/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/;function g(e,n,t){if(!d.test(n)||n.length>l||!p(t))throw new Error(`Datadog App input field "${e}.${n}" must have a name matching ${String(d)} of at most ${l} characters and be a read-only value or function whose schemas implement Standard Schema V1.`);if(t.kind==="function"){for(let o of Object.keys(t.inputs))if(!d.test(o))throw new Error(`Datadog App input function parameter "${e}.${n}.${o}" must have a name matching ${String(d)}.`);if(!A(t))throw new Error(`Datadog App input function field "${e}.${n}" declares a timeoutMs no call could meet. It must be greater than 0 and at most ${2147483647}.`)}}function T(e){if(!s(e)||typeof e.identifier!="string"||!V.test(e.identifier))throw new Error(`Datadog App input contract identifier "${String(s(e)?e.identifier:void 0)}" must match ${String(V)}.`);if(typeof e.version!="number"||!Number.isSafeInteger(e.version)||e.version<1)throw new Error(`Datadog App input contract "${e.identifier}" must have a positive integer version.`);if(!s(e.fields)||Object.keys(e.fields).length===0||Object.keys(e.fields).length>u)throw new Error(`Datadog App input contract "${e.identifier}" must define between 1 and ${u} fields.`);for(let[n,t]of Object.entries(e.fields))g(e.identifier,n,t)}function N(e,n){if(!s(n))throw new Error(`Older Datadog App input contract "${e}" must declare its extra inputs as an object.`);for(let[t,o]of Object.entries(n))g(e,t,o)}var Y=Object.freeze({readOnly(e){return I.readOnly(e)}}),K=Object.freeze({readOnly(e){return h.readOnly(e)}});function _(e){let n=S(e);return T(n),n}function q(e){let n=e,t="latest"in n?n.latest:_(n),o=n.olderVersions??[];T(t);for(let i of o)T(i.contract),N(t.identifier,i.extraInputs);let a=R(t,...o),r=Object.freeze({...a,surfaces:Object.freeze([...n.surfaces??x])});return y.add(r),r}function W(e,n=e.latest){if(P(e),n!==e.latest&&!e.olderVersions.some(o=>s(o)&&o.contract===n))throw new Error("The consumer contract must be a version served by its host definition.");let t=Object.freeze({identifier:e.identifier,latest:n,fields:n.fields,surfaces:e.surfaces});return y.add(t),t}function P(e){if(typeof e!="object"||e===null||!y.has(e))throw new Error("useDatadogAppInput() requires a definition exported by @datadog/apps-frontend/inputs/schema.")}export{Y as a,K as b,_ as c,q as d,W as e,P as f};
|
|
7
|
+
//# sourceMappingURL=chunk-OEPH347K.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/embedding/types.ts", "../../../src/embedding/versioning.ts", "../../../src/inputs/published-definition.ts"],
|
|
4
|
-
"sourcesContent": ["import type { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport type Unsubscribe = () => void;\n\nexport type Result<TValue, TError> =\n | Readonly<{ ok: true; value: TValue }>\n | Readonly<{ ok: false; error: TError }>;\n\n/**\n * A synchronous, deterministic, validation-only Standard Schema.\n *\n * Both embedding peers validate independently. Schemas must therefore have\n * identical input/output types and must not coerce or transform accepted\n * values.\n */\nexport type ValueSchema<TValue> = StandardSchemaV1<TValue, TValue>;\n\nexport type AnySchema = StandardSchemaV1;\n\nexport type InferOf<TSchema extends AnySchema> =\n StandardSchemaV1.InferOutput<TSchema>;\n\nexport type ValidationOnlySchema<TSchema extends AnySchema> =\n StandardSchemaV1.InferInput<TSchema> extends StandardSchemaV1.InferOutput<TSchema>\n ? StandardSchemaV1.InferOutput<TSchema> extends StandardSchemaV1.InferInput<TSchema>\n ? TSchema\n : never\n : never;\n\nexport type ContractVersion = number;\n\nexport interface ValueField<TSchema extends AnySchema> {\n readonly kind: 'value';\n readonly schema: ValidationOnlySchema<TSchema>;\n}\n\nexport interface FunctionField<\n TInputs extends Readonly<Record<string, AnySchema>>,\n TResult extends AnySchema,\n> {\n readonly kind: 'function';\n readonly inputs: {\n readonly [TName in keyof TInputs]: ValidationOnlySchema<TInputs[TName]>;\n };\n readonly result: ValidationOnlySchema<TResult>;\n /**\n * How long this function may run before it times out, overriding the\n * default `FUNCTION_CALL_TIMEOUT_MS`. A fast lookup can ask for seconds\n * instead of inheriting a ten-minute budget.\n *\n * Never sent over the wire. The app arms its wait from the contract it\n * claims and the host arms its watchdog from the contract it registers, so\n * two peers on different contract revisions may use different numbers.\n * That needs no reconciling: whichever watchdog fires first wins through\n * the normal `TIMED_OUT` path, as it already did with the default alone.\n *\n * Must be positive and no larger than `MAX_TIMER_DELAY_MS`. Outside that\n * range no call could ever meet it -- at `0` the host's deadline checks are\n * already past, and beyond the timer ceiling `setTimeout` overflows and\n * fires almost at once -- so `defineContract()` rejects it outright.\n */\n readonly timeoutMs?: number;\n}\n\nexport type AnyFunctionField = FunctionField<\n Readonly<Record<string, AnySchema>>,\n AnySchema\n>;\n\nexport type AnyField = ValueField<AnySchema> | AnyFunctionField;\n\nexport interface Contract<TFields extends Record<string, AnyField>> {\n readonly identifier: string;\n readonly version: ContractVersion;\n readonly fields: TFields;\n}\n\nexport type AnyContract = Contract<Record<string, AnyField>>;\n\nexport interface LiveValue<TValue> {\n get(): TValue;\n subscribe(onChange: () => void): Unsubscribe;\n}\n\nexport interface HostFunctionContext {\n /**\n * Aborts once the call is cancelled or its deadline passes. An async\n * implementation should check or listen for this to stop early. A\n * *synchronous* implementation has no way to observe it mid-call: JS\n * can't preempt a running function, so a synchronous handler that blocks\n * past the deadline still runs to completion and produces its value --\n * the caller is simply told the call timed out and never sees that\n * value, rather than the value being prevented from being computed.\n */\n readonly signal: AbortSignal;\n}\n\nexport interface HostFunction {\n invoke(\n inputs: Readonly<Record<string, unknown>>,\n context: HostFunctionContext,\n ): unknown;\n}\n\nexport type FunctionInputs<\n TInputs extends Readonly<Record<string, AnySchema>>,\n> = {\n readonly [TName in keyof TInputs as undefined extends InferOf<\n TInputs[TName]\n >\n ? TName\n : never]?: InferOf<TInputs[TName]>;\n} & {\n readonly [TName in keyof TInputs as undefined extends InferOf<\n TInputs[TName]\n >\n ? never\n : TName]: InferOf<TInputs[TName]>;\n};\n\n/** Resolves a contract field to the plain value/callable shape a claimant receives, ignoring subscription. */\ntype FieldValue<TField extends AnyField> =\n TField extends ValueField<infer TSchema>\n ? InferOf<TSchema>\n : TField extends FunctionField<infer TInputs, infer TResult>\n ? (inputs: FunctionInputs<TInputs>) => Promise<InferOf<TResult>>\n : never;\n\ntype ClaimedField<TField extends AnyField> =\n TField extends ValueField<infer TSchema>\n ? LiveValue<InferOf<TSchema>>\n : FieldValue<TField>;\n\n/** The live, per-field view of a claim: subscribable `LiveValue`s for value fields, callables for function fields. */\nexport type ClaimedFields<TContract extends AnyContract> = {\n readonly [TKey in keyof TContract['fields']]: ClaimedField<\n TContract['fields'][TKey]\n >;\n};\n\ndeclare const hostModuleBrand: unique symbol;\n\n/**\n * One contract version, live and ready to serve claims. Nominally branded --\n * `hostModuleBrand` is declared but never exported, so only this package can\n * produce a `HostModule`, and only through `createHostModule()`. That is what\n * keeps a host from assembling a module for one hand-picked version: the\n * single supported way in is to provide an inputs definition, which mints a\n * module for *every* version that definition still converts to. The brand has\n * no runtime representation.\n */\nexport interface HostModule {\n readonly [hostModuleBrand]: true;\n readonly contract: AnyContract;\n readonly implementation: Readonly<\n Record<string, LiveValue<unknown> | HostFunction>\n >;\n readonly signal?: AbortSignal;\n}\n\nexport interface Issue {\n readonly message: string;\n readonly path: readonly (string | number)[];\n}\n\nexport type AnyError =\n | Readonly<{ code: 'ORIGIN_REJECTED'; origin: string }>\n | Readonly<{\n code: 'APP_PROTOCOL_TOO_OLD';\n appProtocols: readonly number[];\n hostProtocols: readonly number[];\n }>\n | Readonly<{\n code: 'HOST_PROTOCOL_TOO_OLD';\n appProtocols: readonly number[];\n hostProtocols: readonly number[];\n }>\n | Readonly<{\n code: 'PROTOCOL_INCOMPATIBLE';\n appProtocols: readonly number[];\n hostProtocols: readonly number[];\n }>\n | Readonly<{ code: 'PEER_LACKS_MODULE'; identifier: string }>\n | Readonly<{\n code: 'APP_MAJOR_TOO_OLD';\n wanted: ContractVersion;\n hostVersions: readonly ContractVersion[];\n }>\n | Readonly<{\n code: 'HOST_MAJOR_TOO_OLD';\n wanted: ContractVersion;\n hostVersions: readonly ContractVersion[];\n }>\n | Readonly<{ code: 'CONTRACT_INCOMPATIBLE'; field: string }>\n | Readonly<{ code: 'INVALID_ARGUMENT'; issues: readonly Issue[] }>\n | Readonly<{ code: 'FUNCTION_FAILED'; field: string }>\n | Readonly<{ code: 'INVALID_RESULT'; issues: readonly Issue[] }>\n | Readonly<{ code: 'TIMED_OUT'; timeoutMs: number }>\n | Readonly<{ code: 'TRANSPORT_FAILED'; cause: unknown }>\n | Readonly<{ code: 'ABORTED' }>\n | Readonly<{ code: 'DISCONNECTED' }>\n | Readonly<{ code: 'UNRECOGNIZED'; rawCode: string; raw: unknown }>;\n\nexport type ErrorOf<TCode extends AnyError['code']> = Extract<\n AnyError,\n { code: TCode }\n>;\n\nexport type ConnectError = ErrorOf<\n | 'ORIGIN_REJECTED'\n | 'APP_PROTOCOL_TOO_OLD'\n | 'HOST_PROTOCOL_TOO_OLD'\n | 'PROTOCOL_INCOMPATIBLE'\n | 'TIMED_OUT'\n | 'TRANSPORT_FAILED'\n | 'ABORTED'\n | 'DISCONNECTED'\n | 'UNRECOGNIZED'\n>;\n\nexport type WireClaimError = ErrorOf<\n | 'PEER_LACKS_MODULE'\n | 'APP_MAJOR_TOO_OLD'\n | 'HOST_MAJOR_TOO_OLD'\n | 'CONTRACT_INCOMPATIBLE'\n | 'INVALID_RESULT'\n | 'TIMED_OUT'\n | 'ABORTED'\n | 'DISCONNECTED'\n | 'UNRECOGNIZED'\n>;\n\nexport type WireFunctionError = ErrorOf<\n | 'CONTRACT_INCOMPATIBLE'\n | 'INVALID_ARGUMENT'\n | 'FUNCTION_FAILED'\n | 'INVALID_RESULT'\n | 'TIMED_OUT'\n | 'ABORTED'\n | 'DISCONNECTED'\n | 'UNRECOGNIZED'\n>;\n\nexport type ClaimInvalidationError = ErrorOf<\n 'INVALID_RESULT' | 'DISCONNECTED' | 'UNRECOGNIZED'\n>;\n\nexport interface Claimed<TContract extends AnyContract> {\n readonly fields: ClaimedFields<TContract>;\n release(): void;\n onValuesChanged(listener: () => void): Unsubscribe;\n onInvalidated(\n listener: (error: ClaimInvalidationError) => void,\n ): Unsubscribe;\n}\n\nexport interface ClaimOptions {\n /**\n * Local claim deadline. Must be finite, non-negative, and no larger than\n * the platform timer ceiling (`2_147_483_647`).\n */\n readonly timeoutMs?: number;\n readonly signal?: AbortSignal;\n}\n\nexport interface AppConnection {\n claim<TContract extends AnyContract>(\n contract: TContract,\n options?: ClaimOptions,\n ): Promise<Result<Claimed<TContract>, WireClaimError>>;\n}\n\n/**\n * Identifies which product surface a Datadog App is embedded into (e.g. the\n * Service Catalog side panel vs. IDP), so an app can render surface-specific\n * content. Each value matches the identifier of the schema that surface\n * provides. Sent host-to-app as part of the embedding connection handshake.\n */\n/**\n * Every surface, as a tuple rather than a bare union so it can also serve as a\n * type: `DatadogAppInputsSchema` defaults its `surfaces` to this, which makes\n * an IDE print the members in full on hover instead of collapsing them to the\n * `SurfaceId` alias.\n */\nexport const EVERY_SURFACE: readonly [\n 'datadog.idp.homepage',\n 'datadog.idp.service-panel',\n 'datadog.idp.self-service',\n 'datadog.app-builder',\n 'datadog.appsec',\n 'datadog.notebook',\n 'datadog.dashboard',\n] = [\n 'datadog.idp.homepage',\n 'datadog.idp.service-panel',\n 'datadog.idp.self-service',\n 'datadog.app-builder',\n 'datadog.appsec',\n 'datadog.notebook',\n 'datadog.dashboard',\n];\n\n/**\n * The static category of surface where an embedding session is running.\n * It is chosen when the connection is established and does not change in\n * place. Dynamic placement or parent/child relationships (for example, a\n * pinned app moving between containers) belong in separately versioned\n * module inputs rather than mutations to `surfaceId`.\n *\n * Derived from `EVERY_SURFACE`, so there is one list, but widened to arbitrary\n * strings: it is metadata forwarded to `listen()` and may be used by the host\n * to gate which input schemas are offered on a given surface, but it never\n * gates whether embedding connects \u2014 a host is free to pass a value with\n * no matching surface (e.g. an unmapped view context) rather than going\n * without one.\n */\nexport type SurfaceId = (typeof EVERY_SURFACE)[number] | (string & {});\n\nexport type AppConnectionState =\n | Readonly<{ state: 'connecting'; error?: ConnectError }>\n | Readonly<{\n state: 'connected';\n connection: AppConnection;\n surfaceId?: SurfaceId;\n }>\n | Readonly<{ state: 'reconnecting'; lastError: ConnectError }>\n | Readonly<{ state: 'rejected'; error: ConnectError }>\n | Readonly<{ state: 'not-embedded' }>\n | Readonly<{ state: 'closed' }>;\n\n/**\n * Public-safe view of `AppConnectionState`: the same lifecycle cases, minus\n * the raw `AppConnection` a consumer would otherwise have no use for outside\n * of claiming a contract.\n */\nexport type EmbeddingMetadata =\n | Readonly<{ state: 'connecting'; error?: ConnectError }>\n | Readonly<{ state: 'connected'; surfaceId?: SurfaceId }>\n | Readonly<{ state: 'reconnecting'; lastError: ConnectError }>\n | Readonly<{ state: 'rejected'; error: ConnectError }>\n | Readonly<{ state: 'not-embedded' }>\n | Readonly<{ state: 'closed' }>;\n\nexport interface EmbeddingMetadataStore {\n readonly getSnapshot: () => EmbeddingMetadata;\n readonly subscribe: (onChange: () => void) => Unsubscribe;\n}\n\nexport interface AppConnectionHandle {\n getSnapshot(): AppConnectionState;\n subscribe(onChange: () => void): Unsubscribe;\n close(): void;\n}\n\nexport interface AppConnectionFactory {\n connect(): AppConnectionHandle;\n}\n\nexport interface HostListenOptions {\n /** Security boundary for the app-created bootstrap port. */\n readonly peer: Readonly<{\n frame: HTMLIFrameElement;\n appOrigin: string;\n /**\n * Set when the iframe is intentionally configured with an opaque\n * sandboxed origin, so the host should accept a `\"null\"` origin from\n * it in place of an exact match against `appOrigin`.\n */\n allowOpaqueOrigin?: boolean;\n }>;\n readonly modules: readonly HostModule[];\n /** Static surface category for the lifetime of the established connection. */\n readonly surfaceId?: SurfaceId;\n /**\n * Local compatibility and establishment deadline for each phase. Must be\n * finite, non-negative, and no larger than the platform timer ceiling\n * (`2_147_483_647`).\n */\n readonly timeoutMs?: number;\n readonly signal?: AbortSignal;\n}\n\nexport interface HostListener {\n onError(listener: (error: ConnectError) => void): Unsubscribe;\n /**\n * Fires exactly once per successful operational session: after permanent\n * bootstrap and compatibility negotiation complete, before any\n * per-module claim resolves. Not a one-shot for the listener's whole\n * lifetime -- if this session is later superseded (a new bootstrap\n * replaces it, see `close()`'s effect on an active connection) and a new\n * session establishes, this fires again for that new session. Never\n * fires for an attempt that fails, or after `close()`. A subscriber that\n * calls `onReady` while a session is already active is notified\n * immediately upon subscribing, so a late subscriber cannot miss an\n * already-established session.\n */\n onReady(listener: () => void): Unsubscribe;\n close(): void;\n}\n\nexport type EmbeddingError =\n | Readonly<{ code: 'TIMED_OUT'; message: string; action: 'retry' }>\n | Readonly<{\n code: 'ORIGIN_REJECTED';\n message: string;\n action: 'contact-support';\n }>\n | Readonly<{\n code: 'APP_PROTOCOL_TOO_OLD';\n message: string;\n action: 'update-app';\n }>\n | Readonly<{\n code: 'HOST_PROTOCOL_TOO_OLD' | 'PROTOCOL_INCOMPATIBLE';\n message: string;\n action: 'contact-support';\n }>\n | Readonly<{\n code: 'CONNECTION_LOST';\n message: string;\n action: 'retry';\n }>\n | Readonly<{\n code: 'UNKNOWN';\n message: string;\n action: 'contact-support';\n }>;\n\nexport type ClaimError =\n | EmbeddingError\n | Readonly<{\n code: 'APP_MAJOR_TOO_OLD';\n action: 'update-app';\n requestedVersion: ContractVersion;\n availableVersions: readonly ContractVersion[];\n message: string;\n }>\n | Readonly<{\n code: 'HOST_MAJOR_TOO_OLD';\n action: 'contact-support';\n requestedVersion: ContractVersion;\n availableVersions: readonly ContractVersion[];\n message: string;\n }>;\n\nexport type ClaimedValues<TContract extends AnyContract> = Readonly<{\n [TKey in keyof TContract['fields']]: FieldValue<TContract['fields'][TKey]>;\n}>;\n\nexport type ClaimState<TContract extends AnyContract> =\n | Readonly<{ status: 'pending' }>\n | Readonly<{\n status: 'ready';\n fields: ClaimedValues<TContract>;\n }>\n | Readonly<{ status: 'unavailable' }>\n | Readonly<{ status: 'failed'; error: ClaimError }>;\n\nexport interface ClaimStore<TContract extends AnyContract> {\n readonly getSnapshot: () => ClaimState<TContract>;\n readonly subscribe: (onChange: () => void) => Unsubscribe;\n}\n\n/** Framework-neutral claim capability consumed by feature modules. */\nexport interface AppClaims {\n getClaim<TContract extends AnyContract>(\n contract: TContract,\n ): ClaimStore<TContract>;\n}\n\n/** Owns the lifecycle of one concrete embedding implementation. */\nexport interface AppEmbedding extends AppClaims {\n start(): Unsubscribe;\n getEmbeddingMetadata(): EmbeddingMetadataStore;\n}\n\n/**\n * One established connection, owned by the caller that opened it. These say\n * nothing about which operational protocol produced them, so the connection\n * lifecycle does not change when a protocol is added or retired.\n */\nexport type ManagedAppConnection = Readonly<{\n connection: AppConnection;\n surfaceId?: SurfaceId;\n closeSignal: AbortSignal;\n close(): void;\n}>;\n\nexport type ManagedHostConnection = Readonly<{\n closeSignal: AbortSignal;\n close(): void;\n}>;\n", "import { MAX_CLAIM_FIELD_NAME_LENGTH } from './config';\nimport {\n createHostModule,\n isAnyFieldShape,\n VALID_FIELD_NAME,\n} from './contract';\nimport { teardown } from './shared';\nimport type {\n AnyContract,\n AnyField,\n ContractVersion,\n FunctionField,\n FunctionInputs,\n HostFunction,\n HostFunctionContext,\n HostModule,\n InferOf,\n LiveValue,\n Unsubscribe,\n ValueField,\n} from './types';\n\ntype HostFieldImplementation<TField extends AnyField> =\n TField extends ValueField<infer TSchema>\n ? LiveValue<InferOf<TSchema>>\n : TField extends FunctionField<infer TInputs, infer TResult>\n ? (\n inputs: FunctionInputs<TInputs>,\n context: HostFunctionContext,\n ) => InferOf<TResult> | Promise<InferOf<TResult>>\n : never;\n\n/** The live host-side implementation of a raw field map: `LiveValue`s for value fields, plain callables for function fields. */\nexport type HostFieldsFor<TFields extends Record<string, AnyField>> = Readonly<{\n [TName in keyof TFields]: HostFieldImplementation<TFields[TName]>;\n}>;\n\n/** The live host-side implementation of a whole contract's fields. */\nexport type HostFields<TContract extends AnyContract> = HostFieldsFor<\n TContract['fields']\n>;\n\n/**\n * A `LiveValue` that recomputes from `sources` on every `get()` rather than\n * caching, so it always reflects whichever of `sources` last changed without\n * needing its own dedupe or disposal bookkeeping -- that already lives on\n * `sources` themselves.\n */\nexport function deriveLiveValue<TValue>(\n sources: readonly LiveValue<unknown>[],\n compute: () => TValue,\n): LiveValue<TValue> {\n return Object.freeze({\n get: compute,\n subscribe(onChange: () => void): Unsubscribe {\n // Acquired sequentially (not via `sources.map()`) so a later\n // source throwing rolls back every subscription already made.\n const unsubscribes: Unsubscribe[] = [];\n try {\n for (const source of sources) {\n unsubscribes.push(source.subscribe(onChange));\n }\n } catch (error) {\n for (const unsubscribe of unsubscribes) {\n teardown(\n 'deriveLiveValue subscription rollback',\n unsubscribe,\n );\n }\n throw error;\n }\n // Routed through `teardown()` so one throwing unsubscribe can't\n // skip the rest.\n return () => {\n for (const unsubscribe of unsubscribes) {\n teardown('deriveLiveValue unsubscribe', unsubscribe);\n }\n };\n },\n });\n}\n\n/**\n * One older version of `TLatest`: its own frozen contract, the extra live\n * inputs its `convert` needs beyond what `TLatest` already carries, and the\n * function that derives its fields from `TLatest` plus those extras. Runs\n * once, at `buildModules()` time, and must return live fields -- typically\n * built with `deriveLiveValue()` -- so the older version stays exactly as\n * reactive as `TLatest`, with `TLatest`'s own implementation untouched.\n */\nexport interface OlderContractVersion<\n TLatest extends AnyContract,\n TOlder extends AnyContract,\n TExtraInputs extends Record<string, AnyField>,\n> {\n readonly contract: TOlder;\n readonly extraInputs: TExtraInputs;\n convert(\n latest: HostFields<TLatest>,\n extra: HostFieldsFor<TExtraInputs>,\n ): HostFields<TOlder>;\n}\n\nexport type AnyOlderContractVersion<TLatest extends AnyContract> =\n OlderContractVersion<TLatest, AnyContract, Record<string, AnyField>>;\n\n/**\n * Declares and validates one `OlderContractVersion`. Takes `latest` as its\n * own argument -- rather than only through `definition.convert`'s parameter\n * type -- so `TLatest` can be inferred directly from a value in covariant\n * position; inference can't otherwise recover it from `convert`'s parameter,\n * a contravariant position, and silently falls back to `AnyContract`.\n */\nexport function olderVersion<\n TLatest extends AnyContract,\n TOlder extends AnyContract,\n const TExtraInputs extends Record<string, AnyField>,\n>(\n _latest: TLatest,\n definition: OlderContractVersion<TLatest, TOlder, TExtraInputs>,\n): OlderContractVersion<TLatest, TOlder, TExtraInputs> {\n for (const [name, field] of Object.entries(definition.extraInputs)) {\n if (\n !VALID_FIELD_NAME.test(name) ||\n name.length > MAX_CLAIM_FIELD_NAME_LENGTH ||\n !isAnyFieldShape(field)\n ) {\n throw new Error(\n `Older-version extra input \"${definition.contract.identifier}.${name}\" must be a named read-only value or function whose schemas implement Standard Schema V1.`,\n );\n }\n }\n return Object.freeze({\n contract: definition.contract,\n extraInputs: Object.freeze({ ...definition.extraInputs }),\n convert: definition.convert,\n });\n}\n\nexport interface VersionedContract<\n TLatest extends AnyContract,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n> {\n readonly identifier: TLatest['identifier'];\n /**\n * The version an up-to-date peer claims. Read by the claiming side to\n * know what it is asking for; never a way to *provide* one version alone,\n * since `buildModules()` is all-or-nothing.\n */\n readonly latest: TLatest;\n readonly olderVersions: TOlderVersions;\n /**\n * `X`: every field needed to serve every version, in one flat namespace.\n * A provider populates exactly this and learns nothing about how many\n * versions sit behind it.\n */\n readonly fields: VersionedContractFields<TLatest, TOlderVersions>;\n /**\n * Mints one live module per version -- latest plus every version that\n * still has a converter -- from one flat field record. There is\n * deliberately no way to ask for a subset: supporting a version and\n * serving it are the same act.\n */\n buildModules(\n fields: HostFieldsFor<VersionedContractFields<TLatest, TOlderVersions>>,\n signal?: AbortSignal,\n ): readonly HostModule[];\n}\n\n/**\n * Structural bound for \"some versioned contract\", used where generic code\n * needs to accept any of them. Deliberately forgetful about `buildModules`'s\n * parameter and about `olderVersions`' element type: both are contravariant,\n * so naming them would make every concrete contract fail to satisfy this.\n * Callers recover the precise field types from the generic parameter itself\n * (see `DatadogAppInputImplementations`), not from this bound.\n */\nexport type AnyVersionedContract = Readonly<{\n identifier: string;\n latest: AnyContract;\n olderVersions: readonly unknown[];\n fields: Readonly<Record<string, AnyField>>;\n buildModules: (\n fields: never,\n signal?: AbortSignal,\n ) => readonly HostModule[];\n}>;\n\nexport type UnionToIntersection<TUnion> = (\n TUnion extends unknown ? (key: TUnion) => void : never\n) extends (key: infer TIntersection) => void\n ? TIntersection\n : never;\n\ntype OlderVersionsExtraFieldsUnion<\n TLatest extends AnyContract,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n> = {\n [TIndex in keyof TOlderVersions]: TOlderVersions[TIndex] extends OlderContractVersion<\n TLatest,\n AnyContract,\n infer TExtraInputs\n >\n ? TExtraInputs\n : never;\n}[number];\n\n/**\n * Every field needed to construct every version this contract declares,\n * flattened into one namespace: `latest`'s own fields plus each older\n * version's `extraInputs`. This is `giving` values' whole contract with\n * versioning -- a caller populates this one flat record with no notion that\n * more than one version exists behind it. Field names must therefore be\n * unique across `latest` and every older version's `extraInputs`; two older\n * versions may reuse the same name only when it means the same schema, since\n * flattening gives it exactly one slot.\n */\nexport type VersionedContractFields<\n TLatest extends AnyContract,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n> =\n OlderVersionsExtraFieldsUnion<TLatest, TOlderVersions> extends never\n ? TLatest['fields']\n : TLatest['fields'] &\n UnionToIntersection<\n OlderVersionsExtraFieldsUnion<TLatest, TOlderVersions>\n >;\n\nfunction toHostModule<TContract extends AnyContract>(\n contract: TContract,\n fields: HostFields<TContract>,\n signal: AbortSignal | undefined,\n): HostModule {\n // Null-prototype as defence in depth. `olderVersion` already rejects an\n // extra input named \"__proto__\" via `VALID_FIELD_NAME`, so no such name\n // should reach here; a plain `{}` would silently drop it through the\n // legacy setter rather than defining an own property if one ever did.\n const implementation: Record<string, LiveValue<unknown> | HostFunction> =\n Object.create(null);\n const rawFields: Record<string, unknown> = fields;\n for (const [name, field] of Object.entries(contract.fields)) {\n implementation[name] =\n field.kind === 'value'\n ? (rawFields[name] as LiveValue<unknown>)\n : Object.freeze({\n invoke: rawFields[name] as HostFunction['invoke'],\n });\n }\n return createHostModule(contract, Object.freeze(implementation), signal);\n}\n\n/** Narrows a flat field record to the names one version actually reads. */\nfunction pickFields(\n fields: Readonly<Record<string, unknown>>,\n names: readonly string[],\n): Readonly<Record<string, unknown>> {\n // Null-prototype for the same defence-in-depth reason as `toHostModule`\n // above: `names` can include an older version's extra-input name, which\n // `olderVersion` already shape-checks with `VALID_FIELD_NAME`.\n const picked: Record<string, unknown> = Object.create(null);\n for (const name of names) {\n picked[name] = fields[name];\n }\n return picked;\n}\n\n/**\n * Whether two versions asking for the same field name mean the same thing.\n * Flattening gives a name exactly one slot, so a disagreement has to be an\n * authoring error rather than something a provider could satisfy twice.\n */\nfunction isSameField(left: AnyField, right: AnyField): boolean {\n if (left.kind !== right.kind) {\n return false;\n }\n if (left.kind === 'value' && right.kind === 'value') {\n return left.schema === right.schema;\n }\n if (left.kind === 'function' && right.kind === 'function') {\n const leftNames = Object.keys(left.inputs);\n const rightNames = Object.keys(right.inputs);\n // Deliberately does not compare `timeoutMs`. This check exists so one\n // provider implementation can serve every version sharing a flattened\n // slot, which a mismatched schema or input name would prevent. A\n // deadline cannot prevent it: the flattened descriptor is only used to\n // type the provider record and to slice it by name, and `buildModules`\n // hands each version `toHostModule(older.contract, ...)`, so every\n // deadline is resolved from that version's own contract field. Two\n // versions reusing one extra-input name may declare different\n // deadlines with no runtime consequence whatsoever.\n return !(\n leftNames.length !== rightNames.length ||\n left.result !== right.result ||\n leftNames.some(\n (name) =>\n !Object.prototype.hasOwnProperty.call(right.inputs, name) ||\n left.inputs[name] !== right.inputs[name],\n )\n );\n }\n return false;\n}\n\n/**\n * Flattens `latest`'s own fields together with every older version's extra\n * inputs into the one namespace a provider populates, rejecting the two ways\n * that flattening can go wrong: an extra input that shadows a real field of\n * `latest`, and two older versions claiming one name for different schemas.\n */\nfunction mergeVersionedFields<TLatest extends AnyContract>(\n latest: TLatest,\n olderVersions: readonly AnyOlderContractVersion<TLatest>[],\n): Readonly<Record<string, AnyField>> {\n // Null-prototype as defence in depth: `VALID_FIELD_NAME` already excludes\n // an extra input named \"__proto__\", but were one to reach here it must\n // become an own property rather than invoke the inherited legacy setter\n // and silently repoint `merged`'s prototype.\n const merged: Record<string, AnyField> = Object.create(null);\n for (const [name, field] of Object.entries(latest.fields)) {\n merged[name] = field;\n }\n for (const older of olderVersions) {\n for (const [name, field] of Object.entries(older.extraInputs)) {\n if (Object.prototype.hasOwnProperty.call(latest.fields, name)) {\n throw new Error(\n `\"${latest.identifier}\" v${older.contract.version} declares extra input \"${name}\", which already names a field of v${latest.version}.`,\n );\n }\n const existing = Object.prototype.hasOwnProperty.call(merged, name)\n ? merged[name]\n : undefined;\n if (existing && !isSameField(existing, field)) {\n throw new Error(\n `\"${latest.identifier}\" extra input \"${name}\" is declared with conflicting schemas by more than one older version.`,\n );\n }\n merged[name] = field;\n }\n }\n return Object.freeze(merged);\n}\n\n/**\n * Ties a latest contract to any number of older versions it stays willing to\n * serve. `buildModules()` derives each older version's fields from the\n * latest implementation plus that version's own extra inputs and returns one\n * independent, fully live `HostModule` per version -- ready to hand to a\n * host listener alongside modules for any other contract.\n */\nexport function defineVersionedContract<\n TLatest extends AnyContract,\n const TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n>(\n latest: TLatest,\n ...olderVersions: TOlderVersions\n): VersionedContract<TLatest, TOlderVersions> {\n const versions = new Set<ContractVersion>([latest.version]);\n for (const older of olderVersions) {\n if (older.contract.identifier !== latest.identifier) {\n throw new Error(\n `Older version \"${older.contract.identifier}\" v${older.contract.version} must share identifier \"${latest.identifier}\" with its latest contract.`,\n );\n }\n if (older.contract.version >= latest.version) {\n throw new Error(\n `Older version \"${latest.identifier}\" v${older.contract.version} must be older than latest v${latest.version}.`,\n );\n }\n if (versions.has(older.contract.version)) {\n throw new Error(\n `\"${latest.identifier}\" declares version ${older.contract.version} more than once.`,\n );\n }\n versions.add(older.contract.version);\n }\n\n const fields = mergeVersionedFields(latest, olderVersions);\n const latestNames = Object.keys(latest.fields);\n\n return Object.freeze({\n identifier: latest.identifier,\n latest,\n // `Object.freeze` on the returned object is shallow: exposing the\n // validated array by reference would let a caller mutate it (push,\n // sort, splice) after the fact despite the wrapper looking frozen.\n olderVersions: Object.freeze([...olderVersions]) as TOlderVersions,\n fields: fields as VersionedContractFields<TLatest, TOlderVersions>,\n buildModules(\n allFields: HostFieldsFor<\n VersionedContractFields<TLatest, TOlderVersions>\n >,\n signal?: AbortSignal,\n ): readonly HostModule[] {\n const flat: Readonly<Record<string, unknown>> = allFields;\n // Slicing by each version's own field names is what lets two\n // versions share one slot: both reads hit the same live value.\n const latestImplementation = pickFields(\n flat,\n latestNames,\n ) as HostFields<TLatest>;\n const modules: HostModule[] = [\n toHostModule(latest, latestImplementation, signal),\n ];\n for (const older of olderVersions) {\n const derived = older.convert(\n latestImplementation,\n pickFields(\n flat,\n Object.keys(older.extraInputs),\n ) as HostFieldsFor<Record<string, AnyField>>,\n );\n modules.push(toHostModule(older.contract, derived, signal));\n }\n return Object.freeze(modules);\n },\n });\n}\n", "import {\n MAX_CLAIM_FIELD_NAME_LENGTH,\n MAX_CLAIM_FIELDS,\n MAX_TIMER_DELAY_MS,\n} from '../embedding/config';\nimport {\n defineContract,\n fn as defineFunctionField,\n hasUsableFunctionTimeout,\n isAnyFieldShape,\n VALID_FIELD_NAME,\n value as defineValueField,\n} from '../embedding/contract';\nimport { isRecord } from '../embedding/shared';\nimport { EVERY_SURFACE } from '../embedding/types';\nimport type {\n AnyContract,\n AnyField,\n AnySchema,\n Contract,\n ContractVersion,\n FunctionField,\n InferOf,\n SurfaceId,\n ValidationOnlySchema,\n ValueField,\n ValueSchema,\n} from '../embedding/types';\nimport { defineVersionedContract } from '../embedding/versioning';\nimport type {\n AnyOlderContractVersion,\n AnyVersionedContract,\n VersionedContract,\n} from '../embedding/versioning';\n\ndeclare const publishedDefinitionBrand: unique symbol;\n\n/**\n * One published inputs definition: every version it serves, and the surfaces\n * it is offered on.\n *\n * `surfaces` is read at runtime by `datadogAppHostInputsFor` to gate which\n * schemas a host offers on a given surface \u2014 a dashboard-only schema is not\n * offered on IDP even if a synthetic `dashboard` field is present in the\n * inputs bag. Omitted resolves to every `SurfaceId`, so the hint reads as\n * \"available everywhere\" rather than as an empty list.\n */\nexport type DatadogAppInputsSchema<\n TLatest extends AnyContract,\n TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[] =\n readonly [],\n> = VersionedContract<TLatest, TOlderVersions> &\n Readonly<{ surfaces: TSurfaces }>;\n\nexport type AnyDatadogAppInputsSchema = AnyVersionedContract &\n Readonly<{ surfaces: readonly SurfaceId[] }>;\n\nexport type PublishedDatadogAppInputsDefinition<\n TSchema extends AnyDatadogAppInputsSchema,\n> = TSchema &\n Readonly<{\n [publishedDefinitionBrand]: (\n fields: TSchema['latest']['fields'],\n ) => TSchema['latest']['fields'];\n }>;\n\n/** A package-owned definition whose concrete, deliberately invariant fields are unknown. */\nexport type AnyPublishedDatadogAppInputsDefinition = AnyDatadogAppInputsSchema &\n Readonly<{ [publishedDefinitionBrand]: unknown }>;\n\nconst publishedDefinitions = new WeakSet<object>();\n\ntype PortableSchema<TSchema extends AnySchema> = ValueSchema<InferOf<TSchema>>;\n\nconst CONTRACT_IDENTIFIER_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/;\n\nfunction assertValidField(\n contractIdentifier: string,\n name: string,\n field: unknown,\n): asserts field is AnyField {\n if (\n !VALID_FIELD_NAME.test(name) ||\n name.length > MAX_CLAIM_FIELD_NAME_LENGTH ||\n !isAnyFieldShape(field)\n ) {\n throw new Error(\n `Datadog App input field \"${contractIdentifier}.${name}\" must have a name matching ${String(VALID_FIELD_NAME)} of at most ${MAX_CLAIM_FIELD_NAME_LENGTH} characters and be a read-only value or function whose schemas implement Standard Schema V1.`,\n );\n }\n if (field.kind === 'function') {\n for (const inputName of Object.keys(field.inputs)) {\n if (!VALID_FIELD_NAME.test(inputName)) {\n throw new Error(\n `Datadog App input function parameter \"${contractIdentifier}.${name}.${inputName}\" must have a name matching ${String(VALID_FIELD_NAME)}.`,\n );\n }\n }\n if (!hasUsableFunctionTimeout(field)) {\n throw new Error(\n `Datadog App input function field \"${contractIdentifier}.${name}\" declares a timeoutMs no call could meet. It must be greater than 0 and at most ${MAX_TIMER_DELAY_MS}.`,\n );\n }\n }\n}\n\nfunction assertValidContract(\n contract: unknown,\n): asserts contract is AnyContract {\n if (\n !isRecord(contract) ||\n typeof contract.identifier !== 'string' ||\n !CONTRACT_IDENTIFIER_PATTERN.test(contract.identifier)\n ) {\n throw new Error(\n `Datadog App input contract identifier \"${String(isRecord(contract) ? contract.identifier : undefined)}\" must match ${String(CONTRACT_IDENTIFIER_PATTERN)}.`,\n );\n }\n if (\n typeof contract.version !== 'number' ||\n !Number.isSafeInteger(contract.version) ||\n contract.version < 1\n ) {\n throw new Error(\n `Datadog App input contract \"${contract.identifier}\" must have a positive integer version.`,\n );\n }\n if (\n !isRecord(contract.fields) ||\n Object.keys(contract.fields).length === 0 ||\n Object.keys(contract.fields).length > MAX_CLAIM_FIELDS\n ) {\n throw new Error(\n `Datadog App input contract \"${contract.identifier}\" must define between 1 and ${MAX_CLAIM_FIELDS} fields.`,\n );\n }\n for (const [name, field] of Object.entries(contract.fields)) {\n assertValidField(contract.identifier, name, field);\n }\n}\n\nfunction assertValidExtraInputs(\n contractIdentifier: string,\n extraInputs: unknown,\n): void {\n if (!isRecord(extraInputs)) {\n throw new Error(\n `Older Datadog App input contract \"${contractIdentifier}\" must declare its extra inputs as an object.`,\n );\n }\n for (const [name, field] of Object.entries(extraInputs)) {\n assertValidField(contractIdentifier, name, field);\n }\n}\n\ninterface PortableValueBuilder {\n readOnly<TSchema extends AnySchema>(\n schema: ValidationOnlySchema<TSchema>,\n ): ValueField<PortableSchema<TSchema>>;\n}\n\ninterface PortableFunctionBuilder {\n readOnly<\n const TInputs extends Readonly<Record<string, AnySchema>>,\n TResult extends AnySchema,\n >(\n definition: Readonly<{\n inputs: {\n readonly [TName in keyof TInputs]: ValidationOnlySchema<\n TInputs[TName]\n >;\n };\n result: ValidationOnlySchema<TResult>;\n /**\n * Optional per-function override of `FUNCTION_CALL_TIMEOUT_MS`.\n * See `FunctionField.timeoutMs`.\n */\n timeoutMs?: number;\n }>,\n ): FunctionField<\n {\n readonly [TName in keyof TInputs]: PortableSchema<TInputs[TName]>;\n },\n PortableSchema<TResult>\n >;\n}\n\n/** Builds an input value field while hiding its concrete validator type. */\nexport const value: PortableValueBuilder = /* @__PURE__ */ Object.freeze({\n readOnly<TSchema extends AnySchema>(\n schema: ValidationOnlySchema<TSchema>,\n ): ValueField<PortableSchema<TSchema>> {\n return defineValueField.readOnly(schema) as unknown as ValueField<\n PortableSchema<TSchema>\n >;\n },\n});\n\n/** Builds an input function field while hiding its concrete validator types. */\nexport const fn: PortableFunctionBuilder = /* @__PURE__ */ Object.freeze({\n readOnly<\n const TInputs extends Readonly<Record<string, AnySchema>>,\n TResult extends AnySchema,\n >(\n definition: Readonly<{\n inputs: {\n readonly [TName in keyof TInputs]: ValidationOnlySchema<\n TInputs[TName]\n >;\n };\n result: ValidationOnlySchema<TResult>;\n timeoutMs?: number;\n }>,\n ): FunctionField<\n {\n readonly [TName in keyof TInputs]: PortableSchema<TInputs[TName]>;\n },\n PortableSchema<TResult>\n > {\n return defineFunctionField.readOnly(\n definition,\n ) as unknown as FunctionField<\n {\n readonly [TName in keyof TInputs]: PortableSchema<\n TInputs[TName]\n >;\n },\n PortableSchema<TResult>\n >;\n },\n});\n\ntype ValidationOnlyFields<TFields extends Record<string, AnyField>> = {\n readonly [TName in keyof TFields]: TFields[TName] extends ValueField<\n infer TSchema\n >\n ? ValueField<ValidationOnlySchema<TSchema>>\n : TFields[TName] extends FunctionField<infer TInputs, infer TResult>\n ? FunctionField<\n {\n readonly [TInputName in keyof TInputs]: ValidationOnlySchema<\n TInputs[TInputName]\n >;\n },\n ValidationOnlySchema<TResult>\n >\n : never;\n};\n\ntype PortableFields<TFields extends Record<string, AnyField>> = {\n readonly [TName in keyof TFields]: TFields[TName] extends ValueField<\n infer TSchema\n >\n ? ValueField<PortableSchema<TSchema>>\n : TFields[TName] extends FunctionField<infer TInputs, infer TResult>\n ? FunctionField<\n {\n readonly [TInputName in keyof TInputs]: PortableSchema<\n TInputs[TInputName]\n >;\n },\n PortableSchema<TResult>\n >\n : never;\n};\n\nexport type PortableContract<\n TIdentifier extends string,\n TVersion extends ContractVersion,\n TFields extends Record<string, AnyField>,\n> = Contract<PortableFields<TFields>> &\n Readonly<{ identifier: TIdentifier; version: TVersion }>;\n\n/**\n * Defines one version of a package-owned input contract. Concrete validator\n * types are deliberately erased at this boundary: schema authors keep full\n * inference while public declarations expose only Standard Schema.\n *\n * A contract on its own cannot be provided to an app -- only\n * `datadogAppInputsDefinition()`'s output can -- so declaring a version is\n * never the same as offering to serve it.\n */\nexport function datadogAppInputsVersion<\n const TIdentifier extends string,\n const TVersion extends ContractVersion,\n const TFields extends Record<string, AnyField>,\n>(\n definition: Contract<TFields> &\n Readonly<{\n identifier: TIdentifier;\n version: TVersion;\n fields: ValidationOnlyFields<TFields>;\n }>,\n): PortableContract<TIdentifier, TVersion, TFields> {\n const contract = defineContract<TIdentifier, TVersion, TFields>(\n definition as unknown as Parameters<\n typeof defineContract<TIdentifier, TVersion, TFields>\n >[0],\n ) as unknown as PortableContract<TIdentifier, TVersion, TFields>;\n assertValidContract(contract);\n return contract;\n}\n\n/**\n * Publishes one package-owned inputs definition.\n *\n * The common case is one version, declared inline -- `identifier`, `version`,\n * `fields`, and optionally the `surfaces` it is offered on. A schema that has\n * to keep serving older versions instead passes `latest` plus `olderVersions`,\n * so the extra step is paid only where extra versions exist.\n *\n * Either way the result is the single unit both sides deal in: an app claims it\n * without naming a version, and a host provides it without learning that more\n * than one exists. Dropping an `olderVersion()` is how support for that version\n * ends, and simultaneously how the fields a host must supply get smaller.\n */\nexport function datadogAppInputsDefinition<\n const TIdentifier extends string,\n const TVersion extends ContractVersion,\n const TFields extends Record<string, AnyField>,\n const TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n>(\n // `Contract<TFields> &` is the inference site for `TFields`: TS cannot\n // recover it from the mapped `ValidationOnlyFields<TFields>` alone, and\n // silently widens to `Record<string, AnyField>` without this.\n definition: Contract<TFields> &\n Readonly<{\n identifier: TIdentifier;\n version: TVersion;\n fields: ValidationOnlyFields<TFields>;\n /** Surfaces this input is offered on \u2014 read at runtime by the host to gate which schemas are offered per surface. */\n surfaces?: TSurfaces;\n }>,\n): PublishedDatadogAppInputsDefinition<\n DatadogAppInputsSchema<\n PortableContract<TIdentifier, TVersion, TFields>,\n TSurfaces\n >\n>;\nexport function datadogAppInputsDefinition<\n TLatest extends AnyContract,\n const TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n const TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[] =\n readonly [],\n>(\n definition: Readonly<{\n latest: TLatest;\n surfaces?: TSurfaces;\n olderVersions?: TOlderVersions;\n }>,\n): PublishedDatadogAppInputsDefinition<\n DatadogAppInputsSchema<TLatest, TSurfaces, TOlderVersions>\n>;\nexport function datadogAppInputsDefinition(definitionInput: object): unknown {\n const definition = definitionInput as Readonly<Record<string, unknown>>;\n const latest =\n 'latest' in definition\n ? (definition.latest as AnyContract)\n : datadogAppInputsVersion(\n definition as unknown as Parameters<\n typeof datadogAppInputsVersion\n >[0],\n );\n const olderVersions = (definition.olderVersions ??\n []) as readonly AnyOlderContractVersion<AnyContract>[];\n assertValidContract(latest);\n for (const olderVersion of olderVersions) {\n assertValidContract(olderVersion.contract);\n assertValidExtraInputs(latest.identifier, olderVersion.extraInputs);\n }\n const schema = defineVersionedContract(latest, ...olderVersions);\n const published = Object.freeze({\n ...schema,\n surfaces: Object.freeze([\n ...((definition.surfaces as readonly SurfaceId[] | undefined) ??\n EVERY_SURFACE),\n ]),\n });\n publishedDefinitions.add(published);\n return published;\n}\n\n/** Rejects copied or user-authored definitions at the public React boundary. */\nexport function assertPublishedDatadogAppInputsDefinition(\n definition: unknown,\n): asserts definition is AnyPublishedDatadogAppInputsDefinition {\n if (\n typeof definition !== 'object' ||\n definition === null ||\n !publishedDefinitions.has(definition)\n ) {\n throw new Error(\n 'useDatadogAppInput() requires a definition exported by @datadog/apps-frontend/inputs/schema.',\n );\n }\n}\n\n/**\n * Reports whether a value is a definition created by `datadogAppInputsDefinition()`\n * (i.e. published through `@datadog/apps-frontend/inputs/schema`). Backed by the\n * same `WeakSet` brand as `assertPublishedDatadogAppInputsDefinition`, so it\n * cannot be spoofed by a duck-typed lookalike.\n */\nexport function isPublishedDatadogAppInputsDefinition(\n definition: unknown,\n): definition is PublishedDatadogAppInputsDefinition<AnyDatadogAppInputsSchema> {\n return (\n typeof definition === 'object' &&\n definition !== null &&\n publishedDefinitions.has(definition)\n );\n}\n\n/**\n * Turns one plain value into the field descriptor that carries it: a function\n * becomes a callable field with validated inputs and result, anything else a\n * read-only value field. This is the inverse of the erasure `value.readOnly()`\n * and `fn.readOnly()` perform, which is what lets a schema be *declared* in the\n * terms a consumer thinks in while being *built* from real validators.\n */\n// `[TValue] extends [...]` rather than a naked parameter: a naked one\n// distributes, so a union value like `'light' | 'dark'` would become a *union of\n// fields* instead of one field carrying a union.\ntype FieldFor<TValue> = [TValue] extends [\n (inputs: infer TInputs) => infer TResult,\n]\n ? FunctionField<\n { readonly [TName in keyof TInputs]: ValueSchema<TInputs[TName]> },\n ValueSchema<Awaited<TResult>>\n >\n : ValueField<ValueSchema<TValue>>;\n\ntype FieldsFor<TShape extends Readonly<Record<string, unknown>>> = {\n readonly [TName in keyof TShape]: FieldFor<TShape[TName]>;\n};\n\n/**\n * One Datadog App input, described the way it is used rather than the way it is\n * built: its identifier, the values a claim hands you, and the surfaces it is\n * offered on.\n *\n * This is the type a schema annotates itself with, so it is also what an editor\n * shows on hover. Versions are deliberately absent -- how many exist, and which\n * one a given peer gets, is settled by the package and is not a caller's\n * concern.\n *\n * @example\n * ```ts\n * DatadogAppInput<\n * 'datadog.idp.homepage',\n * { position: number; move: (inputs: { delta: number }) => number },\n * readonly ['datadog.idp.homepage']\n * >\n * ```\n */\nexport type DatadogAppInput<\n TIdentifier extends string,\n TShape extends Readonly<Record<string, unknown>>,\n TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n> = PublishedDatadogAppInputsDefinition<\n DatadogAppInputsSchema<\n Contract<FieldsFor<TShape>> &\n Readonly<{ identifier: TIdentifier; version: ContractVersion }>,\n TSurfaces\n >\n>;\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["EVERY_SURFACE", "toHostModule", "contract", "fields", "signal", "implementation", "rawFields", "name", "field", "createHostModule", "pickFields", "names", "picked", "isSameField", "left", "right", "leftNames", "rightNames", "mergeVersionedFields", "latest", "olderVersions", "merged", "older", "existing", "defineVersionedContract", "versions", "latestNames", "allFields", "flat", "latestImplementation", "modules", "derived", "publishedDefinitions", "CONTRACT_IDENTIFIER_PATTERN", "assertValidField", "contractIdentifier", "name", "field", "VALID_FIELD_NAME", "MAX_CLAIM_FIELD_NAME_LENGTH", "isAnyFieldShape", "inputName", "hasUsableFunctionTimeout", "assertValidContract", "contract", "isRecord", "MAX_CLAIM_FIELDS", "assertValidExtraInputs", "extraInputs", "value", "schema", "
|
|
4
|
+
"sourcesContent": ["import type { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport type Unsubscribe = () => void;\n\nexport type Result<TValue, TError> =\n | Readonly<{ ok: true; value: TValue }>\n | Readonly<{ ok: false; error: TError }>;\n\n/**\n * A synchronous, deterministic, validation-only Standard Schema.\n *\n * Both embedding peers validate independently. Schemas must therefore have\n * identical input/output types and must not coerce or transform accepted\n * values.\n */\nexport type ValueSchema<TValue> = StandardSchemaV1<TValue, TValue>;\n\nexport type AnySchema = StandardSchemaV1;\n\nexport type InferOf<TSchema extends AnySchema> =\n StandardSchemaV1.InferOutput<TSchema>;\n\nexport type ValidationOnlySchema<TSchema extends AnySchema> =\n StandardSchemaV1.InferInput<TSchema> extends StandardSchemaV1.InferOutput<TSchema>\n ? StandardSchemaV1.InferOutput<TSchema> extends StandardSchemaV1.InferInput<TSchema>\n ? TSchema\n : never\n : never;\n\nexport type ContractVersion = number;\n\nexport interface ValueField<TSchema extends AnySchema> {\n readonly kind: 'value';\n readonly schema: ValidationOnlySchema<TSchema>;\n}\n\nexport interface FunctionField<\n TInputs extends Readonly<Record<string, AnySchema>>,\n TResult extends AnySchema,\n> {\n readonly kind: 'function';\n readonly inputs: {\n readonly [TName in keyof TInputs]: ValidationOnlySchema<TInputs[TName]>;\n };\n readonly result: ValidationOnlySchema<TResult>;\n /**\n * How long this function may run before it times out, overriding the\n * default `FUNCTION_CALL_TIMEOUT_MS`. A fast lookup can ask for seconds\n * instead of inheriting a ten-minute budget.\n *\n * Never sent over the wire. The app arms its wait from the contract it\n * claims and the host arms its watchdog from the contract it registers, so\n * two peers on different contract revisions may use different numbers.\n * That needs no reconciling: whichever watchdog fires first wins through\n * the normal `TIMED_OUT` path, as it already did with the default alone.\n *\n * Must be positive and no larger than `MAX_TIMER_DELAY_MS`. Outside that\n * range no call could ever meet it -- at `0` the host's deadline checks are\n * already past, and beyond the timer ceiling `setTimeout` overflows and\n * fires almost at once -- so `defineContract()` rejects it outright.\n */\n readonly timeoutMs?: number;\n}\n\nexport type AnyFunctionField = FunctionField<\n Readonly<Record<string, AnySchema>>,\n AnySchema\n>;\n\nexport type AnyField = ValueField<AnySchema> | AnyFunctionField;\n\nexport interface Contract<TFields extends Record<string, AnyField>> {\n readonly identifier: string;\n readonly version: ContractVersion;\n readonly fields: TFields;\n}\n\nexport type AnyContract = Contract<Record<string, AnyField>>;\n\nexport interface LiveValue<TValue> {\n get(): TValue;\n subscribe(onChange: () => void): Unsubscribe;\n}\n\nexport interface HostFunctionContext {\n /**\n * Aborts once the call is cancelled or its deadline passes. An async\n * implementation should check or listen for this to stop early. A\n * *synchronous* implementation has no way to observe it mid-call: JS\n * can't preempt a running function, so a synchronous handler that blocks\n * past the deadline still runs to completion and produces its value --\n * the caller is simply told the call timed out and never sees that\n * value, rather than the value being prevented from being computed.\n */\n readonly signal: AbortSignal;\n}\n\nexport interface HostFunction {\n invoke(\n inputs: Readonly<Record<string, unknown>>,\n context: HostFunctionContext,\n ): unknown;\n}\n\nexport type FunctionInputs<\n TInputs extends Readonly<Record<string, AnySchema>>,\n> = {\n readonly [TName in keyof TInputs as undefined extends InferOf<\n TInputs[TName]\n >\n ? TName\n : never]?: InferOf<TInputs[TName]>;\n} & {\n readonly [TName in keyof TInputs as undefined extends InferOf<\n TInputs[TName]\n >\n ? never\n : TName]: InferOf<TInputs[TName]>;\n};\n\n/** Resolves a contract field to the plain value/callable shape a claimant receives, ignoring subscription. */\ntype FieldValue<TField extends AnyField> =\n TField extends ValueField<infer TSchema>\n ? InferOf<TSchema>\n : TField extends FunctionField<infer TInputs, infer TResult>\n ? (inputs: FunctionInputs<TInputs>) => Promise<InferOf<TResult>>\n : never;\n\ntype ClaimedField<TField extends AnyField> =\n TField extends ValueField<infer TSchema>\n ? LiveValue<InferOf<TSchema>>\n : FieldValue<TField>;\n\n/** The live, per-field view of a claim: subscribable `LiveValue`s for value fields, callables for function fields. */\nexport type ClaimedFields<TContract extends AnyContract> = {\n readonly [TKey in keyof TContract['fields']]: ClaimedField<\n TContract['fields'][TKey]\n >;\n};\n\ndeclare const hostModuleBrand: unique symbol;\n\n/**\n * One contract version, live and ready to serve claims. Nominally branded --\n * `hostModuleBrand` is declared but never exported, so only this package can\n * produce a `HostModule`, and only through `createHostModule()`. That is what\n * keeps a host from assembling a module for one hand-picked version: the\n * single supported way in is to provide an inputs definition, which mints a\n * module for *every* version that definition still converts to. The brand has\n * no runtime representation.\n */\nexport interface HostModule {\n readonly [hostModuleBrand]: true;\n readonly contract: AnyContract;\n readonly implementation: Readonly<\n Record<string, LiveValue<unknown> | HostFunction>\n >;\n readonly signal?: AbortSignal;\n}\n\nexport interface Issue {\n readonly message: string;\n readonly path: readonly (string | number)[];\n}\n\nexport type AnyError =\n | Readonly<{ code: 'ORIGIN_REJECTED'; origin: string }>\n | Readonly<{\n code: 'APP_PROTOCOL_TOO_OLD';\n appProtocols: readonly number[];\n hostProtocols: readonly number[];\n }>\n | Readonly<{\n code: 'HOST_PROTOCOL_TOO_OLD';\n appProtocols: readonly number[];\n hostProtocols: readonly number[];\n }>\n | Readonly<{\n code: 'PROTOCOL_INCOMPATIBLE';\n appProtocols: readonly number[];\n hostProtocols: readonly number[];\n }>\n | Readonly<{ code: 'PEER_LACKS_MODULE'; identifier: string }>\n | Readonly<{\n code: 'APP_MAJOR_TOO_OLD';\n wanted: ContractVersion;\n hostVersions: readonly ContractVersion[];\n }>\n | Readonly<{\n code: 'HOST_MAJOR_TOO_OLD';\n wanted: ContractVersion;\n hostVersions: readonly ContractVersion[];\n }>\n | Readonly<{ code: 'CONTRACT_INCOMPATIBLE'; field: string }>\n | Readonly<{ code: 'INVALID_ARGUMENT'; issues: readonly Issue[] }>\n | Readonly<{ code: 'FUNCTION_FAILED'; field: string }>\n | Readonly<{ code: 'INVALID_RESULT'; issues: readonly Issue[] }>\n | Readonly<{ code: 'TIMED_OUT'; timeoutMs: number }>\n | Readonly<{ code: 'TRANSPORT_FAILED'; cause: unknown }>\n | Readonly<{ code: 'ABORTED' }>\n | Readonly<{ code: 'DISCONNECTED' }>\n | Readonly<{ code: 'UNRECOGNIZED'; rawCode: string; raw: unknown }>;\n\nexport type ErrorOf<TCode extends AnyError['code']> = Extract<\n AnyError,\n { code: TCode }\n>;\n\nexport type ConnectError = ErrorOf<\n | 'ORIGIN_REJECTED'\n | 'APP_PROTOCOL_TOO_OLD'\n | 'HOST_PROTOCOL_TOO_OLD'\n | 'PROTOCOL_INCOMPATIBLE'\n | 'TIMED_OUT'\n | 'TRANSPORT_FAILED'\n | 'ABORTED'\n | 'DISCONNECTED'\n | 'UNRECOGNIZED'\n>;\n\nexport type WireClaimError = ErrorOf<\n | 'PEER_LACKS_MODULE'\n | 'APP_MAJOR_TOO_OLD'\n | 'HOST_MAJOR_TOO_OLD'\n | 'CONTRACT_INCOMPATIBLE'\n | 'INVALID_RESULT'\n | 'TIMED_OUT'\n | 'ABORTED'\n | 'DISCONNECTED'\n | 'UNRECOGNIZED'\n>;\n\nexport type WireFunctionError = ErrorOf<\n | 'CONTRACT_INCOMPATIBLE'\n | 'INVALID_ARGUMENT'\n | 'FUNCTION_FAILED'\n | 'INVALID_RESULT'\n | 'TIMED_OUT'\n | 'ABORTED'\n | 'DISCONNECTED'\n | 'UNRECOGNIZED'\n>;\n\nexport type ClaimInvalidationError = ErrorOf<\n 'INVALID_RESULT' | 'DISCONNECTED' | 'UNRECOGNIZED'\n>;\n\nexport interface Claimed<TContract extends AnyContract> {\n readonly fields: ClaimedFields<TContract>;\n release(): void;\n onValuesChanged(listener: () => void): Unsubscribe;\n onInvalidated(\n listener: (error: ClaimInvalidationError) => void,\n ): Unsubscribe;\n}\n\nexport interface ClaimOptions {\n /**\n * Local claim deadline. Must be finite, non-negative, and no larger than\n * the platform timer ceiling (`2_147_483_647`).\n */\n readonly timeoutMs?: number;\n readonly signal?: AbortSignal;\n}\n\nexport interface AppConnection {\n claim<TContract extends AnyContract>(\n contract: TContract,\n options?: ClaimOptions,\n ): Promise<Result<Claimed<TContract>, WireClaimError>>;\n}\n\n/**\n * Identifies which product surface a Datadog App is embedded into (e.g. the\n * Service Catalog side panel vs. IDP), so an app can render surface-specific\n * content. Each value matches the identifier of the schema that surface\n * provides. Sent host-to-app as part of the embedding connection handshake.\n */\n/**\n * Every surface, as a tuple rather than a bare union so it can also serve as a\n * type: `DatadogAppInputsSchema` defaults its `surfaces` to this, which makes\n * an IDE print the members in full on hover instead of collapsing them to the\n * `SurfaceId` alias.\n */\nexport const EVERY_SURFACE: readonly [\n 'datadog.idp.homepage',\n 'datadog.idp.service-panel',\n 'datadog.idp.self-service',\n 'datadog.app-builder',\n 'datadog.appsec',\n 'datadog.notebook',\n 'datadog.dashboard',\n] = [\n 'datadog.idp.homepage',\n 'datadog.idp.service-panel',\n 'datadog.idp.self-service',\n 'datadog.app-builder',\n 'datadog.appsec',\n 'datadog.notebook',\n 'datadog.dashboard',\n];\n\n/**\n * The static category of surface where an embedding session is running.\n * It is chosen when the connection is established and does not change in\n * place. Dynamic placement or parent/child relationships (for example, a\n * pinned app moving between containers) belong in separately versioned\n * module inputs rather than mutations to `surfaceId`.\n *\n * Derived from `EVERY_SURFACE`, so there is one list, but widened to arbitrary\n * strings: it is metadata forwarded to `listen()` and may be used by the host\n * to gate which input schemas are offered on a given surface, but it never\n * gates whether embedding connects \u2014 a host is free to pass a value with\n * no matching surface (e.g. an unmapped view context) rather than going\n * without one.\n */\nexport type SurfaceId = (typeof EVERY_SURFACE)[number] | (string & {});\n\nexport type AppConnectionState =\n | Readonly<{ state: 'connecting'; error?: ConnectError }>\n | Readonly<{\n state: 'connected';\n connection: AppConnection;\n surfaceId?: SurfaceId;\n }>\n | Readonly<{ state: 'reconnecting'; lastError: ConnectError }>\n | Readonly<{ state: 'rejected'; error: ConnectError }>\n | Readonly<{ state: 'not-embedded' }>\n | Readonly<{ state: 'closed' }>;\n\n/**\n * Public-safe view of `AppConnectionState`: the same lifecycle cases, minus\n * the raw `AppConnection` a consumer would otherwise have no use for outside\n * of claiming a contract.\n */\nexport type EmbeddingMetadata =\n | Readonly<{ state: 'connecting'; error?: ConnectError }>\n | Readonly<{ state: 'connected'; surfaceId?: SurfaceId }>\n | Readonly<{ state: 'reconnecting'; lastError: ConnectError }>\n | Readonly<{ state: 'rejected'; error: ConnectError }>\n | Readonly<{ state: 'not-embedded' }>\n | Readonly<{ state: 'closed' }>;\n\nexport interface EmbeddingMetadataStore {\n readonly getSnapshot: () => EmbeddingMetadata;\n readonly subscribe: (onChange: () => void) => Unsubscribe;\n}\n\nexport interface AppConnectionHandle {\n getSnapshot(): AppConnectionState;\n subscribe(onChange: () => void): Unsubscribe;\n close(): void;\n}\n\nexport interface AppConnectionFactory {\n connect(): AppConnectionHandle;\n}\n\nexport interface HostListenOptions {\n /** Security boundary for the app-created bootstrap port. */\n readonly peer: Readonly<{\n frame: HTMLIFrameElement;\n appOrigin: string;\n /**\n * Set when the iframe is intentionally configured with an opaque\n * sandboxed origin, so the host should accept a `\"null\"` origin from\n * it in place of an exact match against `appOrigin`.\n */\n allowOpaqueOrigin?: boolean;\n }>;\n readonly modules: readonly HostModule[];\n /** Static surface category for the lifetime of the established connection. */\n readonly surfaceId?: SurfaceId;\n /**\n * Local compatibility and establishment deadline for each phase. Must be\n * finite, non-negative, and no larger than the platform timer ceiling\n * (`2_147_483_647`).\n */\n readonly timeoutMs?: number;\n readonly signal?: AbortSignal;\n}\n\nexport interface HostListener {\n onError(listener: (error: ConnectError) => void): Unsubscribe;\n /**\n * Fires exactly once per successful operational session: after permanent\n * bootstrap and compatibility negotiation complete, before any\n * per-module claim resolves. Not a one-shot for the listener's whole\n * lifetime -- if this session is later superseded (a new bootstrap\n * replaces it, see `close()`'s effect on an active connection) and a new\n * session establishes, this fires again for that new session. Never\n * fires for an attempt that fails, or after `close()`. A subscriber that\n * calls `onReady` while a session is already active is notified\n * immediately upon subscribing, so a late subscriber cannot miss an\n * already-established session.\n */\n onReady(listener: () => void): Unsubscribe;\n close(): void;\n}\n\nexport type EmbeddingError =\n | Readonly<{ code: 'TIMED_OUT'; message: string; action: 'retry' }>\n | Readonly<{\n code: 'ORIGIN_REJECTED';\n message: string;\n action: 'contact-support';\n }>\n | Readonly<{\n code: 'APP_PROTOCOL_TOO_OLD';\n message: string;\n action: 'update-app';\n }>\n | Readonly<{\n code: 'HOST_PROTOCOL_TOO_OLD' | 'PROTOCOL_INCOMPATIBLE';\n message: string;\n action: 'contact-support';\n }>\n | Readonly<{\n code: 'CONNECTION_LOST';\n message: string;\n action: 'retry';\n }>\n | Readonly<{\n code: 'UNKNOWN';\n message: string;\n action: 'contact-support';\n }>;\n\nexport type ClaimError =\n | EmbeddingError\n | Readonly<{\n code: 'APP_MAJOR_TOO_OLD';\n action: 'update-app';\n requestedVersion: ContractVersion;\n availableVersions: readonly ContractVersion[];\n message: string;\n }>\n | Readonly<{\n code: 'HOST_MAJOR_TOO_OLD';\n action: 'contact-support';\n requestedVersion: ContractVersion;\n availableVersions: readonly ContractVersion[];\n message: string;\n }>;\n\nexport type ClaimedValues<TContract extends AnyContract> = Readonly<{\n [TKey in keyof TContract['fields']]: FieldValue<TContract['fields'][TKey]>;\n}>;\n\nexport type ClaimState<TContract extends AnyContract> =\n | Readonly<{ status: 'pending' }>\n | Readonly<{\n status: 'ready';\n fields: ClaimedValues<TContract>;\n }>\n | Readonly<{ status: 'unavailable' }>\n | Readonly<{ status: 'failed'; error: ClaimError }>;\n\nexport interface ClaimStore<TContract extends AnyContract> {\n readonly getSnapshot: () => ClaimState<TContract>;\n readonly subscribe: (onChange: () => void) => Unsubscribe;\n}\n\n/** Framework-neutral claim capability consumed by feature modules. */\nexport interface AppClaims {\n getClaim<TContract extends AnyContract>(\n contract: TContract,\n ): ClaimStore<TContract>;\n}\n\n/** Owns the lifecycle of one concrete embedding implementation. */\nexport interface AppEmbedding extends AppClaims {\n start(): Unsubscribe;\n getEmbeddingMetadata(): EmbeddingMetadataStore;\n}\n\n/**\n * One established connection, owned by the caller that opened it. These say\n * nothing about which operational protocol produced them, so the connection\n * lifecycle does not change when a protocol is added or retired.\n */\nexport type ManagedAppConnection = Readonly<{\n connection: AppConnection;\n surfaceId?: SurfaceId;\n closeSignal: AbortSignal;\n close(): void;\n}>;\n\nexport type ManagedHostConnection = Readonly<{\n closeSignal: AbortSignal;\n close(): void;\n}>;\n", "import { MAX_CLAIM_FIELD_NAME_LENGTH } from './config';\nimport {\n createHostModule,\n isAnyFieldShape,\n VALID_FIELD_NAME,\n} from './contract';\nimport { teardown } from './shared';\nimport type {\n AnyContract,\n AnyField,\n ContractVersion,\n FunctionField,\n FunctionInputs,\n HostFunction,\n HostFunctionContext,\n HostModule,\n InferOf,\n LiveValue,\n Unsubscribe,\n ValueField,\n} from './types';\n\ntype HostFieldImplementation<TField extends AnyField> =\n TField extends ValueField<infer TSchema>\n ? LiveValue<InferOf<TSchema>>\n : TField extends FunctionField<infer TInputs, infer TResult>\n ? (\n inputs: FunctionInputs<TInputs>,\n context: HostFunctionContext,\n ) => InferOf<TResult> | Promise<InferOf<TResult>>\n : never;\n\n/** The live host-side implementation of a raw field map: `LiveValue`s for value fields, plain callables for function fields. */\nexport type HostFieldsFor<TFields extends Record<string, AnyField>> = Readonly<{\n [TName in keyof TFields]: HostFieldImplementation<TFields[TName]>;\n}>;\n\n/** The live host-side implementation of a whole contract's fields. */\nexport type HostFields<TContract extends AnyContract> = HostFieldsFor<\n TContract['fields']\n>;\n\n/**\n * A `LiveValue` that recomputes from `sources` on every `get()` rather than\n * caching, so it always reflects whichever of `sources` last changed without\n * needing its own dedupe or disposal bookkeeping -- that already lives on\n * `sources` themselves.\n */\nexport function deriveLiveValue<TValue>(\n sources: readonly LiveValue<unknown>[],\n compute: () => TValue,\n): LiveValue<TValue> {\n return Object.freeze({\n get: compute,\n subscribe(onChange: () => void): Unsubscribe {\n // Acquired sequentially (not via `sources.map()`) so a later\n // source throwing rolls back every subscription already made.\n const unsubscribes: Unsubscribe[] = [];\n try {\n for (const source of sources) {\n unsubscribes.push(source.subscribe(onChange));\n }\n } catch (error) {\n for (const unsubscribe of unsubscribes) {\n teardown(\n 'deriveLiveValue subscription rollback',\n unsubscribe,\n );\n }\n throw error;\n }\n // Routed through `teardown()` so one throwing unsubscribe can't\n // skip the rest.\n return () => {\n for (const unsubscribe of unsubscribes) {\n teardown('deriveLiveValue unsubscribe', unsubscribe);\n }\n };\n },\n });\n}\n\n/**\n * One older version of `TLatest`: its own frozen contract, the extra live\n * inputs its `convert` needs beyond what `TLatest` already carries, and the\n * function that derives its fields from `TLatest` plus those extras. Runs\n * once, at `buildModules()` time, and must return live fields -- typically\n * built with `deriveLiveValue()` -- so the older version stays exactly as\n * reactive as `TLatest`, with `TLatest`'s own implementation untouched.\n */\nexport interface OlderContractVersion<\n TLatest extends AnyContract,\n TOlder extends AnyContract,\n TExtraInputs extends Record<string, AnyField>,\n> {\n readonly contract: TOlder;\n readonly extraInputs: TExtraInputs;\n convert(\n latest: HostFields<TLatest>,\n extra: HostFieldsFor<TExtraInputs>,\n ): HostFields<TOlder>;\n}\n\nexport type AnyOlderContractVersion<TLatest extends AnyContract> =\n OlderContractVersion<TLatest, AnyContract, Record<string, AnyField>>;\n\n/**\n * Declares and validates one `OlderContractVersion`. Takes `latest` as its\n * own argument -- rather than only through `definition.convert`'s parameter\n * type -- so `TLatest` can be inferred directly from a value in covariant\n * position; inference can't otherwise recover it from `convert`'s parameter,\n * a contravariant position, and silently falls back to `AnyContract`.\n */\nexport function olderVersion<\n TLatest extends AnyContract,\n TOlder extends AnyContract,\n const TExtraInputs extends Record<string, AnyField>,\n>(\n _latest: TLatest,\n definition: OlderContractVersion<TLatest, TOlder, TExtraInputs>,\n): OlderContractVersion<TLatest, TOlder, TExtraInputs> {\n for (const [name, field] of Object.entries(definition.extraInputs)) {\n if (\n !VALID_FIELD_NAME.test(name) ||\n name.length > MAX_CLAIM_FIELD_NAME_LENGTH ||\n !isAnyFieldShape(field)\n ) {\n throw new Error(\n `Older-version extra input \"${definition.contract.identifier}.${name}\" must be a named read-only value or function whose schemas implement Standard Schema V1.`,\n );\n }\n }\n return Object.freeze({\n contract: definition.contract,\n extraInputs: Object.freeze({ ...definition.extraInputs }),\n convert: definition.convert,\n });\n}\n\nexport interface VersionedContract<\n TLatest extends AnyContract,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n> {\n readonly identifier: TLatest['identifier'];\n /**\n * The version an up-to-date peer claims. Read by the claiming side to\n * know what it is asking for; never a way to *provide* one version alone,\n * since `buildModules()` is all-or-nothing.\n */\n readonly latest: TLatest;\n readonly olderVersions: TOlderVersions;\n /**\n * `X`: every field needed to serve every version, in one flat namespace.\n * A provider populates exactly this and learns nothing about how many\n * versions sit behind it.\n */\n readonly fields: VersionedContractFields<TLatest, TOlderVersions>;\n /**\n * Mints one live module per version -- latest plus every version that\n * still has a converter -- from one flat field record. There is\n * deliberately no way to ask for a subset: supporting a version and\n * serving it are the same act.\n */\n buildModules(\n fields: HostFieldsFor<VersionedContractFields<TLatest, TOlderVersions>>,\n signal?: AbortSignal,\n ): readonly HostModule[];\n}\n\n/**\n * Structural bound for \"some versioned contract\", used where generic code\n * needs to accept any of them. Deliberately forgetful about `buildModules`'s\n * parameter and about `olderVersions`' element type: both are contravariant,\n * so naming them would make every concrete contract fail to satisfy this.\n * Callers recover the precise field types from the generic parameter itself\n * (see `DatadogAppInputImplementations`), not from this bound.\n */\nexport type AnyVersionedContract = Readonly<{\n identifier: string;\n latest: AnyContract;\n olderVersions: readonly unknown[];\n fields: Readonly<Record<string, AnyField>>;\n buildModules: (\n fields: never,\n signal?: AbortSignal,\n ) => readonly HostModule[];\n}>;\n\nexport type UnionToIntersection<TUnion> = (\n TUnion extends unknown ? (key: TUnion) => void : never\n) extends (key: infer TIntersection) => void\n ? TIntersection\n : never;\n\ntype OlderVersionsExtraFieldsUnion<\n TLatest extends AnyContract,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n> = {\n [TIndex in keyof TOlderVersions]: TOlderVersions[TIndex] extends OlderContractVersion<\n TLatest,\n AnyContract,\n infer TExtraInputs\n >\n ? TExtraInputs\n : never;\n}[number];\n\n/**\n * Every field needed to construct every version this contract declares,\n * flattened into one namespace: `latest`'s own fields plus each older\n * version's `extraInputs`. This is `giving` values' whole contract with\n * versioning -- a caller populates this one flat record with no notion that\n * more than one version exists behind it. Field names must therefore be\n * unique across `latest` and every older version's `extraInputs`; two older\n * versions may reuse the same name only when it means the same schema, since\n * flattening gives it exactly one slot.\n */\nexport type VersionedContractFields<\n TLatest extends AnyContract,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n> =\n OlderVersionsExtraFieldsUnion<TLatest, TOlderVersions> extends never\n ? TLatest['fields']\n : TLatest['fields'] &\n UnionToIntersection<\n OlderVersionsExtraFieldsUnion<TLatest, TOlderVersions>\n >;\n\nfunction toHostModule<TContract extends AnyContract>(\n contract: TContract,\n fields: HostFields<TContract>,\n signal: AbortSignal | undefined,\n): HostModule {\n // Null-prototype as defence in depth. `olderVersion` already rejects an\n // extra input named \"__proto__\" via `VALID_FIELD_NAME`, so no such name\n // should reach here; a plain `{}` would silently drop it through the\n // legacy setter rather than defining an own property if one ever did.\n const implementation: Record<string, LiveValue<unknown> | HostFunction> =\n Object.create(null);\n const rawFields: Record<string, unknown> = fields;\n for (const [name, field] of Object.entries(contract.fields)) {\n implementation[name] =\n field.kind === 'value'\n ? (rawFields[name] as LiveValue<unknown>)\n : Object.freeze({\n invoke: rawFields[name] as HostFunction['invoke'],\n });\n }\n return createHostModule(contract, Object.freeze(implementation), signal);\n}\n\n/** Narrows a flat field record to the names one version actually reads. */\nfunction pickFields(\n fields: Readonly<Record<string, unknown>>,\n names: readonly string[],\n): Readonly<Record<string, unknown>> {\n // Null-prototype for the same defence-in-depth reason as `toHostModule`\n // above: `names` can include an older version's extra-input name, which\n // `olderVersion` already shape-checks with `VALID_FIELD_NAME`.\n const picked: Record<string, unknown> = Object.create(null);\n for (const name of names) {\n picked[name] = fields[name];\n }\n return picked;\n}\n\n/**\n * Whether two versions asking for the same field name mean the same thing.\n * Flattening gives a name exactly one slot, so a disagreement has to be an\n * authoring error rather than something a provider could satisfy twice.\n */\nfunction isSameField(left: AnyField, right: AnyField): boolean {\n if (left.kind !== right.kind) {\n return false;\n }\n if (left.kind === 'value' && right.kind === 'value') {\n return left.schema === right.schema;\n }\n if (left.kind === 'function' && right.kind === 'function') {\n const leftNames = Object.keys(left.inputs);\n const rightNames = Object.keys(right.inputs);\n // Deliberately does not compare `timeoutMs`. This check exists so one\n // provider implementation can serve every version sharing a flattened\n // slot, which a mismatched schema or input name would prevent. A\n // deadline cannot prevent it: the flattened descriptor is only used to\n // type the provider record and to slice it by name, and `buildModules`\n // hands each version `toHostModule(older.contract, ...)`, so every\n // deadline is resolved from that version's own contract field. Two\n // versions reusing one extra-input name may declare different\n // deadlines with no runtime consequence whatsoever.\n return !(\n leftNames.length !== rightNames.length ||\n left.result !== right.result ||\n leftNames.some(\n (name) =>\n !Object.prototype.hasOwnProperty.call(right.inputs, name) ||\n left.inputs[name] !== right.inputs[name],\n )\n );\n }\n return false;\n}\n\n/**\n * Flattens `latest`'s own fields together with every older version's extra\n * inputs into the one namespace a provider populates, rejecting the two ways\n * that flattening can go wrong: an extra input that shadows a real field of\n * `latest`, and two older versions claiming one name for different schemas.\n */\nfunction mergeVersionedFields<TLatest extends AnyContract>(\n latest: TLatest,\n olderVersions: readonly AnyOlderContractVersion<TLatest>[],\n): Readonly<Record<string, AnyField>> {\n // Null-prototype as defence in depth: `VALID_FIELD_NAME` already excludes\n // an extra input named \"__proto__\", but were one to reach here it must\n // become an own property rather than invoke the inherited legacy setter\n // and silently repoint `merged`'s prototype.\n const merged: Record<string, AnyField> = Object.create(null);\n for (const [name, field] of Object.entries(latest.fields)) {\n merged[name] = field;\n }\n for (const older of olderVersions) {\n for (const [name, field] of Object.entries(older.extraInputs)) {\n if (Object.prototype.hasOwnProperty.call(latest.fields, name)) {\n throw new Error(\n `\"${latest.identifier}\" v${older.contract.version} declares extra input \"${name}\", which already names a field of v${latest.version}.`,\n );\n }\n const existing = Object.prototype.hasOwnProperty.call(merged, name)\n ? merged[name]\n : undefined;\n if (existing && !isSameField(existing, field)) {\n throw new Error(\n `\"${latest.identifier}\" extra input \"${name}\" is declared with conflicting schemas by more than one older version.`,\n );\n }\n merged[name] = field;\n }\n }\n return Object.freeze(merged);\n}\n\n/**\n * Ties a latest contract to any number of older versions it stays willing to\n * serve. `buildModules()` derives each older version's fields from the\n * latest implementation plus that version's own extra inputs and returns one\n * independent, fully live `HostModule` per version -- ready to hand to a\n * host listener alongside modules for any other contract.\n */\nexport function defineVersionedContract<\n TLatest extends AnyContract,\n const TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[],\n>(\n latest: TLatest,\n ...olderVersions: TOlderVersions\n): VersionedContract<TLatest, TOlderVersions> {\n const versions = new Set<ContractVersion>([latest.version]);\n for (const older of olderVersions) {\n if (older.contract.identifier !== latest.identifier) {\n throw new Error(\n `Older version \"${older.contract.identifier}\" v${older.contract.version} must share identifier \"${latest.identifier}\" with its latest contract.`,\n );\n }\n if (older.contract.version >= latest.version) {\n throw new Error(\n `Older version \"${latest.identifier}\" v${older.contract.version} must be older than latest v${latest.version}.`,\n );\n }\n if (versions.has(older.contract.version)) {\n throw new Error(\n `\"${latest.identifier}\" declares version ${older.contract.version} more than once.`,\n );\n }\n versions.add(older.contract.version);\n }\n\n const fields = mergeVersionedFields(latest, olderVersions);\n const latestNames = Object.keys(latest.fields);\n\n return Object.freeze({\n identifier: latest.identifier,\n latest,\n // `Object.freeze` on the returned object is shallow: exposing the\n // validated array by reference would let a caller mutate it (push,\n // sort, splice) after the fact despite the wrapper looking frozen.\n olderVersions: Object.freeze([...olderVersions]) as TOlderVersions,\n fields: fields as VersionedContractFields<TLatest, TOlderVersions>,\n buildModules(\n allFields: HostFieldsFor<\n VersionedContractFields<TLatest, TOlderVersions>\n >,\n signal?: AbortSignal,\n ): readonly HostModule[] {\n const flat: Readonly<Record<string, unknown>> = allFields;\n // Slicing by each version's own field names is what lets two\n // versions share one slot: both reads hit the same live value.\n const latestImplementation = pickFields(\n flat,\n latestNames,\n ) as HostFields<TLatest>;\n const modules: HostModule[] = [\n toHostModule(latest, latestImplementation, signal),\n ];\n for (const older of olderVersions) {\n const derived = older.convert(\n latestImplementation,\n pickFields(\n flat,\n Object.keys(older.extraInputs),\n ) as HostFieldsFor<Record<string, AnyField>>,\n );\n modules.push(toHostModule(older.contract, derived, signal));\n }\n return Object.freeze(modules);\n },\n });\n}\n", "import {\n MAX_CLAIM_FIELD_NAME_LENGTH,\n MAX_CLAIM_FIELDS,\n MAX_TIMER_DELAY_MS,\n} from '../embedding/config';\nimport {\n defineContract,\n fn as defineFunctionField,\n hasUsableFunctionTimeout,\n isAnyFieldShape,\n VALID_FIELD_NAME,\n value as defineValueField,\n} from '../embedding/contract';\nimport { isRecord } from '../embedding/shared';\nimport { EVERY_SURFACE } from '../embedding/types';\nimport type {\n AnyContract,\n AnyField,\n AnySchema,\n Contract,\n ContractVersion,\n FunctionField,\n InferOf,\n SurfaceId,\n ValidationOnlySchema,\n ValueField,\n ValueSchema,\n} from '../embedding/types';\nimport { defineVersionedContract } from '../embedding/versioning';\nimport type {\n AnyOlderContractVersion,\n AnyVersionedContract,\n VersionedContract,\n} from '../embedding/versioning';\n\ndeclare const publishedDefinitionBrand: unique symbol;\n\n/**\n * One published inputs definition: every version it serves, and the surfaces\n * it is offered on.\n *\n * `surfaces` is read at runtime by `datadogAppHostInputsFor` to gate which\n * schemas a host offers on a given surface \u2014 a dashboard-only schema is not\n * offered on IDP even if a synthetic `dashboard` field is present in the\n * inputs bag. Omitted resolves to every `SurfaceId`, so the hint reads as\n * \"available everywhere\" rather than as an empty list.\n */\nexport type DatadogAppInputsSchema<\n TLatest extends AnyContract,\n TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[] =\n readonly [],\n> = VersionedContract<TLatest, TOlderVersions> &\n Readonly<{ surfaces: TSurfaces }>;\n\nexport type AnyDatadogAppInputsSchema = AnyVersionedContract &\n Readonly<{ surfaces: readonly SurfaceId[] }>;\n\nexport type PublishedDatadogAppInputsDefinition<\n TSchema extends AnyDatadogAppInputsSchema,\n> = TSchema &\n Readonly<{\n [publishedDefinitionBrand]: (\n fields: TSchema['latest']['fields'],\n ) => TSchema['latest']['fields'];\n }>;\n\n/** A package-owned definition whose concrete, deliberately invariant fields are unknown. */\nexport type AnyPublishedDatadogAppInputsDefinition = AnyDatadogAppInputsSchema &\n Readonly<{ [publishedDefinitionBrand]: unknown }>;\n\n/**\n * Selected-public-version descriptor. Its exported object/API and declaration\n * omit host construction and retained-version operations; this is not a\n * transitive-source or bundle-secrecy boundary.\n */\nexport type PublishedDatadogAppInput<\n TCurrent extends AnyContract,\n TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n> = Readonly<{\n identifier: TCurrent['identifier'];\n latest: TCurrent;\n fields: TCurrent['fields'];\n surfaces: TSurfaces;\n [publishedDefinitionBrand]: (\n fields: TCurrent['fields'],\n ) => TCurrent['fields'];\n}>;\n\n/** The common claimable shape shared by package-owned host and consumer definitions. */\nexport type AnyPublishedDatadogAppInput = Readonly<{\n identifier: string;\n latest: AnyContract;\n fields: Readonly<Record<string, AnyField>>;\n surfaces: readonly SurfaceId[];\n [publishedDefinitionBrand]: unknown;\n}>;\n\nconst publishedDefinitions = new WeakSet<object>();\n\ntype PortableSchema<TSchema extends AnySchema> = ValueSchema<InferOf<TSchema>>;\n\nconst CONTRACT_IDENTIFIER_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/;\n\nfunction assertValidField(\n contractIdentifier: string,\n name: string,\n field: unknown,\n): asserts field is AnyField {\n if (\n !VALID_FIELD_NAME.test(name) ||\n name.length > MAX_CLAIM_FIELD_NAME_LENGTH ||\n !isAnyFieldShape(field)\n ) {\n throw new Error(\n `Datadog App input field \"${contractIdentifier}.${name}\" must have a name matching ${String(VALID_FIELD_NAME)} of at most ${MAX_CLAIM_FIELD_NAME_LENGTH} characters and be a read-only value or function whose schemas implement Standard Schema V1.`,\n );\n }\n if (field.kind === 'function') {\n for (const inputName of Object.keys(field.inputs)) {\n if (!VALID_FIELD_NAME.test(inputName)) {\n throw new Error(\n `Datadog App input function parameter \"${contractIdentifier}.${name}.${inputName}\" must have a name matching ${String(VALID_FIELD_NAME)}.`,\n );\n }\n }\n if (!hasUsableFunctionTimeout(field)) {\n throw new Error(\n `Datadog App input function field \"${contractIdentifier}.${name}\" declares a timeoutMs no call could meet. It must be greater than 0 and at most ${MAX_TIMER_DELAY_MS}.`,\n );\n }\n }\n}\n\nfunction assertValidContract(\n contract: unknown,\n): asserts contract is AnyContract {\n if (\n !isRecord(contract) ||\n typeof contract.identifier !== 'string' ||\n !CONTRACT_IDENTIFIER_PATTERN.test(contract.identifier)\n ) {\n throw new Error(\n `Datadog App input contract identifier \"${String(isRecord(contract) ? contract.identifier : undefined)}\" must match ${String(CONTRACT_IDENTIFIER_PATTERN)}.`,\n );\n }\n if (\n typeof contract.version !== 'number' ||\n !Number.isSafeInteger(contract.version) ||\n contract.version < 1\n ) {\n throw new Error(\n `Datadog App input contract \"${contract.identifier}\" must have a positive integer version.`,\n );\n }\n if (\n !isRecord(contract.fields) ||\n Object.keys(contract.fields).length === 0 ||\n Object.keys(contract.fields).length > MAX_CLAIM_FIELDS\n ) {\n throw new Error(\n `Datadog App input contract \"${contract.identifier}\" must define between 1 and ${MAX_CLAIM_FIELDS} fields.`,\n );\n }\n for (const [name, field] of Object.entries(contract.fields)) {\n assertValidField(contract.identifier, name, field);\n }\n}\n\nfunction assertValidExtraInputs(\n contractIdentifier: string,\n extraInputs: unknown,\n): void {\n if (!isRecord(extraInputs)) {\n throw new Error(\n `Older Datadog App input contract \"${contractIdentifier}\" must declare its extra inputs as an object.`,\n );\n }\n for (const [name, field] of Object.entries(extraInputs)) {\n assertValidField(contractIdentifier, name, field);\n }\n}\n\ninterface PortableValueBuilder {\n readOnly<TSchema extends AnySchema>(\n schema: ValidationOnlySchema<TSchema>,\n ): ValueField<PortableSchema<TSchema>>;\n}\n\ninterface PortableFunctionBuilder {\n readOnly<\n const TInputs extends Readonly<Record<string, AnySchema>>,\n TResult extends AnySchema,\n >(\n definition: Readonly<{\n inputs: TInputs & {\n readonly [TName in keyof TInputs]: ValidationOnlySchema<\n TInputs[TName]\n >;\n };\n result: ValidationOnlySchema<TResult>;\n /**\n * Optional per-function override of `FUNCTION_CALL_TIMEOUT_MS`.\n * See `FunctionField.timeoutMs`.\n */\n timeoutMs?: number;\n }>,\n ): FunctionField<\n {\n readonly [TName in keyof TInputs]: PortableSchema<TInputs[TName]>;\n },\n PortableSchema<TResult>\n >;\n}\n\n/** Builds an input value field while hiding its concrete validator type. */\nexport const value: PortableValueBuilder = /* @__PURE__ */ Object.freeze({\n readOnly<TSchema extends AnySchema>(\n schema: ValidationOnlySchema<TSchema>,\n ): ValueField<PortableSchema<TSchema>> {\n return defineValueField.readOnly(schema) as unknown as ValueField<\n PortableSchema<TSchema>\n >;\n },\n});\n\n/** Builds an input function field while hiding its concrete validator types. */\nexport const fn: PortableFunctionBuilder = /* @__PURE__ */ Object.freeze({\n readOnly<\n const TInputs extends Readonly<Record<string, AnySchema>>,\n TResult extends AnySchema,\n >(\n definition: Readonly<{\n inputs: TInputs & {\n readonly [TName in keyof TInputs]: ValidationOnlySchema<\n TInputs[TName]\n >;\n };\n result: ValidationOnlySchema<TResult>;\n timeoutMs?: number;\n }>,\n ): FunctionField<\n {\n readonly [TName in keyof TInputs]: PortableSchema<TInputs[TName]>;\n },\n PortableSchema<TResult>\n > {\n return defineFunctionField.readOnly(\n definition,\n ) as unknown as FunctionField<\n {\n readonly [TName in keyof TInputs]: PortableSchema<\n TInputs[TName]\n >;\n },\n PortableSchema<TResult>\n >;\n },\n});\n\ntype ValidationOnlyFields<TFields extends Record<string, AnyField>> = {\n readonly [TName in keyof TFields]: TFields[TName] extends ValueField<\n infer TSchema\n >\n ? ValueField<ValidationOnlySchema<TSchema>>\n : TFields[TName] extends FunctionField<infer TInputs, infer TResult>\n ? FunctionField<\n {\n readonly [TInputName in keyof TInputs]: ValidationOnlySchema<\n TInputs[TInputName]\n >;\n },\n ValidationOnlySchema<TResult>\n >\n : never;\n};\n\ntype PortableFields<TFields extends Record<string, AnyField>> = {\n readonly [TName in keyof TFields]: TFields[TName] extends ValueField<\n infer TSchema\n >\n ? ValueField<PortableSchema<TSchema>>\n : TFields[TName] extends FunctionField<infer TInputs, infer TResult>\n ? FunctionField<\n {\n readonly [TInputName in keyof TInputs]: PortableSchema<\n TInputs[TInputName]\n >;\n },\n PortableSchema<TResult>\n >\n : never;\n};\n\nexport type PortableContract<\n TIdentifier extends string,\n TVersion extends ContractVersion,\n TFields extends Record<string, AnyField>,\n> = Contract<PortableFields<TFields>> &\n Readonly<{ identifier: TIdentifier; version: TVersion }>;\n\n/**\n * Defines one version of a package-owned input contract. Concrete validator\n * types are deliberately erased at this boundary: schema authors keep full\n * inference while public declarations expose only Standard Schema.\n *\n * A contract on its own cannot be provided to an app -- only\n * `datadogAppInputsDefinition()`'s output can -- so declaring a version is\n * never the same as offering to serve it.\n */\nexport function datadogAppInputsVersion<\n const TIdentifier extends string,\n const TVersion extends ContractVersion,\n const TFields extends Record<string, AnyField>,\n>(\n definition: Contract<TFields> &\n Readonly<{\n identifier: TIdentifier;\n version: TVersion;\n fields: ValidationOnlyFields<TFields>;\n }>,\n): PortableContract<TIdentifier, TVersion, TFields> {\n const contract = defineContract<TIdentifier, TVersion, TFields>(\n definition as unknown as Parameters<\n typeof defineContract<TIdentifier, TVersion, TFields>\n >[0],\n ) as unknown as PortableContract<TIdentifier, TVersion, TFields>;\n assertValidContract(contract);\n return contract;\n}\n\n/**\n * Builds one package-owned versioned host definition. Schema publication\n * separately chooses which served version the public SDK descriptor exposes.\n *\n * The common case is one version, declared inline -- `identifier`, `version`,\n * `fields`, and optionally the `surfaces` it is offered on. A schema that has\n * to keep serving older versions instead passes `latest` plus `olderVersions`,\n * so the extra step is paid only where extra versions exist.\n *\n * Either way the result is the single unit both sides deal in: an app claims it\n * without naming a version, and a host provides it without learning that more\n * than one exists. Dropping an `olderVersion()` is how support for that version\n * ends, and simultaneously how the fields a host must supply get smaller.\n */\nexport function datadogAppInputsDefinition<\n const TIdentifier extends string,\n const TVersion extends ContractVersion,\n const TFields extends Record<string, AnyField>,\n const TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n>(\n // `Contract<TFields> &` is the inference site for `TFields`: TS cannot\n // recover it from the mapped `ValidationOnlyFields<TFields>` alone, and\n // silently widens to `Record<string, AnyField>` without this.\n definition: Contract<TFields> &\n Readonly<{\n identifier: TIdentifier;\n version: TVersion;\n fields: ValidationOnlyFields<TFields>;\n /** Surfaces this input is offered on \u2014 read at runtime by the host to gate which schemas are offered per surface. */\n surfaces?: TSurfaces;\n }>,\n): PublishedDatadogAppInputsDefinition<\n DatadogAppInputsSchema<\n PortableContract<TIdentifier, TVersion, TFields>,\n TSurfaces\n >\n>;\nexport function datadogAppInputsDefinition<\n TLatest extends AnyContract,\n const TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n const TOlderVersions extends readonly AnyOlderContractVersion<TLatest>[] =\n readonly [],\n>(\n definition: Readonly<{\n latest: TLatest;\n surfaces?: TSurfaces;\n olderVersions?: TOlderVersions;\n }>,\n): PublishedDatadogAppInputsDefinition<\n DatadogAppInputsSchema<TLatest, TSurfaces, TOlderVersions>\n>;\nexport function datadogAppInputsDefinition(definitionInput: object): unknown {\n const definition = definitionInput as Readonly<Record<string, unknown>>;\n const latest =\n 'latest' in definition\n ? (definition.latest as AnyContract)\n : datadogAppInputsVersion(\n definition as unknown as Parameters<\n typeof datadogAppInputsVersion\n >[0],\n );\n const olderVersions = (definition.olderVersions ??\n []) as readonly AnyOlderContractVersion<AnyContract>[];\n assertValidContract(latest);\n for (const olderVersion of olderVersions) {\n assertValidContract(olderVersion.contract);\n assertValidExtraInputs(latest.identifier, olderVersion.extraInputs);\n }\n const schema = defineVersionedContract(latest, ...olderVersions);\n const published = Object.freeze({\n ...schema,\n surfaces: Object.freeze([\n ...((definition.surfaces as readonly SurfaceId[] | undefined) ??\n EVERY_SURFACE),\n ]),\n });\n publishedDefinitions.add(published);\n return published;\n}\n\ntype ServedContract<\n TDefinition extends AnyPublishedDatadogAppInputsDefinition,\n> =\n | TDefinition['latest']\n | Extract<\n TDefinition['olderVersions'][number],\n { readonly contract: AnyContract }\n >['contract'];\n\n/**\n * Creates a selected-public-version descriptor for a contract the host serves.\n * The boundary is its exported object/API and declaration, not transitive\n * source dependencies or bundle secrecy.\n */\nexport function createDatadogAppInputConsumer<\n TDefinition extends AnyPublishedDatadogAppInputsDefinition,\n>(\n definition: TDefinition,\n): PublishedDatadogAppInput<TDefinition['latest'], TDefinition['surfaces']>;\nexport function createDatadogAppInputConsumer<\n TDefinition extends AnyPublishedDatadogAppInputsDefinition,\n TContract extends ServedContract<TDefinition>,\n>(\n definition: TDefinition,\n contract: TContract,\n): PublishedDatadogAppInput<TContract, TDefinition['surfaces']>;\nexport function createDatadogAppInputConsumer(\n definition: AnyPublishedDatadogAppInputsDefinition,\n contract: AnyContract = definition.latest,\n): AnyPublishedDatadogAppInput {\n assertPublishedDatadogAppInputsDefinition(definition);\n if (\n contract !== definition.latest &&\n !definition.olderVersions.some(\n (version) => isRecord(version) && version.contract === contract,\n )\n ) {\n throw new Error(\n 'The consumer contract must be a version served by its host definition.',\n );\n }\n const consumer = Object.freeze({\n identifier: definition.identifier,\n latest: contract,\n fields: contract.fields,\n surfaces: definition.surfaces,\n });\n publishedDefinitions.add(consumer);\n return consumer as AnyPublishedDatadogAppInput;\n}\n\n/** Rejects copied or user-authored definitions at the public React boundary. */\nexport function assertPublishedDatadogAppInputsDefinition(\n definition: unknown,\n): asserts definition is AnyPublishedDatadogAppInput {\n if (\n typeof definition !== 'object' ||\n definition === null ||\n !publishedDefinitions.has(definition)\n ) {\n throw new Error(\n 'useDatadogAppInput() requires a definition exported by @datadog/apps-frontend/inputs/schema.',\n );\n }\n}\n\n/**\n * Reports whether a value is a package-created host definition or consumer\n * descriptor. This ownership brand does not decide public SDK publication or\n * authorization. It uses the same `WeakSet` as\n * `assertPublishedDatadogAppInputsDefinition`, so a copied lookalike does not match.\n */\nexport function isPublishedDatadogAppInputsDefinition(\n definition: unknown,\n): definition is AnyPublishedDatadogAppInput {\n return (\n typeof definition === 'object' &&\n definition !== null &&\n publishedDefinitions.has(definition)\n );\n}\n\n/**\n * Turns one plain value into the field descriptor that carries it: a function\n * becomes a callable field with validated inputs and result, anything else a\n * read-only value field. This is the inverse of the erasure `value.readOnly()`\n * and `fn.readOnly()` perform, which is what lets a schema be *declared* in the\n * terms a consumer thinks in while being *built* from real validators.\n */\n// `[TValue] extends [...]` rather than a naked parameter: a naked one\n// distributes, so a union value like `'light' | 'dark'` would become a *union of\n// fields* instead of one field carrying a union.\ntype FieldFor<TValue> = [TValue] extends [\n (inputs: infer TInputs) => infer TResult,\n]\n ? FunctionField<\n { readonly [TName in keyof TInputs]: ValueSchema<TInputs[TName]> },\n ValueSchema<Awaited<TResult>>\n >\n : ValueField<ValueSchema<TValue>>;\n\ntype FieldsFor<TShape extends Readonly<Record<string, unknown>>> = {\n readonly [TName in keyof TShape]: FieldFor<TShape[TName]>;\n};\n\n/**\n * One Datadog App input, described the way it is used rather than the way it is\n * built: its identifier, the values a claim hands you, and the surfaces it is\n * offered on.\n *\n * This is the type a schema annotates itself with, so it is also what an editor\n * shows on hover. Versions are deliberately absent -- how many exist, and which\n * one a given peer gets, is settled by the package and is not a caller's\n * concern.\n *\n * @example\n * ```ts\n * DatadogAppInput<\n * 'datadog.idp.homepage',\n * { position: number; move: (inputs: { delta: number }) => number },\n * readonly ['datadog.idp.homepage']\n * >\n * ```\n */\nexport type DatadogAppInput<\n TIdentifier extends string,\n TShape extends Readonly<Record<string, unknown>>,\n TSurfaces extends readonly SurfaceId[] = typeof EVERY_SURFACE,\n> = PublishedDatadogAppInputsDefinition<\n DatadogAppInputsSchema<\n Contract<FieldsFor<TShape>> &\n Readonly<{ identifier: TIdentifier; version: ContractVersion }>,\n TSurfaces\n >\n>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["EVERY_SURFACE", "toHostModule", "contract", "fields", "signal", "implementation", "rawFields", "name", "field", "createHostModule", "pickFields", "names", "picked", "isSameField", "left", "right", "leftNames", "rightNames", "mergeVersionedFields", "latest", "olderVersions", "merged", "older", "existing", "defineVersionedContract", "versions", "latestNames", "allFields", "flat", "latestImplementation", "modules", "derived", "publishedDefinitions", "CONTRACT_IDENTIFIER_PATTERN", "assertValidField", "contractIdentifier", "name", "field", "VALID_FIELD_NAME", "MAX_CLAIM_FIELD_NAME_LENGTH", "isAnyFieldShape", "inputName", "hasUsableFunctionTimeout", "assertValidContract", "contract", "isRecord", "MAX_CLAIM_FIELDS", "assertValidExtraInputs", "extraInputs", "value", "schema", "fn", "definition", "datadogAppInputsVersion", "defineContract", "datadogAppInputsDefinition", "definitionInput", "latest", "olderVersions", "olderVersion", "defineVersionedContract", "published", "EVERY_SURFACE", "createDatadogAppInputConsumer", "assertPublishedDatadogAppInputsDefinition", "version", "consumer"]
|
|
7
7
|
}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Copyright 2019-Present Datadog, Inc.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import{d as i}from"./chunk-2V2HASKF.js";import{
|
|
7
|
-
//# sourceMappingURL=chunk-
|
|
6
|
+
import{d as i}from"./chunk-2V2HASKF.js";import{f as n}from"./chunk-OEPH347K.js";import{useSyncExternalStore as a}from"react";function o(t){let p=i();n(t);let e=p.getClaim(t.latest);return a(e.subscribe,e.getSnapshot,e.getSnapshot)}function d(t){return o(t)}export{d as a};
|
|
7
|
+
//# sourceMappingURL=chunk-XSHCFEOH.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/inputs/react/use-package-datadog-app-input.ts", "../../../src/inputs/react/use-datadog-app-input.ts"],
|
|
4
|
+
"sourcesContent": ["import { useSyncExternalStore } from 'react';\n\nimport { useAppEmbedding } from '../../embedding/react/context';\nimport type { ClaimState } from '../../embedding/types';\nimport type { AnyPublishedDatadogAppInput } from '../published-definition';\nimport { assertPublishedDatadogAppInputsDefinition } from '../published-definition';\n\n/** Claims a package-owned definition that is absent from the public schema barrel. */\nexport function usePackageDatadogAppInput<\n TDefinition extends AnyPublishedDatadogAppInput,\n>(definition: TDefinition): ClaimState<TDefinition['latest']> {\n const embedding = useAppEmbedding();\n assertPublishedDatadogAppInputsDefinition(definition);\n const store = embedding.getClaim<TDefinition['latest']>(definition.latest);\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n", "import type { ClaimState } from '../../embedding/types';\nimport type { DatadogAppInputDefinition } from '../schemas/index';\n\nimport { usePackageDatadogAppInput } from './use-package-datadog-app-input';\n\n/**\n * What {@link useDatadogAppInput} gives back for one input: `pending` while the\n * connection or claim is in flight, `ready` with validated `fields`, `unavailable`\n * when this host does not provide the input, or `failed` with an actionable\n * `error`. `fields` exists only on `ready`, so stale values can never be read as\n * live.\n *\n * Named in terms of the input rather than the contract behind it -- which\n * version is being served is not a caller's concern.\n */\nexport type DatadogAppInputState<\n TDefinition extends DatadogAppInputDefinition,\n> = ClaimState<TDefinition['latest']>;\n\n/**\n * A type that refuses to match while saying why.\n *\n * A compiler error is the one piece of documentation a caller cannot skip, so\n * rejections here resolve to a sentence rather than to a bare `never` -- the\n * message becomes the error text, at the call site, in the editor.\n */\ntype Rejected<TMessage extends string> = Readonly<{\n __datadogAppInputsError: TMessage;\n}>;\n\ntype PublishedDefinitionFor<TDefinition extends DatadogAppInputDefinition> =\n Extract<\n DatadogAppInputDefinition,\n Readonly<{ identifier: TDefinition['identifier'] }>\n >;\n\ntype NoExtraFields<TDefinition extends DatadogAppInputDefinition> =\n Exclude<\n keyof TDefinition['latest']['fields'],\n keyof PublishedDefinitionFor<TDefinition>['latest']['fields']\n > extends never\n ? unknown\n : Rejected<'This definition has fields the published one does not. Pass a definition exported from @datadog/apps-frontend/inputs/schema, unmodified.'>;\n\n/**\n * Claims one Datadog App input and tracks its state across renders. Call it\n * below {@link DatadogAppProvider}.\n *\n * Pass a definition exported from `@datadog/apps-frontend/inputs/schema` --\n * {@link datadogTheme} is one. Hovering a definition shows the surfaces it is\n * offered on; the returned {@link ClaimState} says whether its values are usable\n * yet, and carries `fields` only while they are.\n *\n * Versions are not a caller's concern: this claims whichever version the\n * installed copy of the package treats as latest. An older copy asks for an\n * older version and keeps working for as long as the host still converts to it.\n * Past that the claim fails with `APP_MAJOR_TOO_OLD` -- update this package and\n * re-upload the app -- rather than silently degrading.\n *\n * @param definition An input definition from `@datadog/apps-frontend/inputs/schema`.\n * @returns The claim's current state: `pending`, `ready` (with `fields`),\n * `unavailable` when this host does not provide the input, or `failed` with an\n * actionable `error`.\n */\nexport function useDatadogAppInput<\n const TDefinition extends DatadogAppInputDefinition,\n>(\n definition: TDefinition & NoExtraFields<TDefinition>,\n): DatadogAppInputState<TDefinition> {\n return usePackageDatadogAppInput<TDefinition>(definition);\n}\n"],
|
|
5
|
+
"mappings": "gFAAA,OAAS,wBAAAA,MAA4B,QAQ9B,SAASC,EAEdC,EAA4D,CAC1D,IAAMC,EAAYC,EAAgB,EAClCC,EAA0CH,CAAU,EACpD,IAAMI,EAAQH,EAAU,SAAgCD,EAAW,MAAM,EACzE,OAAOK,EACHD,EAAM,UACNA,EAAM,YACNA,EAAM,WACV,CACJ,CC6CO,SAASE,EAGZC,EACiC,CACjC,OAAOC,EAAuCD,CAAU,CAC5D",
|
|
6
|
+
"names": ["useSyncExternalStore", "usePackageDatadogAppInput", "definition", "embedding", "useAppEmbedding", "assertPublishedDatadogAppInputsDefinition", "store", "useSyncExternalStore", "useDatadogAppInput", "definition", "usePackageDatadogAppInput"]
|
|
7
|
+
}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Copyright 2019-Present Datadog, Inc.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import{b as a}from"../../_chunks/chunk-
|
|
6
|
+
import{b as a}from"../../_chunks/chunk-D43RPVCF.js";import"../../_chunks/chunk-EYBITW7J.js";import"../../_chunks/chunk-LEEYMNMO.js";export{a as datadogAppDeepLinks};
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Copyright 2019-Present Datadog, Inc.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import{a as r}from"../../_chunks/chunk-
|
|
6
|
+
import{a as r}from"../../_chunks/chunk-XSHCFEOH.js";import"../../_chunks/chunk-2V2HASKF.js";import{a as t}from"../../_chunks/chunk-DETZPDFA.js";import"../../_chunks/chunk-EYBITW7J.js";import"../../_chunks/chunk-OEPH347K.js";import"../../_chunks/chunk-LEEYMNMO.js";import{DruidsEnvironment as i}from"@datadog/druids/layout/DruidsEnvironment";import{createElement as s}from"react";function u(n){let{defaultThemePreference:m,...o}=n,e=r(t),p=e.status==="ready"?e.fields.theme:m;return s(i,{...o,defaultThemePreference:p})}export{u as DruidsEnvironmentWithThemeInput};
|
|
7
7
|
//# sourceMappingURL=index.js.map
|