@salesforce/vite-plugin-lwc-ui-bundle 1.134.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,35 @@
1
1
  import { JSONSchema } from '@conduit-client/jsonschema-validate';
2
2
  import { Plugin } from 'vite';
3
3
  import { ReadInvokerShape } from './types';
4
- export interface LdsWireAdapterConfig {
5
- type: "wire";
4
+ /**
5
+ * MCP dispatch descriptor. Nested under `mcp` on every adapter config so
6
+ * additional MCP-specific fields (auth, transport, retry policy) can join
7
+ * later without reshaping every consumer entry.
8
+ */
9
+ export interface LdsAdapterMcpDispatch {
6
10
  toolName: string;
11
+ }
12
+ /**
13
+ * Base shape every LDS adapter config extends. Holds the dispatch surface in
14
+ * one place so new backings (e.g. `http`) can land as sibling optional fields
15
+ * without forking each adapter interface. Dual registration is supported at
16
+ * the type level — runtime execution still targets a single backing per call.
17
+ */
18
+ export interface LdsAdapterConfigBase {
19
+ mcp?: LdsAdapterMcpDispatch;
20
+ }
21
+ /**
22
+ * LDS adapter configs whose input is validated against a JSON Schema at
23
+ * invoke time — wire, imperative-mutation, imperative-read. GraphQL variants
24
+ * skip this base because they pass `{ query, variables }` through to the
25
+ * configured MCP tool with no schema check.
26
+ */
27
+ export interface LdsSchemaValidatedAdapterConfig extends LdsAdapterConfigBase {
7
28
  configJsonSchema: JSONSchema;
8
29
  }
30
+ export interface LdsWireAdapterConfig extends LdsSchemaValidatedAdapterConfig {
31
+ type: "wire";
32
+ }
9
33
  /**
10
34
  * Imperative **mutation** adapter. Always an async
11
35
  * `(config) => Promise<Data>` that throws on validation or tool error —
@@ -14,10 +38,8 @@ export interface LdsWireAdapterConfig {
14
38
  * `subscribe`/`refresh` make no sense on write, and allowing them here
15
39
  * would drift off-platform from on-platform semantics.
16
40
  */
17
- export interface LdsImperativeMutationAdapterConfig {
41
+ export interface LdsImperativeMutationAdapterConfig extends LdsSchemaValidatedAdapterConfig {
18
42
  type: "imperative-mutation";
19
- toolName: string;
20
- configJsonSchema: JSONSchema;
21
43
  }
22
44
  /**
23
45
  * Public alias for the read-shape union defined in `runtime.ts`. Re-exported
@@ -30,13 +52,53 @@ export interface LdsImperativeMutationAdapterConfig {
30
52
  * surface for code ported verbatim.
31
53
  */
32
54
  export type LdsImperativeReadInvokerShape = ReadInvokerShape;
33
- export interface LdsImperativeReadAdapterConfig {
55
+ export interface LdsImperativeReadAdapterConfig extends LdsSchemaValidatedAdapterConfig {
34
56
  type: "imperative-read";
35
57
  invokerShape: LdsImperativeReadInvokerShape;
36
- toolName: string;
37
- configJsonSchema: JSONSchema;
38
58
  }
39
- export type LdsAdapterConfig = LdsWireAdapterConfig | LdsImperativeMutationAdapterConfig | LdsImperativeReadAdapterConfig;
59
+ /**
60
+ * GraphQL wire adapter. Emits `{ data, errors, refresh }` (distinct from the
61
+ * base wire `{ data, error }`). No `configJsonSchema` — the adapter passes
62
+ * `{ query, variables }` through to the configured MCP tool.
63
+ */
64
+ export interface LdsGraphqlWireAdapterConfig extends LdsAdapterConfigBase {
65
+ type: "graphql-wire";
66
+ }
67
+ /**
68
+ * Imperative GraphQL mutation — `(config) => Promise<{ data, errors }>`.
69
+ * Errors are routed in-band to the `errors[]` envelope rather than thrown,
70
+ * matching on-platform `toGraphQLResponseFromFailure`.
71
+ */
72
+ export interface LdsGraphqlMutationAdapterConfig extends LdsAdapterConfigBase {
73
+ type: "graphql-mutation";
74
+ }
75
+ /**
76
+ * Read-shape discriminator for imperative GraphQL adapters. Mirrors the
77
+ * `imperative-read` `invokerShape` field so the two families share a pattern:
78
+ * one `type` discriminator + a shape field that selects the return surface.
79
+ *
80
+ * - `query` — `Promise<{ data, errors, subscribe }>` (on-platform
81
+ * `GraphQLImperativeBindingsService` without `exposeRefresh`).
82
+ * - `query-refreshable` — `Promise<{ data, errors, subscribe, refresh }>`
83
+ * (same service with `exposeRefresh: true`).
84
+ * - `legacy` — `{ invoke(config, context, callback),
85
+ * subscribe(config, context, callback): Unsubscribe }`, the older callback
86
+ * surface served by `GraphQLLegacyImperativeBindingsService`.
87
+ *
88
+ * `subscribe` is a deliberate no-op off-platform (no reactive store).
89
+ */
90
+ export type LdsGraphqlImperativeReadInvokerShape = "query" | "query-refreshable" | "legacy";
91
+ /**
92
+ * Imperative GraphQL read adapter. The `invokerShape` picks the return
93
+ * surface — see {@link LdsGraphqlImperativeReadInvokerShape}. Errors are
94
+ * routed in-band to `errors[]` (for `query`/`query-refreshable`) or into the
95
+ * callback payload (for `legacy`); no shape throws on tool errors.
96
+ */
97
+ export interface LdsGraphqlImperativeReadAdapterConfig extends LdsAdapterConfigBase {
98
+ type: "graphql-imperative-read";
99
+ invokerShape: LdsGraphqlImperativeReadInvokerShape;
100
+ }
101
+ export type LdsAdapterConfig = LdsWireAdapterConfig | LdsImperativeMutationAdapterConfig | LdsImperativeReadAdapterConfig | LdsGraphqlWireAdapterConfig | LdsGraphqlMutationAdapterConfig | LdsGraphqlImperativeReadAdapterConfig;
40
102
  export type LdsAdapterRegistry = Record<string, Record<string, LdsAdapterConfig>>;
41
103
  /**
42
104
  * LDS provider — rewrites registered `lightning/*` imports (e.g.
@@ -61,5 +123,5 @@ export type LdsAdapterRegistry = Record<string, Record<string, LdsAdapterConfig>
61
123
  * Only specifiers present in the `adapters` registry are intercepted; imports from
62
124
  * unregistered specifiers pass through unchanged.
63
125
  */
64
- export declare function lds(adapters?: LdsAdapterRegistry): Plugin;
126
+ export declare function lds(overrides?: LdsAdapterRegistry): Plugin;
65
127
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/lds/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAGtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAehD,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,UAAU,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kCAAkC;IAClD,IAAI,EAAE,qBAAqB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,UAAU,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,6BAA6B,GAAG,gBAAgB,CAAC;AAE7D,MAAM,WAAW,8BAA8B;IAC9C,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,6BAA6B,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,UAAU,CAAC;CAC7B;AAED,MAAM,MAAM,gBAAgB,GACzB,oBAAoB,GACpB,kCAAkC,GAClC,8BAA8B,CAAC;AAElC,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAwHlF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,GAAG,CAAC,QAAQ,GAAE,kBAAqC,GAAG,MAAM,CA6F3E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/lds/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAGtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAuChD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACpC,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAAgC,SAAQ,oBAAoB;IAC5E,gBAAgB,EAAE,UAAU,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,+BAA+B;IAC5E,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kCAAmC,SAAQ,+BAA+B;IAC1F,IAAI,EAAE,qBAAqB,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,6BAA6B,GAAG,gBAAgB,CAAC;AAE7D,MAAM,WAAW,8BAA+B,SAAQ,+BAA+B;IACtF,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,6BAA6B,CAAC;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACxE,IAAI,EAAE,cAAc,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,+BAAgC,SAAQ,oBAAoB;IAC5E,IAAI,EAAE,kBAAkB,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,oCAAoC,GAAG,OAAO,GAAG,mBAAmB,GAAG,QAAQ,CAAC;AAE5F;;;;;GAKG;AACH,MAAM,WAAW,qCAAsC,SAAQ,oBAAoB;IAClF,IAAI,EAAE,yBAAyB,CAAC;IAChC,YAAY,EAAE,oCAAoC,CAAC;CACnD;AAED,MAAM,MAAM,gBAAgB,GACzB,oBAAoB,GACpB,kCAAkC,GAClC,8BAA8B,GAC9B,2BAA2B,GAC3B,+BAA+B,GAC/B,qCAAqC,CAAC;AAEzC,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;AA4KlF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,GAAG,CAAC,SAAS,GAAE,kBAAuB,GAAG,MAAM,CA+G9D"}
@@ -5,15 +5,17 @@ import { init, parse } from "es-module-lexer";
5
5
  import MagicString from "magic-string";
6
6
  const ADAPTER_PREFIX = "sf-lds-adapter:";
7
7
  const ADAPTER_ID_PREFIX = "\0" + ADAPTER_PREFIX;
8
- const adapterBaseSource = readFileSync(
9
- join(dirname(fileURLToPath(import.meta.url)), "runtime.js"),
10
- "utf-8"
8
+ const adapterBaseSource = stripTopLevelExports(
9
+ readFileSync(join(dirname(fileURLToPath(import.meta.url)), "runtime.js"), "utf-8")
11
10
  );
11
+ function stripTopLevelExports(source) {
12
+ return source.replace(/^export\s+(?=(?:async\s+)?function\s)/gm, "").replace(/^export\s*\{[^}]*};?\s*$/gm, "");
13
+ }
12
14
  const DEFAULT_ADAPTERS = {
13
15
  "lightning/uiRecordApi": {
14
16
  getRecord: {
15
17
  type: "wire",
16
- toolName: "getRecordMcpTool",
18
+ mcp: { toolName: "getRecordMcpTool" },
17
19
  configJsonSchema: {
18
20
  type: "object",
19
21
  properties: {
@@ -53,7 +55,7 @@ const DEFAULT_ADAPTERS = {
53
55
  },
54
56
  createRecord: {
55
57
  type: "imperative-mutation",
56
- toolName: "createRecordMcpTool",
58
+ mcp: { toolName: "createRecordMcpTool" },
57
59
  configJsonSchema: {
58
60
  type: "object",
59
61
  properties: {
@@ -71,7 +73,7 @@ const DEFAULT_ADAPTERS = {
71
73
  },
72
74
  updateRecord: {
73
75
  type: "imperative-mutation",
74
- toolName: "updateRecordMcpTool",
76
+ mcp: { toolName: "updateRecordMcpTool" },
75
77
  configJsonSchema: {
76
78
  type: "object",
77
79
  properties: {
@@ -95,7 +97,7 @@ const DEFAULT_ADAPTERS = {
95
97
  getObjectInfo_imperative: {
96
98
  type: "imperative-read",
97
99
  invokerShape: "legacy",
98
- toolName: "getObjectInfoMcpTool",
100
+ mcp: { toolName: "getObjectInfoMcpTool" },
99
101
  configJsonSchema: {
100
102
  type: "object",
101
103
  properties: {
@@ -105,8 +107,37 @@ const DEFAULT_ADAPTERS = {
105
107
  additionalProperties: false
106
108
  }
107
109
  }
110
+ },
111
+ // `lightning/graphql` — on-platform exports `gql`, the `graphql` wire
112
+ // adapter, and `executeMutation`. Only `graphql` and `executeMutation`
113
+ // are registry entries; `gql` rides along automatically for any specifier
114
+ // that has at least one graphql-typed entry (emitted by the load hook).
115
+ "lightning/graphql": {
116
+ graphql: { type: "graphql-wire", mcp: { toolName: "graphqlQuery" } },
117
+ executeMutation: { type: "graphql-mutation", mcp: { toolName: "graphqlQuery" } }
108
118
  }
109
119
  };
120
+ function isGraphqlSpecifier(moduleAdapters) {
121
+ return Object.values(moduleAdapters).some(
122
+ (entry) => entry.type === "graphql-wire" || entry.type === "graphql-mutation" || entry.type === "graphql-imperative-read"
123
+ );
124
+ }
125
+ function factoryFor(type) {
126
+ switch (type) {
127
+ case "wire":
128
+ return "createWireAdapter";
129
+ case "imperative-mutation":
130
+ return "createMutationAdapter";
131
+ case "imperative-read":
132
+ return "createReadAdapter";
133
+ case "graphql-wire":
134
+ return "createGraphQLWireAdapter";
135
+ case "graphql-mutation":
136
+ return "createGraphQLMutationAdapter";
137
+ case "graphql-imperative-read":
138
+ return "createGraphQLImperativeReadAdapter";
139
+ }
140
+ }
110
141
  function parseImportSpecifiers(bracesContent) {
111
142
  return bracesContent.split(",").map((s) => s.trim()).filter(Boolean).map((entry) => {
112
143
  const asIdx = entry.indexOf(" as ");
@@ -114,8 +145,20 @@ function parseImportSpecifiers(bracesContent) {
114
145
  return { original, full: entry };
115
146
  });
116
147
  }
117
- function lds(adapters = DEFAULT_ADAPTERS) {
118
- const specifierSnippets = Object.keys(adapters).flatMap((s) => [`'${s}'`, `"${s}"`]);
148
+ function mergeWithDefaults(overrides) {
149
+ const merged = { ...DEFAULT_ADAPTERS };
150
+ for (const [specifier, entries] of Object.entries(overrides)) {
151
+ merged[specifier] = { ...DEFAULT_ADAPTERS[specifier] ?? {}, ...entries };
152
+ }
153
+ return merged;
154
+ }
155
+ function lds(overrides = {}) {
156
+ const adapters = mergeWithDefaults(overrides);
157
+ const graphqlSpecifiers = new Set(
158
+ Object.entries(adapters).filter(([, moduleAdapters]) => isGraphqlSpecifier(moduleAdapters)).map(([specifier]) => specifier)
159
+ );
160
+ const transformSpecifiers = Object.keys(adapters).filter((s) => !graphqlSpecifiers.has(s));
161
+ const specifierSnippets = transformSpecifiers.flatMap((s) => [`'${s}'`, `"${s}"`]);
119
162
  return {
120
163
  name: "vite-plugin-lds",
121
164
  enforce: "pre",
@@ -132,7 +175,7 @@ function lds(adapters = DEFAULT_ADAPTERS) {
132
175
  return null;
133
176
  }
134
177
  const relevant = imports.filter(
135
- (imp) => imp.d === -1 && imp.n !== void 0 && imp.n in adapters
178
+ (imp) => imp.d === -1 && imp.n !== void 0 && imp.n in adapters && !graphqlSpecifiers.has(imp.n)
136
179
  );
137
180
  if (relevant.length === 0) return null;
138
181
  const s = new MagicString(code);
@@ -164,6 +207,7 @@ function lds(adapters = DEFAULT_ADAPTERS) {
164
207
  return { code: s.toString(), map: s.generateMap({ hires: true }) };
165
208
  },
166
209
  resolveId(id) {
210
+ if (graphqlSpecifiers.has(id)) return ADAPTER_ID_PREFIX + id;
167
211
  if (id.startsWith(ADAPTER_PREFIX)) return ADAPTER_ID_PREFIX + id.slice(ADAPTER_PREFIX.length);
168
212
  return null;
169
213
  },
@@ -175,11 +219,13 @@ function lds(adapters = DEFAULT_ADAPTERS) {
175
219
  const lines = [adapterBaseSource];
176
220
  for (const [name, entry] of Object.entries(moduleAdapters)) {
177
221
  const { type, ...cfg } = entry;
178
- const factory = type === "wire" ? "createWireAdapter" : type === "imperative-mutation" ? "createMutationAdapter" : "createReadAdapter";
179
222
  lines.push(
180
- `export const ${name} = ${factory}(${JSON.stringify(name)}, ${JSON.stringify(cfg)});`
223
+ `export const ${name} = ${factoryFor(type)}(${JSON.stringify(name)}, ${JSON.stringify(cfg)});`
181
224
  );
182
225
  }
226
+ if (graphqlSpecifiers.has(specifier)) {
227
+ lines.push("export { gql };");
228
+ }
183
229
  return lines.join("\n");
184
230
  }
185
231
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/providers/lds/index.ts"],"sourcesContent":["/**\n * Copyright (c) 2026, Salesforce, Inc.,\n * All rights reserved.\n * For full license text, see the LICENSE.txt file\n */\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { JSONSchema } from \"@conduit-client/jsonschema-validate\";\nimport { init, parse } from \"es-module-lexer\";\nimport MagicString from \"magic-string\";\nimport type { Plugin } from \"vite\";\nimport type { ReadInvokerShape } from \"./types\";\n\n// prefix to write into transformed source code\nconst ADAPTER_PREFIX = \"sf-lds-adapter:\";\n// prefix used to ID the adapter when loading the virtual module\nconst ADAPTER_ID_PREFIX = \"\\0\" + ADAPTER_PREFIX;\n\n// the source of the adapter base module — reused across virtual modules so\n// each generated specifier emits the createWireAdapter / createMutationAdapter /\n// createReadAdapter factories once\nconst adapterBaseSource = readFileSync(\n\tjoin(dirname(fileURLToPath(import.meta.url)), \"runtime.js\"),\n\t\"utf-8\",\n);\n\nexport interface LdsWireAdapterConfig {\n\ttype: \"wire\";\n\ttoolName: string;\n\tconfigJsonSchema: JSONSchema;\n}\n\n/**\n * Imperative **mutation** adapter. Always an async\n * `(config) => Promise<Data>` that throws on validation or tool error —\n * matching OneStore's `DefaultImperativeBindingsService`, the only service a\n * mutation ever uses on platform. Mutations do not carry an `invokerShape`:\n * `subscribe`/`refresh` make no sense on write, and allowing them here\n * would drift off-platform from on-platform semantics.\n */\nexport interface LdsImperativeMutationAdapterConfig {\n\ttype: \"imperative-mutation\";\n\ttoolName: string;\n\tconfigJsonSchema: JSONSchema;\n}\n\n/**\n * Public alias for the read-shape union defined in `runtime.ts`. Re-exported\n * from this module so consumers don't have to import from the runtime entry\n * point, while keeping the union pinned to one source of truth.\n *\n * Off-platform there is no store, so `subscribe` is a deliberate no-op\n * (callback never fires, returned unsubscribe is idempotent) and `refresh`\n * re-executes the underlying MCP tool. This preserves the OneStore API\n * surface for code ported verbatim.\n */\nexport type LdsImperativeReadInvokerShape = ReadInvokerShape;\n\nexport interface LdsImperativeReadAdapterConfig {\n\ttype: \"imperative-read\";\n\tinvokerShape: LdsImperativeReadInvokerShape;\n\ttoolName: string;\n\tconfigJsonSchema: JSONSchema;\n}\n\nexport type LdsAdapterConfig =\n\t| LdsWireAdapterConfig\n\t| LdsImperativeMutationAdapterConfig\n\t| LdsImperativeReadAdapterConfig;\n\nexport type LdsAdapterRegistry = Record<string, Record<string, LdsAdapterConfig>>;\n\n/**\n * Default adapter registry.\n * Maps LDS module specifiers to MCP tool-backed implementations. Entries can be\n * wire adapters (`type: 'wire'`), imperative mutations (`type: 'imperative-mutation'`),\n * or imperative reads (`type: 'imperative-read'` + `invokerShape`).\n * Add entries here to support additional lightning/* exports.\n */\nconst DEFAULT_ADAPTERS: LdsAdapterRegistry = {\n\t\"lightning/uiRecordApi\": {\n\t\tgetRecord: {\n\t\t\ttype: \"wire\",\n\t\t\ttoolName: \"getRecordMcpTool\",\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\trecordId: { type: \"string\" },\n\t\t\t\t\tlayoutTypes: {\n\t\t\t\t\t\tanyOf: [{ type: \"array\", items: { type: \"string\" } }, { type: \"null\" }],\n\t\t\t\t\t},\n\t\t\t\t\tfields: {\n\t\t\t\t\t\tanyOf: [{ type: \"array\", items: { type: \"string\" } }, { type: \"null\" }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: [\"recordId\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tanyOf: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tfields: { type: \"array\", items: { type: \"string\" }, minItems: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequired: [\"fields\"],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tlayoutTypes: {\n\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\titems: { type: \"string\" },\n\t\t\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequired: [\"layoutTypes\"],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tcreateRecord: {\n\t\t\ttype: \"imperative-mutation\",\n\t\t\ttoolName: \"createRecordMcpTool\",\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\tapiName: { type: \"string\" },\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t\trequired: [],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: [\"apiName\", \"fields\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t},\n\t\t},\n\t\tupdateRecord: {\n\t\t\ttype: \"imperative-mutation\",\n\t\t\ttoolName: \"updateRecordMcpTool\",\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\trecordId: { type: \"string\" },\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t\trequired: [],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: [\"recordId\", \"fields\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t},\n\t\t},\n\t},\n\t\"lightning/uiObjectInfoApi\": {\n\t\t// On-platform this is a `{ invoke, subscribe }` callback surface\n\t\t// emitting `{ data, error }`. The legacy invoker shape preserves that\n\t\t// contract verbatim, so ported consumers keep their call sites.\n\t\tgetObjectInfo_imperative: {\n\t\t\ttype: \"imperative-read\",\n\t\t\tinvokerShape: \"legacy\",\n\t\t\ttoolName: \"getObjectInfoMcpTool\",\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\tobjectApiName: { type: \"string\" },\n\t\t\t\t},\n\t\t\t\trequired: [\"objectApiName\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t},\n\t\t},\n\t},\n};\n\nfunction parseImportSpecifiers(bracesContent: string): { original: string; full: string }[] {\n\treturn bracesContent\n\t\t.split(\",\")\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean)\n\t\t.map((entry) => {\n\t\t\tconst asIdx = entry.indexOf(\" as \");\n\t\t\tconst original = asIdx !== -1 ? entry.slice(0, asIdx).trim() : entry.trim();\n\t\t\treturn { original, full: entry };\n\t\t});\n}\n\n/**\n * LDS provider — rewrites registered `lightning/*` imports (e.g.\n * `lightning/uiRecordApi`) to MCP-tool-backed virtual modules. Unregistered\n * exports pass through to the normal `lightning/*` resolution.\n *\n * Three Vite hooks do the work:\n *\n * - **`transform`** — parses each `.js` / `.ts` file with `es-module-lexer`,\n * finds named imports from registered specifiers, and rewrites them to pull\n * registered names from `sf-lds-adapter:<specifier>` while leaving\n * unregistered names pointing at the original specifier.\n *\n * - **`resolveId`** — maps `sf-lds-adapter:<specifier>` to a `\\0`-prefixed\n * virtual module ID, preventing Rollup from attempting a filesystem lookup.\n *\n * - **`load`** — generates the virtual module, emitting an MCP-backed\n * `createWireAdapter(...)` class for every `type: 'wire'` entry,\n * `createMutationAdapter(...)` for every `type: 'imperative-mutation'` entry,\n * and `createReadAdapter(...)` for every `type: 'imperative-read'` entry.\n *\n * Only specifiers present in the `adapters` registry are intercepted; imports from\n * unregistered specifiers pass through unchanged.\n */\nexport function lds(adapters: LdsAdapterRegistry = DEFAULT_ADAPTERS): Plugin {\n\tconst specifierSnippets = Object.keys(adapters).flatMap((s) => [`'${s}'`, `\"${s}\"`]);\n\n\treturn {\n\t\tname: \"vite-plugin-lds\",\n\t\tenforce: \"pre\",\n\n\t\tasync transform(code, id) {\n\t\t\tconst cleanId = id.split(\"?\")[0] ?? id;\n\t\t\tif (!cleanId.endsWith(\".js\") && !cleanId.endsWith(\".ts\")) return null;\n\t\t\tif (cleanId.includes(\"/node_modules/\")) return null;\n\t\t\tif (!specifierSnippets.some((snippet) => code.includes(snippet))) return null;\n\n\t\t\tawait init;\n\n\t\t\tlet imports: ReturnType<typeof parse>[0];\n\t\t\ttry {\n\t\t\t\t[imports] = parse(code);\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst relevant = imports.filter(\n\t\t\t\t(imp) => imp.d === -1 && imp.n !== undefined && imp.n in adapters,\n\t\t\t);\n\t\t\tif (relevant.length === 0) return null;\n\n\t\t\tconst s = new MagicString(code);\n\t\t\tlet changed = false;\n\n\t\t\tfor (const imp of relevant) {\n\t\t\t\tconst { ss: start, se: end, n: specifier } = imp;\n\t\t\t\tconst statement = code.slice(start, end);\n\n\t\t\t\tconst openBrace = statement.indexOf(\"{\");\n\t\t\t\tconst closeBrace = statement.indexOf(\"}\");\n\t\t\t\tif (openBrace === -1 || closeBrace === -1) continue;\n\n\t\t\t\tconst bracesContent = statement.slice(openBrace + 1, closeBrace);\n\t\t\t\tconst moduleAdapters = adapters[specifier!]!;\n\t\t\t\tconst parsedImport = parseImportSpecifiers(bracesContent);\n\t\t\t\tconst registered = parsedImport.filter((p) => p.original in moduleAdapters);\n\t\t\t\tconst unregistered = parsedImport.filter((p) => !(p.original in moduleAdapters));\n\n\t\t\t\tif (registered.length === 0) continue;\n\n\t\t\t\tconst parts: string[] = [\n\t\t\t\t\t`import { ${registered.map((p) => p.full).join(\", \")} } from '${ADAPTER_PREFIX}${specifier}';`,\n\t\t\t\t];\n\n\t\t\t\tif (unregistered.length > 0) {\n\t\t\t\t\tparts.push(\n\t\t\t\t\t\t`import { ${unregistered.map((p) => p.full).join(\", \")} } from '${specifier}';`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\ts.overwrite(start, end, parts.join(\"\\n\"));\n\t\t\t\tchanged = true;\n\t\t\t}\n\n\t\t\tif (!changed) return null;\n\t\t\treturn { code: s.toString(), map: s.generateMap({ hires: true }) };\n\t\t},\n\n\t\tresolveId(id) {\n\t\t\tif (id.startsWith(ADAPTER_PREFIX)) return ADAPTER_ID_PREFIX + id.slice(ADAPTER_PREFIX.length);\n\t\t\treturn null;\n\t\t},\n\n\t\tload(id) {\n\t\t\tif (!id.startsWith(ADAPTER_ID_PREFIX)) return null;\n\n\t\t\tconst specifier = id.slice(ADAPTER_ID_PREFIX.length);\n\t\t\tconst moduleAdapters = adapters[specifier];\n\t\t\tif (!moduleAdapters) return null;\n\n\t\t\t// create lines of code used to create MCP tool based adapters\n\t\t\tconst lines: string[] = [adapterBaseSource];\n\t\t\tfor (const [name, entry] of Object.entries(moduleAdapters)) {\n\t\t\t\tconst { type, ...cfg } = entry;\n\t\t\t\tconst factory =\n\t\t\t\t\ttype === \"wire\"\n\t\t\t\t\t\t? \"createWireAdapter\"\n\t\t\t\t\t\t: type === \"imperative-mutation\"\n\t\t\t\t\t\t\t? \"createMutationAdapter\"\n\t\t\t\t\t\t\t: \"createReadAdapter\";\n\t\t\t\tlines.push(\n\t\t\t\t\t`export const ${name} = ${factory}(${JSON.stringify(name)}, ${JSON.stringify(cfg)});`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn lines.join(\"\\n\");\n\t\t},\n\t};\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/providers/lds/index.ts"],"sourcesContent":["/**\n * Copyright (c) 2026, Salesforce, Inc.,\n * All rights reserved.\n * For full license text, see the LICENSE.txt file\n */\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { JSONSchema } from \"@conduit-client/jsonschema-validate\";\nimport { init, parse } from \"es-module-lexer\";\nimport MagicString from \"magic-string\";\nimport type { Plugin } from \"vite\";\nimport type { ReadInvokerShape } from \"./types\";\n\n// prefix to write into transformed source code\nconst ADAPTER_PREFIX = \"sf-lds-adapter:\";\n// prefix used to ID the adapter when loading the virtual module\nconst ADAPTER_ID_PREFIX = \"\\0\" + ADAPTER_PREFIX;\n\n// the source of the adapter base module — reused across virtual modules so\n// each generated specifier emits the factories once.\n//\n// Top-level exports from the runtime module are stripped so every factory and\n// `gql` becomes a private binding inside the virtual module. The load hook\n// then controls exactly which names are exported per specifier: adapter\n// entries from the registry, plus `gql` for graphql specifiers. Without this,\n// the built `runtime.js` (trailing `export { …, gql, createWireAdapter, … }`)\n// and the source `runtime.ts` (per-declaration `export function gql …`) both\n// produce a `SyntaxError: Duplicate export of 'gql'` when the load hook also\n// appends `export { gql };`. They also leak the factory names as exports on\n// every LDS virtual module, which isn't a public contract we want.\nconst adapterBaseSource = stripTopLevelExports(\n\treadFileSync(join(dirname(fileURLToPath(import.meta.url)), \"runtime.js\"), \"utf-8\"),\n);\n\n/**\n * Removes top-level ES-module `export` keywords from the embedded runtime\n * source so its declarations survive as private bindings inside the virtual\n * module. Handles two shapes:\n * 1. Per-declaration: `export function foo …` / `export async function foo`\n * → the `export ` prefix is dropped.\n * 2. Trailing re-export clause: `export { foo, bar };` → deleted entirely.\n * Inner occurrences (inside function bodies, comments, strings) are not\n * affected because the source is a flat module with exports only at column 0.\n */\nfunction stripTopLevelExports(source: string): string {\n\treturn source\n\t\t.replace(/^export\\s+(?=(?:async\\s+)?function\\s)/gm, \"\")\n\t\t.replace(/^export\\s*\\{[^}]*};?\\s*$/gm, \"\");\n}\n\n/**\n * MCP dispatch descriptor. Nested under `mcp` on every adapter config so\n * additional MCP-specific fields (auth, transport, retry policy) can join\n * later without reshaping every consumer entry.\n */\nexport interface LdsAdapterMcpDispatch {\n\ttoolName: string;\n}\n\n/**\n * Base shape every LDS adapter config extends. Holds the dispatch surface in\n * one place so new backings (e.g. `http`) can land as sibling optional fields\n * without forking each adapter interface. Dual registration is supported at\n * the type level — runtime execution still targets a single backing per call.\n */\nexport interface LdsAdapterConfigBase {\n\tmcp?: LdsAdapterMcpDispatch;\n}\n\n/**\n * LDS adapter configs whose input is validated against a JSON Schema at\n * invoke time — wire, imperative-mutation, imperative-read. GraphQL variants\n * skip this base because they pass `{ query, variables }` through to the\n * configured MCP tool with no schema check.\n */\nexport interface LdsSchemaValidatedAdapterConfig extends LdsAdapterConfigBase {\n\tconfigJsonSchema: JSONSchema;\n}\n\nexport interface LdsWireAdapterConfig extends LdsSchemaValidatedAdapterConfig {\n\ttype: \"wire\";\n}\n\n/**\n * Imperative **mutation** adapter. Always an async\n * `(config) => Promise<Data>` that throws on validation or tool error —\n * matching OneStore's `DefaultImperativeBindingsService`, the only service a\n * mutation ever uses on platform. Mutations do not carry an `invokerShape`:\n * `subscribe`/`refresh` make no sense on write, and allowing them here\n * would drift off-platform from on-platform semantics.\n */\nexport interface LdsImperativeMutationAdapterConfig extends LdsSchemaValidatedAdapterConfig {\n\ttype: \"imperative-mutation\";\n}\n\n/**\n * Public alias for the read-shape union defined in `runtime.ts`. Re-exported\n * from this module so consumers don't have to import from the runtime entry\n * point, while keeping the union pinned to one source of truth.\n *\n * Off-platform there is no store, so `subscribe` is a deliberate no-op\n * (callback never fires, returned unsubscribe is idempotent) and `refresh`\n * re-executes the underlying MCP tool. This preserves the OneStore API\n * surface for code ported verbatim.\n */\nexport type LdsImperativeReadInvokerShape = ReadInvokerShape;\n\nexport interface LdsImperativeReadAdapterConfig extends LdsSchemaValidatedAdapterConfig {\n\ttype: \"imperative-read\";\n\tinvokerShape: LdsImperativeReadInvokerShape;\n}\n\n/**\n * GraphQL wire adapter. Emits `{ data, errors, refresh }` (distinct from the\n * base wire `{ data, error }`). No `configJsonSchema` — the adapter passes\n * `{ query, variables }` through to the configured MCP tool.\n */\nexport interface LdsGraphqlWireAdapterConfig extends LdsAdapterConfigBase {\n\ttype: \"graphql-wire\";\n}\n\n/**\n * Imperative GraphQL mutation — `(config) => Promise<{ data, errors }>`.\n * Errors are routed in-band to the `errors[]` envelope rather than thrown,\n * matching on-platform `toGraphQLResponseFromFailure`.\n */\nexport interface LdsGraphqlMutationAdapterConfig extends LdsAdapterConfigBase {\n\ttype: \"graphql-mutation\";\n}\n\n/**\n * Read-shape discriminator for imperative GraphQL adapters. Mirrors the\n * `imperative-read` `invokerShape` field so the two families share a pattern:\n * one `type` discriminator + a shape field that selects the return surface.\n *\n * - `query` — `Promise<{ data, errors, subscribe }>` (on-platform\n * `GraphQLImperativeBindingsService` without `exposeRefresh`).\n * - `query-refreshable` — `Promise<{ data, errors, subscribe, refresh }>`\n * (same service with `exposeRefresh: true`).\n * - `legacy` — `{ invoke(config, context, callback),\n * subscribe(config, context, callback): Unsubscribe }`, the older callback\n * surface served by `GraphQLLegacyImperativeBindingsService`.\n *\n * `subscribe` is a deliberate no-op off-platform (no reactive store).\n */\nexport type LdsGraphqlImperativeReadInvokerShape = \"query\" | \"query-refreshable\" | \"legacy\";\n\n/**\n * Imperative GraphQL read adapter. The `invokerShape` picks the return\n * surface — see {@link LdsGraphqlImperativeReadInvokerShape}. Errors are\n * routed in-band to `errors[]` (for `query`/`query-refreshable`) or into the\n * callback payload (for `legacy`); no shape throws on tool errors.\n */\nexport interface LdsGraphqlImperativeReadAdapterConfig extends LdsAdapterConfigBase {\n\ttype: \"graphql-imperative-read\";\n\tinvokerShape: LdsGraphqlImperativeReadInvokerShape;\n}\n\nexport type LdsAdapterConfig =\n\t| LdsWireAdapterConfig\n\t| LdsImperativeMutationAdapterConfig\n\t| LdsImperativeReadAdapterConfig\n\t| LdsGraphqlWireAdapterConfig\n\t| LdsGraphqlMutationAdapterConfig\n\t| LdsGraphqlImperativeReadAdapterConfig;\n\nexport type LdsAdapterRegistry = Record<string, Record<string, LdsAdapterConfig>>;\n\n/**\n * Default adapter registry.\n * Maps LDS module specifiers to MCP tool-backed implementations. Entries can be\n * wire adapters (`type: 'wire'`), imperative mutations (`type: 'imperative-mutation'`),\n * or imperative reads (`type: 'imperative-read'` + `invokerShape`).\n * Add entries here to support additional lightning/* exports.\n */\nconst DEFAULT_ADAPTERS: LdsAdapterRegistry = {\n\t\"lightning/uiRecordApi\": {\n\t\tgetRecord: {\n\t\t\ttype: \"wire\",\n\t\t\tmcp: { toolName: \"getRecordMcpTool\" },\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\trecordId: { type: \"string\" },\n\t\t\t\t\tlayoutTypes: {\n\t\t\t\t\t\tanyOf: [{ type: \"array\", items: { type: \"string\" } }, { type: \"null\" }],\n\t\t\t\t\t},\n\t\t\t\t\tfields: {\n\t\t\t\t\t\tanyOf: [{ type: \"array\", items: { type: \"string\" } }, { type: \"null\" }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: [\"recordId\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tanyOf: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tfields: { type: \"array\", items: { type: \"string\" }, minItems: 1 },\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequired: [\"fields\"],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tlayoutTypes: {\n\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\titems: { type: \"string\" },\n\t\t\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequired: [\"layoutTypes\"],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tcreateRecord: {\n\t\t\ttype: \"imperative-mutation\",\n\t\t\tmcp: { toolName: \"createRecordMcpTool\" },\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\tapiName: { type: \"string\" },\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t\trequired: [],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: [\"apiName\", \"fields\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t},\n\t\t},\n\t\tupdateRecord: {\n\t\t\ttype: \"imperative-mutation\",\n\t\t\tmcp: { toolName: \"updateRecordMcpTool\" },\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\trecordId: { type: \"string\" },\n\t\t\t\t\tfields: {\n\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\tproperties: {},\n\t\t\t\t\t\trequired: [],\n\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: [\"recordId\", \"fields\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t},\n\t\t},\n\t},\n\t\"lightning/uiObjectInfoApi\": {\n\t\t// On-platform this is a `{ invoke, subscribe }` callback surface\n\t\t// emitting `{ data, error }`. The legacy invoker shape preserves that\n\t\t// contract verbatim, so ported consumers keep their call sites.\n\t\tgetObjectInfo_imperative: {\n\t\t\ttype: \"imperative-read\",\n\t\t\tinvokerShape: \"legacy\",\n\t\t\tmcp: { toolName: \"getObjectInfoMcpTool\" },\n\t\t\tconfigJsonSchema: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\tobjectApiName: { type: \"string\" },\n\t\t\t\t},\n\t\t\t\trequired: [\"objectApiName\"],\n\t\t\t\tadditionalProperties: false,\n\t\t\t},\n\t\t},\n\t},\n\t// `lightning/graphql` — on-platform exports `gql`, the `graphql` wire\n\t// adapter, and `executeMutation`. Only `graphql` and `executeMutation`\n\t// are registry entries; `gql` rides along automatically for any specifier\n\t// that has at least one graphql-typed entry (emitted by the load hook).\n\t\"lightning/graphql\": {\n\t\tgraphql: { type: \"graphql-wire\", mcp: { toolName: \"graphqlQuery\" } },\n\t\texecuteMutation: { type: \"graphql-mutation\", mcp: { toolName: \"graphqlQuery\" } },\n\t},\n};\n\n/** True when any entry in a module's adapter map is a `graphql-*` type. */\nfunction isGraphqlSpecifier(moduleAdapters: Record<string, LdsAdapterConfig>): boolean {\n\treturn Object.values(moduleAdapters).some(\n\t\t(entry) =>\n\t\t\tentry.type === \"graphql-wire\" ||\n\t\t\tentry.type === \"graphql-mutation\" ||\n\t\t\tentry.type === \"graphql-imperative-read\",\n\t);\n}\n\n/** Maps a config discriminator to the factory name emitted in the virtual module. */\nfunction factoryFor(type: LdsAdapterConfig[\"type\"]): string {\n\tswitch (type) {\n\t\tcase \"wire\":\n\t\t\treturn \"createWireAdapter\";\n\t\tcase \"imperative-mutation\":\n\t\t\treturn \"createMutationAdapter\";\n\t\tcase \"imperative-read\":\n\t\t\treturn \"createReadAdapter\";\n\t\tcase \"graphql-wire\":\n\t\t\treturn \"createGraphQLWireAdapter\";\n\t\tcase \"graphql-mutation\":\n\t\t\treturn \"createGraphQLMutationAdapter\";\n\t\tcase \"graphql-imperative-read\":\n\t\t\treturn \"createGraphQLImperativeReadAdapter\";\n\t}\n}\n\nfunction parseImportSpecifiers(bracesContent: string): { original: string; full: string }[] {\n\treturn bracesContent\n\t\t.split(\",\")\n\t\t.map((s) => s.trim())\n\t\t.filter(Boolean)\n\t\t.map((entry) => {\n\t\t\tconst asIdx = entry.indexOf(\" as \");\n\t\t\tconst original = asIdx !== -1 ? entry.slice(0, asIdx).trim() : entry.trim();\n\t\t\treturn { original, full: entry };\n\t\t});\n}\n\n/**\n * Deep-merges user overrides onto the default registry: every specifier from\n * both sides is preserved, and per-specifier entries are merged so a consumer\n * can override `getRecord` without losing `createRecord`, or register a new\n * entry on `lightning/graphql` without losing `graphql` / `executeMutation`.\n * Pass an empty object to get just the defaults. To opt out of a default\n * entry, pass the same specifier with a different entry of the same key.\n */\nfunction mergeWithDefaults(overrides: LdsAdapterRegistry): LdsAdapterRegistry {\n\tconst merged: LdsAdapterRegistry = { ...DEFAULT_ADAPTERS };\n\tfor (const [specifier, entries] of Object.entries(overrides)) {\n\t\tmerged[specifier] = { ...(DEFAULT_ADAPTERS[specifier] ?? {}), ...entries };\n\t}\n\treturn merged;\n}\n\n/**\n * LDS provider — rewrites registered `lightning/*` imports (e.g.\n * `lightning/uiRecordApi`) to MCP-tool-backed virtual modules. Unregistered\n * exports pass through to the normal `lightning/*` resolution.\n *\n * Three Vite hooks do the work:\n *\n * - **`transform`** — parses each `.js` / `.ts` file with `es-module-lexer`,\n * finds named imports from registered specifiers, and rewrites them to pull\n * registered names from `sf-lds-adapter:<specifier>` while leaving\n * unregistered names pointing at the original specifier.\n *\n * - **`resolveId`** — maps `sf-lds-adapter:<specifier>` to a `\\0`-prefixed\n * virtual module ID, preventing Rollup from attempting a filesystem lookup.\n *\n * - **`load`** — generates the virtual module, emitting an MCP-backed\n * `createWireAdapter(...)` class for every `type: 'wire'` entry,\n * `createMutationAdapter(...)` for every `type: 'imperative-mutation'` entry,\n * and `createReadAdapter(...)` for every `type: 'imperative-read'` entry.\n *\n * Only specifiers present in the `adapters` registry are intercepted; imports from\n * unregistered specifiers pass through unchanged.\n */\nexport function lds(overrides: LdsAdapterRegistry = {}): Plugin {\n\tconst adapters = mergeWithDefaults(overrides);\n\t// Graphql specifiers are owned whole by the virtual module — every export\n\t// (adapters + `gql`) lives there, so the transform hook should not split\n\t// their imports. Non-graphql specifiers still go through transform so\n\t// unregistered names pass through to the real `lightning/*` module.\n\tconst graphqlSpecifiers = new Set<string>(\n\t\tObject.entries(adapters)\n\t\t\t.filter(([, moduleAdapters]) => isGraphqlSpecifier(moduleAdapters))\n\t\t\t.map(([specifier]) => specifier),\n\t);\n\tconst transformSpecifiers = Object.keys(adapters).filter((s) => !graphqlSpecifiers.has(s));\n\tconst specifierSnippets = transformSpecifiers.flatMap((s) => [`'${s}'`, `\"${s}\"`]);\n\n\treturn {\n\t\tname: \"vite-plugin-lds\",\n\t\tenforce: \"pre\",\n\n\t\tasync transform(code, id) {\n\t\t\tconst cleanId = id.split(\"?\")[0] ?? id;\n\t\t\tif (!cleanId.endsWith(\".js\") && !cleanId.endsWith(\".ts\")) return null;\n\t\t\tif (cleanId.includes(\"/node_modules/\")) return null;\n\t\t\tif (!specifierSnippets.some((snippet) => code.includes(snippet))) return null;\n\n\t\t\tawait init;\n\n\t\t\tlet imports: ReturnType<typeof parse>[0];\n\t\t\ttry {\n\t\t\t\t[imports] = parse(code);\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst relevant = imports.filter(\n\t\t\t\t(imp) =>\n\t\t\t\t\timp.d === -1 && imp.n !== undefined && imp.n in adapters && !graphqlSpecifiers.has(imp.n),\n\t\t\t);\n\t\t\tif (relevant.length === 0) return null;\n\n\t\t\tconst s = new MagicString(code);\n\t\t\tlet changed = false;\n\n\t\t\tfor (const imp of relevant) {\n\t\t\t\tconst { ss: start, se: end, n: specifier } = imp;\n\t\t\t\tconst statement = code.slice(start, end);\n\n\t\t\t\tconst openBrace = statement.indexOf(\"{\");\n\t\t\t\tconst closeBrace = statement.indexOf(\"}\");\n\t\t\t\tif (openBrace === -1 || closeBrace === -1) continue;\n\n\t\t\t\tconst bracesContent = statement.slice(openBrace + 1, closeBrace);\n\t\t\t\tconst moduleAdapters = adapters[specifier!]!;\n\t\t\t\tconst parsedImport = parseImportSpecifiers(bracesContent);\n\t\t\t\tconst registered = parsedImport.filter((p) => p.original in moduleAdapters);\n\t\t\t\tconst unregistered = parsedImport.filter((p) => !(p.original in moduleAdapters));\n\n\t\t\t\tif (registered.length === 0) continue;\n\n\t\t\t\tconst parts: string[] = [\n\t\t\t\t\t`import { ${registered.map((p) => p.full).join(\", \")} } from '${ADAPTER_PREFIX}${specifier}';`,\n\t\t\t\t];\n\n\t\t\t\tif (unregistered.length > 0) {\n\t\t\t\t\tparts.push(\n\t\t\t\t\t\t`import { ${unregistered.map((p) => p.full).join(\", \")} } from '${specifier}';`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\ts.overwrite(start, end, parts.join(\"\\n\"));\n\t\t\t\tchanged = true;\n\t\t\t}\n\n\t\t\tif (!changed) return null;\n\t\t\treturn { code: s.toString(), map: s.generateMap({ hires: true }) };\n\t\t},\n\n\t\tresolveId(id) {\n\t\t\t// Graphql specifiers are intercepted raw — no transform hook split\n\t\t\t// — and mapped into the same `\\0sf-lds-adapter:` virtual namespace\n\t\t\t// so the load hook emits one module per specifier.\n\t\t\tif (graphqlSpecifiers.has(id)) return ADAPTER_ID_PREFIX + id;\n\t\t\tif (id.startsWith(ADAPTER_PREFIX)) return ADAPTER_ID_PREFIX + id.slice(ADAPTER_PREFIX.length);\n\t\t\treturn null;\n\t\t},\n\n\t\tload(id) {\n\t\t\tif (!id.startsWith(ADAPTER_ID_PREFIX)) return null;\n\n\t\t\tconst specifier = id.slice(ADAPTER_ID_PREFIX.length);\n\t\t\tconst moduleAdapters = adapters[specifier];\n\t\t\tif (!moduleAdapters) return null;\n\n\t\t\t// create lines of code used to create MCP tool based adapters\n\t\t\tconst lines: string[] = [adapterBaseSource];\n\t\t\tfor (const [name, entry] of Object.entries(moduleAdapters)) {\n\t\t\t\tconst { type, ...cfg } = entry;\n\t\t\t\tlines.push(\n\t\t\t\t\t`export const ${name} = ${factoryFor(type)}(${JSON.stringify(name)}, ${JSON.stringify(cfg)});`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// `gql` rides along with any specifier that declares a graphql\n\t\t\t// adapter, so `import { gql } from 'lightning/graphql'` (or any\n\t\t\t// aliased form) keeps resolving even when no adapters are\n\t\t\t// imported alongside it. The binding itself is a private function\n\t\t\t// inside `adapterBaseSource` after `stripTopLevelExports`.\n\t\t\tif (graphqlSpecifiers.has(specifier)) {\n\t\t\t\tlines.push(\"export { gql };\");\n\t\t\t}\n\t\t\treturn lines.join(\"\\n\");\n\t\t},\n\t};\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { buildDefaultImperativeBindingsServiceDescriptor, buildQueryImperativeBindingsServiceDescriptor, buildSubscribableImperativeBindingsServiceDescriptor, buildLegacyImperativeBindingsServiceDescriptor } from "@conduit-client/service-bindings-imperative/v1";
2
2
  import { buildLWCWireBindingsServiceDescriptor } from "@conduit-client/service-bindings-lwc/v1";
3
3
  import { err, ok, toError, buildSubscribableResult } from "@conduit-client/utils";
4
- import { getChatSDK } from "@salesforce/sdk-chat";
4
+ import { getChatSDK } from "@salesforce/platform-sdk-chat";
5
5
  function normalizeMcpResponse(raw) {
6
6
  if (raw && typeof raw === "object" && "structuredContent" in raw) {
7
7
  return raw.structuredContent;
@@ -22,6 +22,22 @@ function normalizeMcpResponse(raw) {
22
22
  }
23
23
  return raw ?? {};
24
24
  }
25
+ function resolveMcpToolName(adapterName, cfg) {
26
+ const toolName = cfg.mcp?.toolName;
27
+ if (!toolName) {
28
+ throw new Error(`[${adapterName}] no dispatch backing configured — expected \`mcp.toolName\`.`);
29
+ }
30
+ return toolName;
31
+ }
32
+ async function getCallTool(adapterName) {
33
+ const sdk = await getChatSDK();
34
+ if (typeof sdk.callTool !== "function") {
35
+ throw new Error(
36
+ `[${adapterName}] sdk.callTool is not available on this surface. Make sure window.openai is configured or the component is running in an MCP Apps / OpenAI chat context.`
37
+ );
38
+ }
39
+ return sdk.callTool.bind(sdk);
40
+ }
25
41
  function extractToolErrorText(raw) {
26
42
  const content = raw.content;
27
43
  if (!Array.isArray(content)) return "";
@@ -41,15 +57,8 @@ class McpToolCommand {
41
57
  }
42
58
  async execute() {
43
59
  try {
44
- const app = await getChatSDK();
45
- if (!app.callTool) {
46
- return err(
47
- new Error(
48
- `[${this.adapterName}] sdk.callTool is not available on this surface. Make sure window.openai is configured or the component is running in an MCP Apps / OpenAI chat context.`
49
- )
50
- );
51
- }
52
- const raw = await app.callTool({
60
+ const callTool = await getCallTool(this.adapterName);
61
+ const raw = await callTool({
53
62
  toolName: this.toolName,
54
63
  params: this.params ?? void 0
55
64
  });
@@ -81,6 +90,13 @@ class McpToolSubscribableCommand {
81
90
  this.unwrap
82
91
  );
83
92
  const result = await base.execute();
93
+ const subscribers = /* @__PURE__ */ new Set();
94
+ const subscribe = (cb) => {
95
+ subscribers.add(cb);
96
+ return () => {
97
+ subscribers.delete(cb);
98
+ };
99
+ };
84
100
  const refresh = async () => {
85
101
  const next = await new McpToolCommand(
86
102
  this.adapterName,
@@ -88,9 +104,10 @@ class McpToolSubscribableCommand {
88
104
  this.params,
89
105
  this.unwrap
90
106
  ).execute();
107
+ subscribers.forEach((cb) => cb(next));
91
108
  return next.isOk() ? ok(void 0) : err(next.error);
92
109
  };
93
- return buildSubscribableResult(result, noopSubscribe, refresh);
110
+ return buildSubscribableResult(result, subscribe, refresh);
94
111
  }
95
112
  }
96
113
  const defaultImperativeService = buildDefaultImperativeBindingsServiceDescriptor().service;
@@ -98,23 +115,25 @@ const queryImperativeService = buildQueryImperativeBindingsServiceDescriptor().s
98
115
  const subscribableImperativeService = buildSubscribableImperativeBindingsServiceDescriptor().service;
99
116
  const legacyImperativeService = buildLegacyImperativeBindingsServiceDescriptor().service;
100
117
  function createMutationAdapter(name, cfg) {
118
+ const toolName = resolveMcpToolName(name, cfg);
101
119
  const getCommand = (options) => {
102
120
  options.assertIsValid(options.params[0], cfg.configJsonSchema);
103
- return new McpToolCommand(name, cfg.toolName, options.params[0]);
121
+ return new McpToolCommand(name, toolName, options.params[0]);
104
122
  };
105
123
  const invoker = defaultImperativeService.bind(getCommand);
106
124
  return (...params) => Promise.resolve(invoker(...params));
107
125
  }
108
126
  function createReadAdapter(name, cfg) {
127
+ const toolName = resolveMcpToolName(name, cfg);
109
128
  const getSubscribableCommand = (options) => {
110
129
  options.assertIsValid(options.params[0], cfg.configJsonSchema);
111
- return new McpToolSubscribableCommand(name, cfg.toolName, options.params[0]);
130
+ return new McpToolSubscribableCommand(name, toolName, options.params[0]);
112
131
  };
113
132
  switch (cfg.invokerShape) {
114
133
  case "query": {
115
134
  const getCommand = (options) => {
116
135
  options.assertIsValid(options.params[0], cfg.configJsonSchema);
117
- return new McpToolCommand(name, cfg.toolName, options.params[0]);
136
+ return new McpToolCommand(name, toolName, options.params[0]);
118
137
  };
119
138
  const invoker = queryImperativeService.bind(getCommand);
120
139
  return (...params) => Promise.resolve(invoker(...params));
@@ -136,7 +155,7 @@ function createReadAdapter(name, cfg) {
136
155
  case "legacy": {
137
156
  const getLegacyCommand = (options) => {
138
157
  options.assertIsValid(options.config, cfg.configJsonSchema);
139
- return new McpToolSubscribableCommand(name, cfg.toolName, options.config);
158
+ return new McpToolSubscribableCommand(name, toolName, options.config);
140
159
  };
141
160
  return legacyImperativeService.bind(getLegacyCommand);
142
161
  }
@@ -155,14 +174,155 @@ function unwrapWireEnvelope(payload) {
155
174
  return ok(envelope?.data);
156
175
  }
157
176
  function createWireAdapter(name, cfg) {
177
+ const toolName = resolveMcpToolName(name, cfg);
158
178
  return lwcWireBindingsService.bind(
159
- (config) => new McpToolCommand(name, cfg.toolName, config, unwrapWireEnvelope),
179
+ (config) => new McpToolCommand(name, toolName, config, unwrapWireEnvelope),
160
180
  cfg.configJsonSchema
161
181
  );
162
182
  }
183
+ function gql(strings, ...values) {
184
+ let result = "";
185
+ strings.forEach((string, i) => {
186
+ result += string;
187
+ if (i < values.length) result += String(values[i]);
188
+ });
189
+ return result.trim();
190
+ }
191
+ async function runGraphqlQuery(adapterName, toolName, config) {
192
+ const { query, variables } = config;
193
+ if (!query) return { data: void 0, errors: void 0 };
194
+ const callTool = await getCallTool(adapterName);
195
+ const raw = await callTool({
196
+ toolName,
197
+ params: { query, variables: variables ?? {} }
198
+ });
199
+ return normalizeMcpResponse(raw) ?? {};
200
+ }
201
+ function toGraphqlErrorResult(error) {
202
+ return { data: void 0, errors: [{ message: error.message }] };
203
+ }
204
+ async function runGraphqlQuerySafe(adapterName, toolName, config) {
205
+ try {
206
+ return await runGraphqlQuery(adapterName, toolName, config);
207
+ } catch (error) {
208
+ return toGraphqlErrorResult(error);
209
+ }
210
+ }
211
+ function createGraphQLWireAdapter(name, cfg) {
212
+ const toolName = resolveMcpToolName(name, cfg);
213
+ return class {
214
+ _dataCallback;
215
+ _config;
216
+ _connected = false;
217
+ constructor(dataCallback) {
218
+ this._dataCallback = dataCallback;
219
+ }
220
+ connect() {
221
+ this._connected = true;
222
+ void this._fetch();
223
+ }
224
+ disconnect() {
225
+ this._connected = false;
226
+ }
227
+ update(config) {
228
+ this._config = config;
229
+ if (!this._connected || this._config === void 0) {
230
+ return;
231
+ }
232
+ void this._fetch();
233
+ }
234
+ refresh() {
235
+ return this._fetch();
236
+ }
237
+ async _fetch() {
238
+ this._emit(await runGraphqlQuerySafe(name, toolName, this._config ?? {}));
239
+ }
240
+ _emit({ data, errors }) {
241
+ this._dataCallback({
242
+ data,
243
+ errors: errors?.length ? errors : void 0,
244
+ refresh: () => this.refresh()
245
+ });
246
+ }
247
+ };
248
+ }
249
+ function createGraphQLMutationAdapter(name, cfg) {
250
+ const toolName = resolveMcpToolName(name, cfg);
251
+ return async (config) => {
252
+ if (!config?.query) return { data: void 0, errors: [{ message: "No query provided" }] };
253
+ return runGraphqlQuerySafe(name, toolName, config);
254
+ };
255
+ }
256
+ function createGraphQLImperativeReadAdapter(name, cfg) {
257
+ const toolName = resolveMcpToolName(name, cfg);
258
+ if (cfg.invokerShape === "legacy") {
259
+ async function run(config, callback) {
260
+ if (!config?.query) {
261
+ callback({ data: void 0, errors: void 0 });
262
+ return;
263
+ }
264
+ const result = await runGraphqlQuerySafe(name, toolName, config);
265
+ callback({
266
+ data: result.data,
267
+ errors: result.errors?.length ? result.errors : void 0
268
+ });
269
+ }
270
+ return {
271
+ invoke(config, _context, callback) {
272
+ void run(config, callback);
273
+ },
274
+ subscribe(config, _context, callback) {
275
+ void run(config, callback);
276
+ return noopUnsubscribe;
277
+ }
278
+ };
279
+ }
280
+ if (cfg.invokerShape === "query-refreshable") {
281
+ return async (config) => {
282
+ const result = await runGraphqlQuerySafe(name, toolName, config);
283
+ if (result.errors?.length) {
284
+ return { data: void 0, errors: result.errors };
285
+ }
286
+ const subscribers = /* @__PURE__ */ new Set();
287
+ return {
288
+ data: result.data,
289
+ errors: void 0,
290
+ subscribe: (cb) => {
291
+ subscribers.add(cb);
292
+ return () => {
293
+ subscribers.delete(cb);
294
+ };
295
+ },
296
+ refresh: async () => {
297
+ const fresh = await runGraphqlQuerySafe(name, toolName, config);
298
+ const payload = {
299
+ data: fresh.data,
300
+ errors: fresh.errors?.length ? fresh.errors : void 0
301
+ };
302
+ subscribers.forEach((cb) => cb(payload));
303
+ }
304
+ };
305
+ };
306
+ }
307
+ return async (config) => {
308
+ const result = await runGraphqlQuerySafe(name, toolName, config);
309
+ if (result.errors?.length) {
310
+ return { data: void 0, errors: result.errors };
311
+ }
312
+ return {
313
+ data: result.data,
314
+ errors: void 0,
315
+ subscribe: noopSubscribe
316
+ };
317
+ };
318
+ }
163
319
  export {
320
+ createGraphQLImperativeReadAdapter,
321
+ createGraphQLMutationAdapter,
322
+ createGraphQLWireAdapter,
164
323
  createMutationAdapter,
165
324
  createReadAdapter,
166
- createWireAdapter
325
+ createWireAdapter,
326
+ gql
167
327
  };
168
328
  //# sourceMappingURL=runtime.js.map