@salesforce/platform-sdk 11.64.0 → 11.66.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/extension-attach.d.ts +56 -0
- package/dist/core/extension-attach.d.ts.map +1 -0
- package/dist/core/{plugin-factory.d.ts → extension-factory.d.ts} +16 -16
- package/dist/core/extension-factory.d.ts.map +1 -0
- package/dist/core/extension-types.d.ts +231 -0
- package/dist/core/extension-types.d.ts.map +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +5 -5
- package/dist/data/extensions/index.d.ts +19 -0
- package/dist/data/extensions/index.d.ts.map +1 -0
- package/dist/data/{plugins → extensions}/index.js +12 -12
- package/dist/data/{plugins → extensions}/labels/index.d.ts +18 -18
- package/dist/data/extensions/labels/index.d.ts.map +1 -0
- package/dist/data/{plugins → extensions}/labels/query.d.ts +1 -1
- package/dist/data/extensions/labels/query.d.ts.map +1 -0
- package/dist/data/index.d.ts +35 -27
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +158 -153
- package/dist/data/shared/graphql/cache/services.d.ts +7 -7
- package/dist/data/shared/graphql/cache/services.d.ts.map +1 -1
- package/dist/data/webapp/index.d.ts.map +1 -1
- package/dist/{plugin-factory-BC3b3BOy.js → extension-factory-CJkfM4km.js} +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -21
- package/package.json +8 -8
- package/dist/core/plugin-attach.d.ts +0 -46
- package/dist/core/plugin-attach.d.ts.map +0 -1
- package/dist/core/plugin-factory.d.ts.map +0 -1
- package/dist/core/plugin-types.d.ts +0 -208
- package/dist/core/plugin-types.d.ts.map +0 -1
- package/dist/data/plugins/index.d.ts +0 -19
- package/dist/data/plugins/index.d.ts.map +0 -1
- package/dist/data/plugins/labels/index.d.ts.map +0 -1
- package/dist/data/plugins/labels/query.d.ts.map +0 -1
- package/dist/data/reserved.d.ts +0 -3
- package/dist/data/reserved.d.ts.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ExtendedSDK, ExtensionsFor } from './extension-types';
|
|
2
|
+
/**
|
|
3
|
+
* Run each extension's `setup` in array order and mount the returned namespace
|
|
4
|
+
* into the SDK's `ext` container under the entry's effective mount name — its
|
|
5
|
+
* `name`, or its `as` alias when the entry is `{ extension, as }`. `setup` may be
|
|
6
|
+
* sync or async; each is `await`ed before the next runs, so the ordering is
|
|
7
|
+
* deterministic.
|
|
8
|
+
*
|
|
9
|
+
* Compartmentalized under `ext`: every extension namespace mounts on `sdk.ext`
|
|
10
|
+
* (e.g. `sdk.ext.labels`), never as a sibling of the base surface's own members
|
|
11
|
+
* (`graphql`/`fetch`). This is the design decision that removes name
|
|
12
|
+
* reservation entirely — a extension key lives one level down from the SDK
|
|
13
|
+
* surface, so it can never shadow a current or future SDK member, and there is
|
|
14
|
+
* no set of names to declare off-limits. The only collision left is
|
|
15
|
+
* extension-vs-extension *within* `ext`, which still throws.
|
|
16
|
+
*
|
|
17
|
+
* Aliasing rebinds only the mount key: `setup` still runs on the underlying
|
|
18
|
+
* extension, so two extensions that both declare `name: "labels"` can attach under
|
|
19
|
+
* distinct keys (`{ extension: a, as: "x" }`, `{ extension: b, as: "y" }`). See
|
|
20
|
+
* {@link resolveEntry} for the bare-vs-aliased narrowing and the loud guard
|
|
21
|
+
* against a malformed entry from untyped JavaScript.
|
|
22
|
+
*
|
|
23
|
+
* Each `setup` receives the base SDK, and that is all the type promises it:
|
|
24
|
+
* `setup(sdk)` is typed as `Base`, never the accumulating shape. Because every
|
|
25
|
+
* namespace mounts onto one shared `ext` object (below) attached before the
|
|
26
|
+
* loop, a later extension *can* reach an earlier extension's namespace at runtime via
|
|
27
|
+
* `sdk.ext.<name>` — but that reachability is an untyped byproduct, not a WI-1
|
|
28
|
+
* contract to build on. Typed cross-extension access (a extension declaring the
|
|
29
|
+
* namespaces it needs and receiving them in `setup`) is WI-3, via the reserved
|
|
30
|
+
* `Deps` seam on {@link Extension}; until then, author setups as independent.
|
|
31
|
+
*
|
|
32
|
+
* Atomic and non-mutating: namespaces mount onto a fresh `ext` object hung off
|
|
33
|
+
* a fresh SDK view whose prototype is `base`, so the base's own and inherited
|
|
34
|
+
* members resolve through the prototype chain (and `instanceof` still holds)
|
|
35
|
+
* while `base` itself is never written to. If any `setup` throws, the
|
|
36
|
+
* half-built view is simply discarded and `base` is left pristine — there is
|
|
37
|
+
* nothing to roll back. This keeps attach safe against a memoized/shared
|
|
38
|
+
* instance (e.g. the chat/view singletons WI-4 introduces): each attach derives
|
|
39
|
+
* its own object, so a repeat attach can never collide with a prior one. The
|
|
40
|
+
* empty-extension case returns the base instance unchanged — no `ext` key — so
|
|
41
|
+
* `ExtendedSDK<Base, []>` stays structurally `Base`.
|
|
42
|
+
*
|
|
43
|
+
* SDK-agnostic: `Base` is inferred from the passed instance, and `extensions` is
|
|
44
|
+
* constrained to {@link ExtensionsFor}<Base> so only extensions compatible with this
|
|
45
|
+
* base type may attach. The returned type is {@link ExtendedSDK}<Base, Extensions>
|
|
46
|
+
* — the base plus an `ext` namespace carrying each extension's resolved API.
|
|
47
|
+
*
|
|
48
|
+
* Fail-loud: a base already declaring `ext` (the reserved container key), a
|
|
49
|
+
* malformed entry (no `setup`, or a non-string/empty mount name), a mount name
|
|
50
|
+
* already claimed by another extension in this call, or a `setup` that throws or
|
|
51
|
+
* rejects surfaces as an error (the extension cases name the extension and chain
|
|
52
|
+
* the cause). The `ext` slot is locked, so a `setup` reassigning the container
|
|
53
|
+
* wholesale throws rather than silently dropping every namespace.
|
|
54
|
+
*/
|
|
55
|
+
export declare function attachExtensions<Base extends object, const Extensions extends ExtensionsFor<Base>>(base: Base, extensions: Extensions): Promise<ExtendedSDK<Base, Extensions>>;
|
|
56
|
+
//# sourceMappingURL=extension-attach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-attach.d.ts","sourceRoot":"","sources":["../../src/core/extension-attach.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAoB,WAAW,EAAa,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA4CjG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAsB,gBAAgB,CACrC,IAAI,SAAS,MAAM,EACnB,KAAK,CAAC,UAAU,SAAS,aAAa,CAAC,IAAI,CAAC,EAC3C,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAoF5E"}
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { LiteralName,
|
|
1
|
+
import { LiteralName, Extension } from './extension-types';
|
|
2
2
|
/**
|
|
3
|
-
* Bind a
|
|
4
|
-
* `setup`'s parameter. `
|
|
5
|
-
* and returns a definer; each call to that definer infers only the
|
|
3
|
+
* Bind a extension authoring helper to one SDK surface, so authors never annotate
|
|
4
|
+
* `setup`'s parameter. `createExtensionFactory<Sdk>()` captures the base SDK once
|
|
5
|
+
* and returns a definer; each call to that definer infers only the extension's
|
|
6
6
|
* literal `Name` and its `Api`, with `setup(sdk)` already typed as `Sdk`:
|
|
7
7
|
*
|
|
8
8
|
* ```ts
|
|
9
|
-
* const
|
|
10
|
-
* const labels =
|
|
9
|
+
* const defineDataExtension = createExtensionFactory<DataSDK>();
|
|
10
|
+
* const labels = defineDataExtension({ name: "labels", setup: (sdk) => ({ ... }) });
|
|
11
11
|
* ```
|
|
12
12
|
*
|
|
13
|
-
* `createDataSDK` exposes the DataSDK-bound definer as `
|
|
13
|
+
* `createDataSDK` exposes the DataSDK-bound definer as `defineDataExtension`. This
|
|
14
14
|
* factory is also the public escape hatch for a surface with no first-party
|
|
15
15
|
* definer yet, or for an author's own SDK.
|
|
16
16
|
*
|
|
17
|
-
* ## Why a curried factory, and not a single `
|
|
17
|
+
* ## Why a curried factory, and not a single `defineExtension<Sdk, Name, Api>`?
|
|
18
18
|
*
|
|
19
19
|
* The obvious alternative is one generic function whose caller fixes the SDK:
|
|
20
|
-
* `
|
|
20
|
+
* `defineExtension<DataSDK>({ name, setup })`. TypeScript does not allow it —
|
|
21
21
|
* type-argument lists are all-or-nothing per call, so supplying `Sdk` forces
|
|
22
22
|
* you to also supply `Name` and `Api` (`Expected 3 type arguments, but got 1`),
|
|
23
23
|
* which throws away the very inference that makes the helper worth using. That
|
|
24
24
|
* leaves only one way to keep `Sdk` implicit at the value call: annotate the
|
|
25
|
-
* parameter (`setup: (sdk: DataSDK) => ...`) on every
|
|
25
|
+
* parameter (`setup: (sdk: DataSDK) => ...`) on every extension. And a *forgotten*
|
|
26
26
|
* annotation does not error — it silently infers `Sdk = unknown`, a
|
|
27
|
-
* universally-attachable binding that slips a surface-specific
|
|
28
|
-
* per-surface {@link
|
|
27
|
+
* universally-attachable binding that slips a surface-specific extension past the
|
|
28
|
+
* per-surface {@link ExtensionsFor} guard.
|
|
29
29
|
*
|
|
30
30
|
* Currying dodges both problems. The outer call takes `Sdk` as its only type
|
|
31
31
|
* argument and no value arguments, so nothing forces `Name`/`Api` to be spelled
|
|
32
|
-
* out; the inner call infers those from the
|
|
33
|
-
* any
|
|
32
|
+
* out; the inner call infers those from the extension object. `Sdk` is fixed before
|
|
33
|
+
* any extension is written, so it can be neither forgotten nor widened — the
|
|
34
34
|
* footgun is designed out rather than documented around.
|
|
35
35
|
*
|
|
36
36
|
* The returned definer is identity at runtime. It carries the {@link LiteralName}
|
|
@@ -38,5 +38,5 @@ import { LiteralName, Plugin } from './plugin-types';
|
|
|
38
38
|
* concrete literal there is no key to accumulate onto the extended SDK, so
|
|
39
39
|
* failing loud here beats a silently dropped namespace downstream.
|
|
40
40
|
*/
|
|
41
|
-
export declare function
|
|
42
|
-
//# sourceMappingURL=
|
|
41
|
+
export declare function createExtensionFactory<Sdk>(): <const Name extends string, Api>(extension: Extension<Sdk, LiteralName<Name>, Api>) => Extension<Sdk, Name, Api>;
|
|
42
|
+
//# sourceMappingURL=extension-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-factory.d.ts","sourceRoot":"","sources":["../../src/core/extension-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,MACT,KAAK,CAAC,IAAI,SAAS,MAAM,EAAE,GAAG,EAC7D,WAAW,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,KAC/C,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAG5B"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A extension: a named namespace factory bound to a base SDK instance at attach
|
|
8
|
+
* time. SDK-agnostic — `Sdk` is the base type this extension's `setup` requires.
|
|
9
|
+
*
|
|
10
|
+
* The contract does not depend on any concrete SDK. Enforcement of a specific
|
|
11
|
+
* SDK happens at attach time via {@link ExtensionsFor}: a extension is attachable to
|
|
12
|
+
* a base `B` only where `B` is assignable to `Sdk`. So authoring
|
|
13
|
+
* `setup(sdk: DataSDK)` type-checks the extension against DataSDK when it is
|
|
14
|
+
* attached through `createDataSDK`, even though `Extension` itself never imports
|
|
15
|
+
* DataSDK.
|
|
16
|
+
*
|
|
17
|
+
* Reserved — `Deps` (inert in WI-1): the trailing type parameter is the seam
|
|
18
|
+
* for WI-3 extension dependencies. It defaults to `[]` and is referenced only
|
|
19
|
+
* through `setup`'s parameter, as `Sdk & Accumulate<Deps>`. With the default
|
|
20
|
+
* empty tuple `Accumulate<[]>` is `unknown`, and `Sdk & unknown` reduces to
|
|
21
|
+
* `Sdk`, so `setup` sees exactly the base SDK — a three-argument
|
|
22
|
+
* `Extension<Sdk, Name, Api>` (see {@link AnyExtension}, {@link ExtensionsFor}) is
|
|
23
|
+
* unchanged and no WI-1 extension's type shifts. There is no `deps` field yet, so
|
|
24
|
+
* `attach` has no dependency to honor or silently drop.
|
|
25
|
+
*
|
|
26
|
+
* Threading it through `setup` (rather than leaving it dangling) is deliberate:
|
|
27
|
+
* an unreferenced reserved type parameter is not free — it trips
|
|
28
|
+
* `noUnusedLocals`. This makes the slot load-bearing while behaviorally a
|
|
29
|
+
* no-op. WI-3's add-back is then a pure superset: add a `deps?: Deps` field and
|
|
30
|
+
* populate the tuple, and the already-wired `setup` view lights up. The spike
|
|
31
|
+
* notes the superset holds with or without this slot, so it is kept as an
|
|
32
|
+
* explicit intent marker, not a forward-compat necessity.
|
|
33
|
+
*/
|
|
34
|
+
export interface Extension<Sdk, Name extends string, Api, Deps extends readonly AnyExtension[] = []> {
|
|
35
|
+
/** The single namespace key this extension mounts under (e.g. "labels"). */
|
|
36
|
+
name: Name;
|
|
37
|
+
/**
|
|
38
|
+
* Build the extension API. Runs at attach time with the fully-resolved,
|
|
39
|
+
* instance-bound base SDK. May be synchronous or async — return the API
|
|
40
|
+
* directly, or a promise of it (e.g. to `await` a dynamic import or a
|
|
41
|
+
* capability handshake). The resolved `Api` is what mounts under `name`.
|
|
42
|
+
*
|
|
43
|
+
* `sdk` is `Sdk & Accumulate<Deps>`; with the reserved `Deps = []` this is
|
|
44
|
+
* just `Sdk` today (see the `Deps` note above). WI-3 populates `Deps` so a
|
|
45
|
+
* extension's declared dependencies' namespaces appear here.
|
|
46
|
+
*/
|
|
47
|
+
setup: (sdk: Sdk & Accumulate<Deps>) => Api | PromiseLike<Api>;
|
|
48
|
+
}
|
|
49
|
+
/** True iff `T` is a union of two or more members. */
|
|
50
|
+
type IsUnion<T, U = T> = T extends unknown ? ([U] extends [T] ? false : true) : never;
|
|
51
|
+
/**
|
|
52
|
+
* Reject a `name` that is not a single string literal. A concrete literal
|
|
53
|
+
* (`"labels"`) passes through unchanged; anything else collapses to `never`, so
|
|
54
|
+
* the authoring helpers error at definition time rather than silently losing key
|
|
55
|
+
* accumulation. See {@link createExtensionFactory}.
|
|
56
|
+
*
|
|
57
|
+
* Two shapes are rejected, both of which would otherwise mount phantom keys:
|
|
58
|
+
* - a widened `string` (`string extends Name`) — no literal key to accumulate;
|
|
59
|
+
* - a union literal (`"a" | "b"`, e.g. from `name: cond ? "a" : "b"`) — this
|
|
60
|
+
* survives the `string extends Name` check, but {@link Accumulate}
|
|
61
|
+
* distributes over the union and types *both* `a` and `b` as present,
|
|
62
|
+
* non-optional members while `attach` mounts only one, leaving the other
|
|
63
|
+
* typed-present yet `undefined` at runtime. Requiring a single literal is
|
|
64
|
+
* what keeps the accumulated key set sound.
|
|
65
|
+
*/
|
|
66
|
+
export type LiteralName<Name extends string> = string extends Name ? never : IsUnion<Name> extends true ? never : Name;
|
|
67
|
+
/**
|
|
68
|
+
* Any extension, for use in constraints. `never` in the (contravariant) `Sdk`
|
|
69
|
+
* slot makes every concrete `Extension<...>` assignable to this — it is the top
|
|
70
|
+
* type over the SDK parameter.
|
|
71
|
+
*/
|
|
72
|
+
export type AnyExtension = Extension<never, string, unknown>;
|
|
73
|
+
/**
|
|
74
|
+
* Rebind a extension's mount point: attach `extension` under `as` instead of its own
|
|
75
|
+
* `name`. This is the consumer's recourse for a collision they didn't cause —
|
|
76
|
+
* two uneditable third-party extensions that both mount `sdk.ext.labels` can each be
|
|
77
|
+
* aliased to a distinct key. Aliasing rebinds the mount *key* only, never the
|
|
78
|
+
* extension's identity, which is what keeps identity-based dependency resolution
|
|
79
|
+
* (a later WI) robust to it.
|
|
80
|
+
*
|
|
81
|
+
* `As` is intentionally the raw alias literal, NOT `LiteralName<As>`: pinning
|
|
82
|
+
* `LiteralName` here would collapse the constraint form `AliasedExtension<_,
|
|
83
|
+
* string>` (used in {@link ExtensionsFor}) to `as: never` and reject every alias.
|
|
84
|
+
* The widened/union-`as` guard is instead applied at the call boundary by
|
|
85
|
+
* {@link ValidAliasNames}, exactly as {@link UniqueExtensionNames} guards mount
|
|
86
|
+
* uniqueness there — the entry type stays permissive; the boundary validates.
|
|
87
|
+
*
|
|
88
|
+
* `name?: never; setup?: never` reject the mixed shape structurally, mirroring
|
|
89
|
+
* the runtime discriminator. An object carrying a bare extension's defining
|
|
90
|
+
* members *and* `{ extension, as }` satisfies both arms of {@link ExtensionEntry};
|
|
91
|
+
* without these guards {@link MountName} (which tests the aliased arm first)
|
|
92
|
+
* would key it under `as`, while `attach` — discriminating on `"setup" in
|
|
93
|
+
* entry` — mounts the bare extension under `name`. The `never` fields fail the
|
|
94
|
+
* aliased arm for such an object, so it matches only {@link Extension} and both
|
|
95
|
+
* sides agree on `name`. Unlike the `LiteralName` case above, these are fixed
|
|
96
|
+
* optional-never fields independent of `P`/`As`, so a real `{ extension, as }`
|
|
97
|
+
* entry (which omits them) leaves the `ExtensionsFor` constraint form intact.
|
|
98
|
+
*/
|
|
99
|
+
export interface AliasedExtension<P extends AnyExtension, As extends string> {
|
|
100
|
+
extension: P;
|
|
101
|
+
as: As;
|
|
102
|
+
name?: never;
|
|
103
|
+
setup?: never;
|
|
104
|
+
}
|
|
105
|
+
/** Any aliased entry, for use in unions/constraints (cf. {@link AnyExtension}). */
|
|
106
|
+
type AnyAliasedExtension = AliasedExtension<AnyExtension, string>;
|
|
107
|
+
/**
|
|
108
|
+
* The `extensions: []` array constraint that enforces a concrete base SDK. A bare
|
|
109
|
+
* `Extension<Sdk, Name, Api>` — or an {@link AliasedExtension} wrapping one — is a
|
|
110
|
+
* member iff a `Base` value is assignable to the (inner) extension's `setup`
|
|
111
|
+
* parameter, i.e. the extension asks for no more than `Base` provides (a extension
|
|
112
|
+
* that ignores the SDK, `Sdk = unknown`, is universally attachable).
|
|
113
|
+
* `createDataSDK` binds `Base = DataSDK`; that is where DataSDK-specific
|
|
114
|
+
* enforcement occurs.
|
|
115
|
+
*/
|
|
116
|
+
export type ExtensionsFor<Base> = readonly (Extension<Base, string, unknown> | AliasedExtension<Extension<Base, string, unknown>, string>)[];
|
|
117
|
+
/**
|
|
118
|
+
* What may appear in the `extensions: []` array: a bare extension, or a bare extension
|
|
119
|
+
* wrapped with an `{ as }` alias. Everything downstream ({@link Accumulate},
|
|
120
|
+
* {@link DuplicateMountName}, {@link ExtendedSDK}) is written against
|
|
121
|
+
* `ExtensionEntry` and routes through {@link ExtensionOf}/{@link MountName}, so the
|
|
122
|
+
* bare-vs-aliased distinction is resolved in exactly those two helpers and
|
|
123
|
+
* nowhere else.
|
|
124
|
+
*/
|
|
125
|
+
export type ExtensionEntry = AnyExtension | AnyAliasedExtension;
|
|
126
|
+
/** The underlying extension of an entry, whether it was passed bare or aliased. */
|
|
127
|
+
type ExtensionOf<E extends ExtensionEntry> = E extends AnyAliasedExtension ? E["extension"] : E;
|
|
128
|
+
/**
|
|
129
|
+
* The literal key an entry mounts under: its alias `as` when aliased, else the
|
|
130
|
+
* extension's own `name`. This is the single place the effective mount key is
|
|
131
|
+
* computed — all mount-name-keyed logic ({@link Accumulate},
|
|
132
|
+
* {@link DuplicateMountName}) routes through it, so aliasing is transparent to
|
|
133
|
+
* them: `[a, a]` (both mount `"labels"`) collides, but `[{ extension: a, as: "x"
|
|
134
|
+
* }, { extension: a, as: "y" }]` resolves to distinct keys and does not.
|
|
135
|
+
*/
|
|
136
|
+
type MountName<E extends ExtensionEntry> = E extends AnyAliasedExtension ? E["as"] : ExtensionOf<E>["name"];
|
|
137
|
+
/**
|
|
138
|
+
* The resolved API an entry's extension `setup` returns. `Awaited` unwraps the
|
|
139
|
+
* async case so the mounted namespace is the settled value, never a promise.
|
|
140
|
+
*/
|
|
141
|
+
type ApiOf<E extends ExtensionEntry> = Awaited<ReturnType<ExtensionOf<E>["setup"]>>;
|
|
142
|
+
/**
|
|
143
|
+
* Walk the extension tuple left→right, intersecting `{ [name]: namespace }` per
|
|
144
|
+
* entry. Namespaces are non-optional: presence is a static attach fact.
|
|
145
|
+
*
|
|
146
|
+
* This intersects unconditionally: a duplicate mount name would collapse to
|
|
147
|
+
* `{ labels: A } & { labels: B }` here rather than erroring. Uniqueness is not
|
|
148
|
+
* this type's job — it is enforced up front by {@link UniqueExtensionNames} at the
|
|
149
|
+
* authoring boundary, with `attach`'s runtime guard as the backstop for tuples
|
|
150
|
+
* built dynamically past the static check.
|
|
151
|
+
*/
|
|
152
|
+
type Accumulate<Extensions extends readonly ExtensionEntry[]> = Extensions extends readonly [
|
|
153
|
+
infer Head extends ExtensionEntry,
|
|
154
|
+
...infer Tail extends readonly ExtensionEntry[]
|
|
155
|
+
] ? {
|
|
156
|
+
[K in MountName<Head>]: ApiOf<Head>;
|
|
157
|
+
} & Accumulate<Tail> : unknown;
|
|
158
|
+
/**
|
|
159
|
+
* The first mount name that repeats in the tuple, or `never` if all are
|
|
160
|
+
* distinct. Walks left→right accumulating seen names in `Seen`; the first
|
|
161
|
+
* {@link MountName} already in `Seen` is the duplicate. Keyed on
|
|
162
|
+
* {@link MountName}, so aliasing a clash apart is a valid recourse (see there).
|
|
163
|
+
*/
|
|
164
|
+
type DuplicateMountName<Extensions extends readonly ExtensionEntry[], Seen = never> = Extensions extends readonly [
|
|
165
|
+
infer Head extends ExtensionEntry,
|
|
166
|
+
...infer Tail extends readonly ExtensionEntry[]
|
|
167
|
+
] ? [MountName<Head>] extends [Seen] ? MountName<Head> : DuplicateMountName<Tail, Seen | MountName<Head>> : never;
|
|
168
|
+
/**
|
|
169
|
+
* A constraint intersected into the `extensions` option to reject a tuple whose
|
|
170
|
+
* mount names are not unique. Resolves to `unknown` (a no-op intersection) when
|
|
171
|
+
* every mount name is distinct; otherwise to an object whose `extensions` field is
|
|
172
|
+
* a human-readable error string, which makes the supplied array inassignable
|
|
173
|
+
* and surfaces the message in the diagnostic.
|
|
174
|
+
*
|
|
175
|
+
* This moves the collision from a runtime throw (`attach` fail-loud) to a
|
|
176
|
+
* compile error at the call site. The two are complementary, not redundant:
|
|
177
|
+
* this catches statically-known tuples early with a clear message, while
|
|
178
|
+
* `attach` still guards tuples assembled dynamically (e.g. `[...a, ...b]`)
|
|
179
|
+
* whose duplicates a static check cannot see.
|
|
180
|
+
*/
|
|
181
|
+
export type UniqueExtensionNames<Extensions extends readonly ExtensionEntry[]> = [
|
|
182
|
+
DuplicateMountName<Extensions>
|
|
183
|
+
] extends [never] ? unknown : {
|
|
184
|
+
extensions: `Two extensions mount under "${DuplicateMountName<Extensions> & string}"; mount names must be unique.`;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* A constraint intersected into the `extensions` option to reject an aliased entry
|
|
188
|
+
* whose `as` is not a single string literal — the same soundness bar
|
|
189
|
+
* {@link LiteralName} applies to a extension's `name` (see there for why a widened
|
|
190
|
+
* or union `as` would mount a phantom namespace). Applied at the boundary rather
|
|
191
|
+
* than on {@link AliasedExtension} for the reason that type documents. Resolves to
|
|
192
|
+
* `unknown` or an inassignable `{ extensions }` error exactly as
|
|
193
|
+
* {@link UniqueExtensionNames} does.
|
|
194
|
+
*/
|
|
195
|
+
export type ValidAliasNames<Extensions extends readonly ExtensionEntry[]> = Extensions extends readonly [
|
|
196
|
+
infer Head extends ExtensionEntry,
|
|
197
|
+
...infer Tail extends readonly ExtensionEntry[]
|
|
198
|
+
] ? Head extends AnyAliasedExtension ? [LiteralName<Head["as"]>] extends [never] ? {
|
|
199
|
+
extensions: `An alias "as" must be a single string literal, not a widened or union type.`;
|
|
200
|
+
} : ValidAliasNames<Tail> : ValidAliasNames<Tail> : unknown;
|
|
201
|
+
/** Collapse an intersection into a single flat object type for readable hovers. */
|
|
202
|
+
type Flatten<T> = {
|
|
203
|
+
[K in keyof T]: T[K];
|
|
204
|
+
} & {};
|
|
205
|
+
/**
|
|
206
|
+
* The base SDK plus an `ext` namespace carrying every attached extension's API.
|
|
207
|
+
*
|
|
208
|
+
* Extensions are compartmentalized under `ext` (e.g. `sdk.ext.labels`) rather than
|
|
209
|
+
* spliced onto the SDK root, mirroring where {@link attachExtensions} mounts them.
|
|
210
|
+
* This is what lets the SDK add members over time without a name-reservation
|
|
211
|
+
* registry: a extension *key* can never collide with a current or future root
|
|
212
|
+
* member because it lives one level down. The single exception is `ext` itself —
|
|
213
|
+
* that one root key is now SDK-owned as the extension container, exactly as
|
|
214
|
+
* `graphql`/`fetch` are SDK-owned. A base SDK surface must therefore not declare
|
|
215
|
+
* its own `ext` member. Extension-vs-extension uniqueness within `ext` is still
|
|
216
|
+
* enforced — statically by {@link UniqueExtensionNames}, at runtime by `attach`.
|
|
217
|
+
*
|
|
218
|
+
* Only a tuple *known* to be non-empty introduces `ext`, whose value is the
|
|
219
|
+
* left→right {@link Accumulate}d namespace map. Both other cases resolve to
|
|
220
|
+
* exactly `Base` (no `ext` key): the empty tuple `[]`, and — deliberately — a
|
|
221
|
+
* widened, non-tuple extension array (e.g. `DataSDKExtension[]`) whose length TypeScript
|
|
222
|
+
* cannot see. The runtime returns the base untouched whenever the array is empty,
|
|
223
|
+
* so keying presence off "provably non-empty" (rather than "provably empty")
|
|
224
|
+
* keeps the type from promising an `ext` the runtime may not create for a widened
|
|
225
|
+
* array that happens to be empty.
|
|
226
|
+
*/
|
|
227
|
+
export type ExtendedSDK<Base, Extensions extends readonly ExtensionEntry[]> = Extensions extends readonly [ExtensionEntry, ...ExtensionEntry[]] ? Flatten<Base & {
|
|
228
|
+
ext: Flatten<Accumulate<Extensions>>;
|
|
229
|
+
}> : Base;
|
|
230
|
+
export {};
|
|
231
|
+
//# sourceMappingURL=extension-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-types.d.ts","sourceRoot":"","sources":["../../src/core/extension-types.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -17,6 +17,6 @@ export type { McpAppsHostContext, McpAppsSessionOptions } from './mcpapps-sessio
|
|
|
17
17
|
export { getSurfaceCapabilities } from './capabilities';
|
|
18
18
|
export type { SurfaceCapabilities } from './capabilities';
|
|
19
19
|
export { wrapSDKPromise } from './sdk-promise';
|
|
20
|
-
export {
|
|
21
|
-
export type {
|
|
20
|
+
export { createExtensionFactory } from './extension-factory';
|
|
21
|
+
export type { Extension, AnyExtension, AliasedExtension, ExtensionsFor, ExtensionEntry, ExtendedSDK, LiteralName, UniqueExtensionNames, ValidAliasNames, } from './extension-types';
|
|
22
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACN,OAAO,EACP,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,YAAY,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG5C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGrD,YAAY,EACX,WAAW,EACX,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,QAAQ,EACR,SAAS,GACT,MAAM,QAAQ,CAAC;AAGhB,YAAY,EACX,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAQ,EACR,OAAO,GACP,MAAM,QAAQ,CAAC;AAGhB,YAAY,EACX,YAAY,EACZ,OAAO,EACP,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,GACX,MAAM,QAAQ,CAAC;AAGhB,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7F,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC7E,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAGnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAQ/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACN,OAAO,EACP,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,YAAY,GACZ,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG5C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGrD,YAAY,EACX,WAAW,EACX,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,QAAQ,EACR,SAAS,GACT,MAAM,QAAQ,CAAC;AAGhB,YAAY,EACX,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAQ,EACR,OAAO,GACP,MAAM,QAAQ,CAAC;AAGhB,YAAY,EACX,YAAY,EACZ,OAAO,EACP,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,GACX,MAAM,QAAQ,CAAC;AAGhB,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7F,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC7E,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAGnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAQ/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,YAAY,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,eAAe,GACf,MAAM,mBAAmB,CAAC"}
|
package/dist/core/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { M as r, a as s, S as i, g as o, i as
|
|
1
|
+
import { M as r, a as s, S as i, g as o, i as t, b as p, r as f } from "../surface-Dd2tqrPi.js";
|
|
2
2
|
import { g as S } from "../capabilities-5BWkCbcP.js";
|
|
3
3
|
import { w as g } from "../sdk-promise-D0sy7OW1.js";
|
|
4
|
-
import { c as
|
|
4
|
+
import { c as x } from "../extension-factory-CJkfM4km.js";
|
|
5
5
|
export {
|
|
6
6
|
r as McpAppsNotAvailableError,
|
|
7
7
|
s as McpAppsSession,
|
|
8
8
|
i as Surface,
|
|
9
|
-
|
|
9
|
+
x as createExtensionFactory,
|
|
10
10
|
S as getSurfaceCapabilities,
|
|
11
11
|
o as getVerifiedSurface,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
t as initialize,
|
|
13
|
+
p as isSfEmbeddingIframe,
|
|
14
14
|
f as resetSurface,
|
|
15
15
|
g as wrapSDKPromise
|
|
16
16
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* First-party DataSDK extension catalog. Import extensions from this subpath and
|
|
8
|
+
* attach them via `createDataSDK({ extensions: [...] })`:
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createDataSDK } from "@salesforce/platform-sdk/data";
|
|
12
|
+
* import { labels } from "@salesforce/platform-sdk/data/extensions";
|
|
13
|
+
*
|
|
14
|
+
* const sdk = await createDataSDK({ extensions: [labels({ namespace: "MyApp" })] });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export { labels } from './labels';
|
|
18
|
+
export type { LabelsApi, LabelsOptions, LabelFallback } from './labels';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/extensions/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineDataExtension as b } from "../index.js";
|
|
2
2
|
const m = "BASE_VALUE", p = `
|
|
3
3
|
query Labels($namespace: String, $names: [String!]!, $locale: String, $fallback: LabelFallback) {
|
|
4
4
|
uiapi {
|
|
@@ -10,23 +10,23 @@ const m = "BASE_VALUE", p = `
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
`,
|
|
14
|
-
function
|
|
13
|
+
`, E = /* @__PURE__ */ new Set(["TRANSLATION_NOT_FOUND", "LABEL_NOT_FOUND"]), f = ["uiapi", "platform", "labels"];
|
|
14
|
+
function L(n) {
|
|
15
15
|
const e = n.path;
|
|
16
16
|
return e?.length !== f.length + 1 ? !1 : f.every((s, l) => e[l] === s) && typeof e[f.length] == "number";
|
|
17
17
|
}
|
|
18
18
|
function d(n) {
|
|
19
19
|
const e = n.extensions?.code;
|
|
20
|
-
return e != null &&
|
|
20
|
+
return e != null && E.has(e) && L(n);
|
|
21
21
|
}
|
|
22
22
|
const h = 100;
|
|
23
|
-
function
|
|
23
|
+
function y(n, e) {
|
|
24
24
|
const s = [...new Set(n)], l = [];
|
|
25
25
|
for (let r = 0; r < s.length; r += e)
|
|
26
26
|
l.push(s.slice(r, r + e));
|
|
27
27
|
return l;
|
|
28
28
|
}
|
|
29
|
-
async function
|
|
29
|
+
async function A(n, e, s, l, r) {
|
|
30
30
|
const t = { names: s, fallback: r };
|
|
31
31
|
e != null && (t.namespace = e), l != null && (t.locale = l);
|
|
32
32
|
const a = await n.query({
|
|
@@ -43,9 +43,9 @@ async function y(n, e, s, l, r) {
|
|
|
43
43
|
);
|
|
44
44
|
return c;
|
|
45
45
|
}
|
|
46
|
-
async function
|
|
47
|
-
const t =
|
|
48
|
-
t.map((c) =>
|
|
46
|
+
async function S(n, e, s, l, r) {
|
|
47
|
+
const t = y(s, h), a = await Promise.all(
|
|
48
|
+
t.map((c) => A(n, e, c, l, r))
|
|
49
49
|
), o = {};
|
|
50
50
|
for (const c of a)
|
|
51
51
|
for (const i of c)
|
|
@@ -56,7 +56,7 @@ function u(n) {
|
|
|
56
56
|
const e = n?.trim();
|
|
57
57
|
return e || void 0;
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function g(n = {}) {
|
|
60
60
|
const e = { ...n };
|
|
61
61
|
return b({
|
|
62
62
|
name: "labels",
|
|
@@ -66,7 +66,7 @@ function _(n = {}) {
|
|
|
66
66
|
return {};
|
|
67
67
|
const r = async (t, a) => {
|
|
68
68
|
const o = u(a?.namespace) ?? u(e.namespace), c = u(a?.locale) ?? u(e.locale), i = a?.fallback ?? e.fallback ?? m;
|
|
69
|
-
return
|
|
69
|
+
return S(l, o, t, c, i);
|
|
70
70
|
};
|
|
71
71
|
return {
|
|
72
72
|
async get(t, a) {
|
|
@@ -80,5 +80,5 @@ function _(n = {}) {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
export {
|
|
83
|
-
|
|
83
|
+
g as labels
|
|
84
84
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LabelFallback } from './query';
|
|
2
|
-
import {
|
|
2
|
+
import { DataSDKExtension } from '../../index';
|
|
3
3
|
export type { LabelFallback };
|
|
4
4
|
/**
|
|
5
5
|
* Where labels are read from and how they resolve. Supplied once when the
|
|
6
|
-
*
|
|
6
|
+
* extension is configured (`labels({ namespace: "MyApp" })`) to set defaults,
|
|
7
7
|
* and again per call ({@link LabelsApi.get}/{@link LabelsApi.getAll}) to override
|
|
8
8
|
* them for that call. Each field resolves independently as `call ?? config ??
|
|
9
9
|
* built-in default`.
|
|
@@ -31,15 +31,15 @@ export interface LabelsOptions {
|
|
|
31
31
|
fallback?: LabelFallback;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* The `labels` namespace mounted
|
|
35
|
-
* a namespace (configured or per-call) and report
|
|
36
|
-
* — `undefined` from {@link get}, an absent key
|
|
37
|
-
* decides what a miss means; fall back to the
|
|
38
|
-
* `await sdk.labels.get?.(name) ?? name`.
|
|
34
|
+
* The `labels` namespace mounted in the DataSDK's `ext` container — `sdk.ext.labels`.
|
|
35
|
+
* Both methods resolve labels in a namespace (configured or per-call) and report
|
|
36
|
+
* an unresolved label as a miss — `undefined` from {@link get}, an absent key
|
|
37
|
+
* from {@link getAll}. The caller decides what a miss means; fall back to the
|
|
38
|
+
* name with `await sdk.ext.labels.get?.(name) ?? name`.
|
|
39
39
|
*
|
|
40
40
|
* The methods are optional, mirroring the {@link DataSDK.graphql} namespace they
|
|
41
41
|
* depend on: a surface whose DataSDK has no `graphql` cannot fetch labels, so
|
|
42
|
-
* `get`/`getAll` are absent there. Feature-detect (`sdk.labels.get?.(name)`) or
|
|
42
|
+
* `get`/`getAll` are absent there. Feature-detect (`sdk.ext.labels.get?.(name)`) or
|
|
43
43
|
* narrow once, exactly as you would `sdk.graphql`.
|
|
44
44
|
*/
|
|
45
45
|
export interface LabelsApi {
|
|
@@ -71,13 +71,13 @@ export interface LabelsApi {
|
|
|
71
71
|
getAll?(names: readonly string[], options?: LabelsOptions): Promise<Record<string, string>>;
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
|
-
* A first-party DataSDK
|
|
75
|
-
* custom labels. Attach it via `createDataSDK({
|
|
76
|
-
* then call `sdk.labels.get?.(name)` / `sdk.labels.getAll?.(names)` — the
|
|
74
|
+
* A first-party DataSDK extension that mounts a `labels` namespace for reading
|
|
75
|
+
* custom labels. Attach it via `createDataSDK({ extensions: [labels()] })`,
|
|
76
|
+
* then call `sdk.ext.labels.get?.(name)` / `sdk.ext.labels.getAll?.(names)` — the
|
|
77
77
|
* methods are optional, absent on a surface whose DataSDK has no `graphql`.
|
|
78
78
|
*
|
|
79
79
|
* Requires org API v264 or later (the release that introduced the
|
|
80
|
-
* `uiapi.platform.labels` GraphQL shape this
|
|
80
|
+
* `uiapi.platform.labels` GraphQL shape this extension queries).
|
|
81
81
|
*
|
|
82
82
|
* @param config - Default {@link LabelsOptions} for every call; each field is
|
|
83
83
|
* overridable per call. Omit `namespace` (here and per call) to read from the
|
|
@@ -86,13 +86,13 @@ export interface LabelsApi {
|
|
|
86
86
|
* @example
|
|
87
87
|
* ```typescript
|
|
88
88
|
* import { createDataSDK } from "@salesforce/platform-sdk/data";
|
|
89
|
-
* import {
|
|
89
|
+
* import { labels } from "@salesforce/platform-sdk/data/extensions";
|
|
90
90
|
*
|
|
91
|
-
* const sdk = await createDataSDK({
|
|
92
|
-
* const greeting = (await sdk.labels.get?.("greeting")) ?? "greeting"; // uses "MyApp"; ?? name if you want the key
|
|
93
|
-
* const french = await sdk.labels.get?.("greeting", { locale: "fr" }); // string | undefined
|
|
94
|
-
* const many = await sdk.labels.getAll?.(["greeting", "farewell"]); // only resolved names
|
|
91
|
+
* const sdk = await createDataSDK({ extensions: [labels({ namespace: "MyApp" })] });
|
|
92
|
+
* const greeting = (await sdk.ext.labels.get?.("greeting")) ?? "greeting"; // uses "MyApp"; ?? name if you want the key
|
|
93
|
+
* const french = await sdk.ext.labels.get?.("greeting", { locale: "fr" }); // string | undefined
|
|
94
|
+
* const many = await sdk.ext.labels.getAll?.(["greeting", "farewell"]); // only resolved names
|
|
95
95
|
* ```
|
|
96
96
|
*/
|
|
97
|
-
export declare function
|
|
97
|
+
export declare function labels(config?: LabelsOptions): DataSDKExtension<"labels", LabelsApi>;
|
|
98
98
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/data/extensions/labels/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAA0B,KAAK,aAAa,EAAiB,MAAM,SAAS,CAAC;AACpF,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEzE,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACzB;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACzE;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5F;AAgBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,MAAM,CAAC,MAAM,GAAE,aAAkB,GAAG,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAsDxF"}
|
|
@@ -11,7 +11,7 @@ export type LabelFallback = "BASE_VALUE" | "USER_DEFAULT" | "NONE";
|
|
|
11
11
|
/**
|
|
12
12
|
* Return the org-default (base) value when a label has no translation for the
|
|
13
13
|
* requested locale, instead of the logged-in user's language (the server's
|
|
14
|
-
* `USER_DEFAULT` behavior). The
|
|
14
|
+
* `USER_DEFAULT` behavior). The extension resolves an explicit target locale, so it
|
|
15
15
|
* opts into `BASE_VALUE`.
|
|
16
16
|
*/
|
|
17
17
|
export declare const DEFAULT_LABEL_FALLBACK: LabelFallback;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../src/data/extensions/labels/query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAA4B,CAAC;AAiIlE,oEAAoE;AACpE,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AA6D/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAuBjC"}
|