@party-stack/salesforce-ontology 0.4.2 → 0.5.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.
- package/README.md +61 -68
- package/lib/adapter/backend.d.ts +15 -0
- package/lib/adapter/backend.d.ts.map +1 -0
- package/lib/adapter/backend.js +94 -0
- package/lib/adapter/backend.js.map +1 -0
- package/lib/adapter/index.d.ts +2 -4
- package/lib/adapter/index.js +2 -4
- package/lib/adapter/makeSalesforceOntologyBackend.d.ts +12 -0
- package/lib/adapter/makeSalesforceOntologyBackend.d.ts.map +1 -0
- package/lib/adapter/makeSalesforceOntologyBackend.js +186 -0
- package/lib/adapter/makeSalesforceOntologyBackend.js.map +1 -0
- package/lib/adapter/salesforceCodec.d.ts +1 -1
- package/lib/adapter/salesforceCodec.js.map +1 -1
- package/lib/adapter/salesforceObjectSearch.d.ts +15 -0
- package/lib/adapter/salesforceObjectSearch.d.ts.map +1 -0
- package/lib/adapter/salesforceObjectSearch.js +65 -0
- package/lib/adapter/salesforceObjectSearch.js.map +1 -0
- package/lib/adapter/soql.d.ts +17 -0
- package/lib/adapter/soql.d.ts.map +1 -0
- package/lib/adapter/soql.js +65 -0
- package/lib/adapter/soql.js.map +1 -0
- package/lib/config/index.d.ts +10 -7
- package/lib/config/index.d.ts.map +1 -1
- package/lib/config/index.js +63 -44
- package/lib/config/index.js.map +1 -1
- package/lib/connect.d.ts +18 -0
- package/lib/connect.d.ts.map +1 -0
- package/lib/connect.js +32 -0
- package/lib/connect.js.map +1 -0
- package/lib/connectionOptions.d.ts +10 -0
- package/lib/connectionOptions.d.ts.map +1 -0
- package/lib/connectionOptions.js +1 -0
- package/lib/index.d.ts +4 -7
- package/lib/index.js +3 -7
- package/lib/meta/{createSalesforceMetaOntologyBackendAdapter.d.ts → backend.d.ts} +5 -5
- package/lib/meta/backend.d.ts.map +1 -0
- package/lib/meta/backend.js +86 -0
- package/lib/meta/backend.js.map +1 -0
- package/lib/meta/convertMetaActionType.d.ts +3 -3
- package/lib/meta/convertMetaActionType.d.ts.map +1 -1
- package/lib/meta/convertMetaActionType.js.map +1 -1
- package/lib/meta/convertMetaLinkType.d.ts +2 -2
- package/lib/meta/convertMetaLinkType.d.ts.map +1 -1
- package/lib/meta/convertMetaLinkType.js.map +1 -1
- package/lib/meta/convertMetaLoadSubsetOptions.d.ts +2 -2
- package/lib/meta/convertMetaLoadSubsetOptions.d.ts.map +1 -1
- package/lib/meta/convertMetaLoadSubsetOptions.js +33 -33
- package/lib/meta/convertMetaLoadSubsetOptions.js.map +1 -1
- package/lib/meta/convertMetaObjectType.d.ts +2 -2
- package/lib/meta/convertMetaObjectType.d.ts.map +1 -1
- package/lib/meta/convertMetaObjectType.js.map +1 -1
- package/lib/meta/convertMetaQueryFunctionType.d.ts +1 -1
- package/lib/meta/convertMetaQueryFunctionType.js.map +1 -1
- package/lib/meta/convertMetaTypeDef.d.ts +1 -1
- package/lib/meta/convertMetaTypeDef.js.map +1 -1
- package/lib/meta/index.d.ts +2 -4
- package/lib/meta/index.js +3 -5
- package/lib/meta/loadActions.d.ts +15 -0
- package/lib/meta/loadActions.d.ts.map +1 -0
- package/lib/meta/loadActions.js +103 -0
- package/lib/meta/loadActions.js.map +1 -0
- package/lib/meta/loadEntities.d.ts +5 -0
- package/lib/meta/loadEntities.d.ts.map +1 -0
- package/lib/meta/loadEntities.js +14 -0
- package/lib/meta/loadEntities.js.map +1 -0
- package/lib/meta/loadQueryFunctions.d.ts +11 -0
- package/lib/meta/loadQueryFunctions.d.ts.map +1 -0
- package/lib/meta/loadQueryFunctions.js +43 -0
- package/lib/meta/loadQueryFunctions.js.map +1 -0
- package/lib/meta/synthesizeCrudActionTypes.d.ts +2 -2
- package/lib/meta/synthesizeCrudActionTypes.d.ts.map +1 -1
- package/lib/meta/synthesizeCrudActionTypes.js.map +1 -1
- package/lib/serviceConnector.d.ts +8 -0
- package/lib/serviceConnector.d.ts.map +1 -0
- package/lib/serviceConnector.js +125 -0
- package/lib/serviceConnector.js.map +1 -0
- package/lib/utils/AsyncIterable.d.ts +1 -1
- package/lib/utils/AsyncIterable.d.ts.map +1 -1
- package/lib/utils/AsyncIterable.js +11 -0
- package/lib/utils/AsyncIterable.js.map +1 -1
- package/package.json +15 -19
- package/lib/adapter/convertLoadSubsetOptions.d.ts +0 -20
- package/lib/adapter/convertLoadSubsetOptions.d.ts.map +0 -1
- package/lib/adapter/convertLoadSubsetOptions.js +0 -127
- package/lib/adapter/convertLoadSubsetOptions.js.map +0 -1
- package/lib/adapter/createSalesforceOntologyBackendAdapter.d.ts +0 -22
- package/lib/adapter/createSalesforceOntologyBackendAdapter.d.ts.map +0 -1
- package/lib/adapter/createSalesforceOntologyBackendAdapter.js +0 -139
- package/lib/adapter/createSalesforceOntologyBackendAdapter.js.map +0 -1
- package/lib/adapter/objectCollectionOptions.d.ts +0 -36
- package/lib/adapter/objectCollectionOptions.d.ts.map +0 -1
- package/lib/adapter/objectCollectionOptions.js +0 -204
- package/lib/adapter/objectCollectionOptions.js.map +0 -1
- package/lib/connection.d.ts +0 -45
- package/lib/connection.d.ts.map +0 -1
- package/lib/connection.js +0 -258
- package/lib/connection.js.map +0 -1
- package/lib/installation/createSalesforceBackendInstallation.d.ts +0 -37
- package/lib/installation/createSalesforceBackendInstallation.d.ts.map +0 -1
- package/lib/installation/createSalesforceBackendInstallation.js +0 -84
- package/lib/installation/createSalesforceBackendInstallation.js.map +0 -1
- package/lib/installation/index.d.ts +0 -2
- package/lib/installation/index.js +0 -1
- package/lib/meta/actionTypeCollectionOptions.d.ts +0 -15
- package/lib/meta/actionTypeCollectionOptions.d.ts.map +0 -1
- package/lib/meta/actionTypeCollectionOptions.js +0 -121
- package/lib/meta/actionTypeCollectionOptions.js.map +0 -1
- package/lib/meta/createSalesforceMetaOntologyBackendAdapter.d.ts.map +0 -1
- package/lib/meta/createSalesforceMetaOntologyBackendAdapter.js +0 -42
- package/lib/meta/createSalesforceMetaOntologyBackendAdapter.js.map +0 -1
- package/lib/meta/entityCollectionOptions.d.ts +0 -16
- package/lib/meta/entityCollectionOptions.d.ts.map +0 -1
- package/lib/meta/entityCollectionOptions.js +0 -81
- package/lib/meta/entityCollectionOptions.js.map +0 -1
- package/lib/meta/queryFunctionTypeCollectionOptions.d.ts +0 -11
- package/lib/meta/queryFunctionTypeCollectionOptions.d.ts.map +0 -1
- package/lib/meta/queryFunctionTypeCollectionOptions.js +0 -59
- package/lib/meta/queryFunctionTypeCollectionOptions.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadActions.js","names":[],"sources":["../../src/meta/loadActions.ts"],"sourcesContent":["import { classifySalesforceStandardAction } from \"../standardActions.js\";\nimport { salesforceCrudActionTypeId, salesforceCrudActionTypeName } from \"../utils/ids.js\";\nimport {\n convertSalesforceMetaActionType,\n convertSalesforceMetaStandardActionType,\n} from \"./convertMetaActionType.js\";\nimport { matchesMetaNameQuery } from \"./convertMetaLoadSubsetOptions.js\";\nimport { synthesizeSalesforceCrudActionTypes } from \"./synthesizeCrudActionTypes.js\";\nimport type { SalesforceCrudActionTypeSelection } from \"../crud.js\";\nimport type { MetaNameQuery } from \"./convertMetaLoadSubsetOptions.js\";\nimport type { ActionType as MetaActionType } from \"@party-stack/ontology-spec/meta\";\nimport type { Query } from \"@party-stack/ontology-storage\";\nimport type {\n SalesforceClient,\n SalesforceInvocableActionDescribe,\n SalesforceInvocableActionListResponse,\n SalesforceInvocableActionSummary,\n SalesforceSObjectDescribe,\n} from \"@party-stack/salesforce-client\";\n\nexport interface ActionTypeLoadOptions {\n client: SalesforceClient;\n flowActionTypeNames?: string[];\n standardActionTypeNames?: string[];\n crudActionTypes?: readonly SalesforceCrudActionTypeSelection[];\n}\n\nfunction normalizeFlowActionList(\n response: SalesforceInvocableActionListResponse\n): SalesforceInvocableActionSummary[] {\n if (Array.isArray(response)) {\n return response;\n }\n if (typeof response === \"object\" && response !== null && \"actions\" in response) {\n return Array.isArray(response.actions) ? response.actions : [];\n }\n // Some Salesforce responses return a map of actionName -> url.\n return Object.keys(response).map((name) => ({ name }));\n}\n\nasync function loadFlowActionDescribe(\n client: SalesforceClient,\n apiName: string\n): Promise<SalesforceInvocableActionDescribe | undefined> {\n try {\n return await client.describeFlowAction(apiName);\n } catch {\n // Skip inaccessible or non-autolaunched flows.\n return undefined;\n }\n}\n\nasync function loadStandardActionDescribe(\n client: SalesforceClient,\n apiName: string\n): Promise<SalesforceInvocableActionDescribe | undefined> {\n try {\n return await client.describeStandardAction(apiName);\n } catch {\n // Skip standard actions unavailable to this user.\n return undefined;\n }\n}\n\nasync function loadFlowActionDescribes(\n client: SalesforceClient,\n names: readonly string[]\n): Promise<Array<SalesforceInvocableActionDescribe | undefined>> {\n if (typeof client.describeFlowActions === \"function\") {\n try {\n return await client.describeFlowActions(names);\n } catch {\n // Older Salesforce orgs may not expose Composite API access.\n }\n }\n return Promise.all(names.map((name) => loadFlowActionDescribe(client, name)));\n}\n\nasync function loadStandardActionDescribes(\n client: SalesforceClient,\n names: readonly string[]\n): Promise<Array<SalesforceInvocableActionDescribe | undefined>> {\n if (typeof client.describeStandardActions === \"function\") {\n try {\n return await client.describeStandardActions(names);\n } catch {\n // Older Salesforce orgs may not expose Composite API access.\n }\n }\n return Promise.all(names.map((name) => loadStandardActionDescribe(client, name)));\n}\n\nasync function loadSelectedActionDescribes(\n client: SalesforceClient,\n flowNames: readonly string[],\n standardNames: readonly string[]\n): Promise<\n [\n Array<SalesforceInvocableActionDescribe | undefined>,\n Array<SalesforceInvocableActionDescribe | undefined>,\n ]\n> {\n if (typeof client.describeInvocableActions === \"function\") {\n try {\n const combined = await client.describeInvocableActions([\n ...flowNames.map((apiName) => ({\n kind: \"flow\" as const,\n apiName,\n })),\n ...standardNames.map((apiName) => ({\n kind: \"standard\" as const,\n apiName,\n })),\n ]);\n return [combined.slice(0, flowNames.length), combined.slice(flowNames.length)];\n } catch {\n // Fall through to subsystem-specific compatibility methods.\n }\n }\n return Promise.all([\n flowNames.length > 0 ? loadFlowActionDescribes(client, flowNames) : [],\n standardNames.length > 0 ? loadStandardActionDescribes(client, standardNames) : [],\n ]);\n}\n\nexport async function loadSalesforceActionTypes(\n opts: ActionTypeLoadOptions,\n query: MetaNameQuery = { type: \"list\" },\n window?: Pick<Query, \"offset\" | \"limit\">\n): Promise<MetaActionType[]> {\n const describeCache = new Map<string, ReturnType<typeof loadSelectedActionDescribes>>();\n const requestedNames = query.type === \"getBatch\" ? new Set(query.names) : undefined;\n const configuredCrudNames = new Set(\n (opts.crudActionTypes ?? []).flatMap((selection) =>\n selection.operations.map((operation) =>\n salesforceCrudActionTypeName(operation, selection.objectType)\n )\n )\n );\n const [flowSummaries, standardSummaries] = await Promise.all([\n opts.flowActionTypeNames || requestedNames\n ? Promise.resolve(undefined)\n : opts.client.listFlowActions().then(normalizeFlowActionList),\n opts.standardActionTypeNames || requestedNames\n ? Promise.resolve(undefined)\n : opts.client.listStandardActions().then(normalizeFlowActionList),\n ]);\n const candidates: Array<{\n kind: \"flow\" | \"standard\";\n name: string;\n displayName: string;\n }> = [\n ...(\n opts.flowActionTypeNames ??\n (requestedNames\n ? [...requestedNames].filter((name) => !configuredCrudNames.has(name))\n : (flowSummaries?.map((summary) => summary.name) ?? []))\n ).map((name) => ({\n kind: \"flow\" as const,\n name,\n displayName: flowSummaries?.find((summary) => summary.name === name)?.label ?? name,\n })),\n ...(\n opts.standardActionTypeNames ??\n (requestedNames\n ? [...requestedNames].filter((name) => !configuredCrudNames.has(name))\n : (standardSummaries\n ?.filter((summary) => classifySalesforceStandardAction(summary.name) === \"action\")\n .map((summary) => summary.name) ?? []))\n ).map((name) => ({\n kind: \"standard\" as const,\n name,\n displayName: standardSummaries?.find((summary) => summary.name === name)?.label ?? name,\n })),\n ];\n const matchingCandidates =\n query.type === \"search\"\n ? candidates.filter((candidate) => matchesMetaNameQuery(query, candidate))\n : candidates;\n matchingCandidates.sort((left, right) => left.name.localeCompare(right.name));\n const offset = Math.max(0, Math.trunc(window?.offset ?? 0));\n const limit = window?.limit;\n const selectedCandidates = requestedNames\n ? matchingCandidates\n : matchingCandidates.slice(\n offset,\n limit === undefined ? undefined : offset + Math.max(0, Math.trunc(limit))\n );\n const names = selectedCandidates\n .filter((candidate) => candidate.kind === \"flow\")\n .map((candidate) => candidate.name);\n const standardNames = selectedCandidates\n .filter((candidate) => candidate.kind === \"standard\")\n .map((candidate) => candidate.name);\n const describeCacheKey = JSON.stringify([names, standardNames]);\n let cached = describeCache.get(describeCacheKey);\n if (!cached) {\n cached = loadSelectedActionDescribes(opts.client, names, standardNames);\n describeCache.set(describeCacheKey, cached);\n }\n const [describes, rawStandardDescribes] = await cached;\n const standardDescribes = rawStandardDescribes.filter(\n (describe): describe is SalesforceInvocableActionDescribe =>\n Boolean(describe) &&\n (opts.standardActionTypeNames !== undefined ||\n classifySalesforceStandardAction(describe!.name) === \"action\")\n );\n const flowDescribes = describes.filter((describe): describe is SalesforceInvocableActionDescribe =>\n Boolean(describe)\n );\n const sObjectNames = new Set((opts.crudActionTypes ?? []).map((selection) => selection.objectType));\n for (const describe of [...flowDescribes, ...standardDescribes]) {\n for (const input of describe.inputs ?? []) {\n const sObjectType = input.sobjectType ?? input.sObjectType;\n if (input.type?.toLowerCase() === \"sobject\" && sObjectType) {\n sObjectNames.add(sObjectType);\n }\n }\n }\n const sObjectDescribes = new Map<string, SalesforceSObjectDescribe>(\n await Promise.all(\n [...sObjectNames].map(async (name) => [name, await opts.client.describeSObject(name)] as const)\n )\n );\n const flowActions = flowDescribes.map((describe) =>\n convertSalesforceMetaActionType(describe, sObjectDescribes)\n );\n const standardActions = standardDescribes.map((describe) =>\n convertSalesforceMetaStandardActionType(describe, sObjectDescribes)\n );\n const crudActions = (opts.crudActionTypes ?? []).flatMap((selection) => {\n const describe = sObjectDescribes.get(selection.objectType);\n return describe\n ? synthesizeSalesforceCrudActionTypes(describe).filter(\n (action) =>\n (!requestedNames || requestedNames.has(action.name)) &&\n matchesMetaNameQuery(query, action) &&\n selection.operations.some(\n (operation) =>\n action.id === salesforceCrudActionTypeId(operation, selection.objectType)\n )\n )\n : [];\n });\n const actions = new Map([...flowActions, ...standardActions].map((action) => [action.name, action]));\n for (const action of crudActions) {\n if (actions.has(action.name)) {\n throw new Error(`Multiple Salesforce actions use ontology name \"${action.name}\".`);\n }\n actions.set(action.name, action);\n }\n return [...actions.values()];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SalesforceClient, SalesforceSObjectDescribe } from "@party-stack/salesforce-client";
|
|
2
|
+
//#region src/meta/loadEntities.d.ts
|
|
3
|
+
export declare function describeSObjects(client: SalesforceClient, names: readonly string[]): Promise<SalesforceSObjectDescribe[]>;
|
|
4
|
+
//#endregion
|
|
5
|
+
//# sourceMappingURL=loadEntities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadEntities.d.ts","names":[],"sources":["../../src/meta/loadEntities.ts"],"mappings":";;wBAEsB,iBAClB,QAAQ,kBACR,2BACD,QAAQ"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/meta/loadEntities.ts
|
|
2
|
+
async function describeSObjects(client, names) {
|
|
3
|
+
return (await Promise.all([...new Set(names)].map(async (name) => {
|
|
4
|
+
try {
|
|
5
|
+
return await client.describeSObject(name);
|
|
6
|
+
} catch {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
}))).filter((describe) => Boolean(describe));
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { describeSObjects };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=loadEntities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadEntities.js","names":[],"sources":["../../src/meta/loadEntities.ts"],"sourcesContent":["import type { SalesforceClient, SalesforceSObjectDescribe } from \"@party-stack/salesforce-client\";\n\nexport async function describeSObjects(\n client: SalesforceClient,\n names: readonly string[]\n): Promise<SalesforceSObjectDescribe[]> {\n const describes = await Promise.all(\n [...new Set(names)].map(async (name) => {\n try {\n return await client.describeSObject(name);\n } catch {\n return undefined;\n }\n })\n );\n return describes.filter((describe): describe is SalesforceSObjectDescribe => Boolean(describe));\n}\n"],"mappings":";AAEA,eAAsB,iBAClB,QACA,OACoC;CAUpC,QAAO,MATiB,QAAQ,IAC5B,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,SAAS;EACpC,IAAI;GACA,OAAO,MAAM,OAAO,gBAAgB,IAAI;EAC5C,QAAQ;GACJ;EACJ;CACJ,CAAC,CACL,EAAA,CACiB,QAAQ,aAAoD,QAAQ,QAAQ,CAAC;AAClG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MetaNameQuery } from "./convertMetaLoadSubsetOptions.js";
|
|
2
|
+
import { SalesforceClient } from "@party-stack/salesforce-client";
|
|
3
|
+
import { Query } from "@party-stack/ontology-storage";
|
|
4
|
+
import { QueryFunctionTypeDef } from "@party-stack/ontology-spec";
|
|
5
|
+
//#region src/meta/loadQueryFunctions.d.ts
|
|
6
|
+
export declare function loadSalesforceQueryFunctionTypes(opts: {
|
|
7
|
+
client: SalesforceClient;
|
|
8
|
+
standardQueryFunctionTypeNames?: string[];
|
|
9
|
+
}, query?: MetaNameQuery, window?: Pick<Query, "offset" | "limit">): Promise<QueryFunctionTypeDef[]>;
|
|
10
|
+
//#endregion
|
|
11
|
+
//# sourceMappingURL=loadQueryFunctions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadQueryFunctions.d.ts","names":[],"sources":["../../src/meta/loadQueryFunctions.ts"],"mappings":";;;;;wBAmCsB,iCAClB;EAAQ,QAAQ;EAAkB;GAClC,QAAO,eACP,SAAS,KAAK,6BACf,QAAQ"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { matchesMetaNameQuery } from "./convertMetaLoadSubsetOptions.js";
|
|
2
|
+
import { classifySalesforceStandardAction } from "../standardActions.js";
|
|
3
|
+
import { convertSalesforceMetaStandardQueryFunctionType } from "./convertMetaQueryFunctionType.js";
|
|
4
|
+
//#region src/meta/loadQueryFunctions.ts
|
|
5
|
+
async function describeStandardActions(client, names) {
|
|
6
|
+
if (typeof client.describeStandardActions === "function") try {
|
|
7
|
+
return await client.describeStandardActions(names);
|
|
8
|
+
} catch {}
|
|
9
|
+
return Promise.all(names.map(async (name) => {
|
|
10
|
+
try {
|
|
11
|
+
return await client.describeStandardAction(name);
|
|
12
|
+
} catch {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
async function loadSalesforceQueryFunctionTypes(opts, query = { type: "list" }, window) {
|
|
18
|
+
let summaries;
|
|
19
|
+
if (query.type !== "getBatch" && !opts.standardQueryFunctionTypeNames) {
|
|
20
|
+
const response = await opts.client.listStandardActions();
|
|
21
|
+
summaries = Array.isArray(response) ? response : Array.isArray(response.actions) ? response.actions : Object.keys(response).map((name) => ({ name }));
|
|
22
|
+
}
|
|
23
|
+
const requestedNames = query.type === "getBatch" ? new Set(query.names) : void 0;
|
|
24
|
+
const candidates = (opts.standardQueryFunctionTypeNames ?? (requestedNames ? [...requestedNames] : summaries?.map((summary) => summary.name) ?? [])).filter((name) => (!requestedNames || requestedNames.has(name)) && (opts.standardQueryFunctionTypeNames !== void 0 || classifySalesforceStandardAction(name) === "queryFunction")).map((name) => ({
|
|
25
|
+
name,
|
|
26
|
+
displayName: summaries?.find((summary) => summary.name === name)?.label ?? name
|
|
27
|
+
})).filter((candidate) => matchesMetaNameQuery(query, candidate));
|
|
28
|
+
const offset = Math.max(0, Math.trunc(window?.offset ?? 0));
|
|
29
|
+
const limit = window?.limit;
|
|
30
|
+
const names = (requestedNames ? candidates : candidates.slice(offset, limit === void 0 ? void 0 : offset + Math.max(0, Math.trunc(limit)))).map((candidate) => candidate.name);
|
|
31
|
+
const describes = (await describeStandardActions(opts.client, names)).filter((describe) => Boolean(describe));
|
|
32
|
+
const sObjectNames = /* @__PURE__ */ new Set();
|
|
33
|
+
for (const describe of describes) for (const parameter of [...describe.inputs ?? [], ...describe.outputs ?? []]) {
|
|
34
|
+
const name = parameter.sobjectType ?? parameter.sObjectType;
|
|
35
|
+
if (name) sObjectNames.add(name);
|
|
36
|
+
}
|
|
37
|
+
const sObjectDescribes = new Map(await Promise.all([...sObjectNames].map(async (name) => [name, await opts.client.describeSObject(name)])));
|
|
38
|
+
return describes.map((describe) => convertSalesforceMetaStandardQueryFunctionType(describe, sObjectDescribes));
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { loadSalesforceQueryFunctionTypes };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=loadQueryFunctions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadQueryFunctions.js","names":[],"sources":["../../src/meta/loadQueryFunctions.ts"],"sourcesContent":["import { classifySalesforceStandardAction } from \"../standardActions.js\";\nimport { matchesMetaNameQuery } from \"./convertMetaLoadSubsetOptions.js\";\nimport { convertSalesforceMetaStandardQueryFunctionType } from \"./convertMetaQueryFunctionType.js\";\nimport type { MetaNameQuery } from \"./convertMetaLoadSubsetOptions.js\";\nimport type { QueryFunctionTypeDef } from \"@party-stack/ontology-spec\";\nimport type { Query } from \"@party-stack/ontology-storage\";\nimport type {\n SalesforceClient,\n SalesforceInvocableActionDescribe,\n SalesforceInvocableActionSummary,\n SalesforceSObjectDescribe,\n} from \"@party-stack/salesforce-client\";\n\nasync function describeStandardActions(\n client: SalesforceClient,\n names: readonly string[]\n): Promise<Array<SalesforceInvocableActionDescribe | undefined>> {\n if (typeof client.describeStandardActions === \"function\") {\n try {\n return await client.describeStandardActions(names);\n } catch {\n // Fall through when Composite API access is unavailable.\n }\n }\n return Promise.all(\n names.map(async (name) => {\n try {\n return await client.describeStandardAction(name);\n } catch {\n return undefined;\n }\n })\n );\n}\n\nexport async function loadSalesforceQueryFunctionTypes(\n opts: { client: SalesforceClient; standardQueryFunctionTypeNames?: string[] },\n query: MetaNameQuery = { type: \"list\" },\n window?: Pick<Query, \"offset\" | \"limit\">\n): Promise<QueryFunctionTypeDef[]> {\n let summaries: SalesforceInvocableActionSummary[] | undefined;\n if (query.type !== \"getBatch\" && !opts.standardQueryFunctionTypeNames) {\n const response = await opts.client.listStandardActions();\n summaries = Array.isArray(response)\n ? response\n : Array.isArray(response.actions)\n ? response.actions\n : Object.keys(response).map((name) => ({ name }));\n }\n const requestedNames = query.type === \"getBatch\" ? new Set(query.names) : undefined;\n const candidates = (\n opts.standardQueryFunctionTypeNames ??\n (requestedNames ? [...requestedNames] : (summaries?.map((summary) => summary.name) ?? []))\n )\n .filter(\n (name) =>\n (!requestedNames || requestedNames.has(name)) &&\n (opts.standardQueryFunctionTypeNames !== undefined ||\n classifySalesforceStandardAction(name) === \"queryFunction\")\n )\n .map((name) => ({\n name,\n displayName: summaries?.find((summary) => summary.name === name)?.label ?? name,\n }))\n .filter((candidate) => matchesMetaNameQuery(query, candidate));\n const offset = Math.max(0, Math.trunc(window?.offset ?? 0));\n const limit = window?.limit;\n const names = (\n requestedNames\n ? candidates\n : candidates.slice(\n offset,\n limit === undefined ? undefined : offset + Math.max(0, Math.trunc(limit))\n )\n ).map((candidate) => candidate.name);\n const describes = (await describeStandardActions(opts.client, names)).filter(\n (describe): describe is SalesforceInvocableActionDescribe => Boolean(describe)\n );\n const sObjectNames = new Set<string>();\n for (const describe of describes) {\n for (const parameter of [...(describe.inputs ?? []), ...(describe.outputs ?? [])]) {\n const name = parameter.sobjectType ?? parameter.sObjectType;\n if (name) sObjectNames.add(name);\n }\n }\n const sObjectDescribes = new Map<string, SalesforceSObjectDescribe>(\n await Promise.all(\n [...sObjectNames].map(async (name) => [name, await opts.client.describeSObject(name)] as const)\n )\n );\n return describes.map((describe) =>\n convertSalesforceMetaStandardQueryFunctionType(describe, sObjectDescribes)\n );\n}\n"],"mappings":";;;;AAaA,eAAe,wBACX,QACA,OAC6D;CAC7D,IAAI,OAAO,OAAO,4BAA4B,YAC1C,IAAI;EACA,OAAO,MAAM,OAAO,wBAAwB,KAAK;CACrD,QAAQ,CAER;CAEJ,OAAO,QAAQ,IACX,MAAM,IAAI,OAAO,SAAS;EACtB,IAAI;GACA,OAAO,MAAM,OAAO,uBAAuB,IAAI;EACnD,QAAQ;GACJ;EACJ;CACJ,CAAC,CACL;AACJ;AAEA,eAAsB,iCAClB,MACA,QAAuB,EAAE,MAAM,OAAO,GACtC,QAC+B;CAC/B,IAAI;CACJ,IAAI,MAAM,SAAS,cAAc,CAAC,KAAK,gCAAgC;EACnE,MAAM,WAAW,MAAM,KAAK,OAAO,oBAAoB;EACvD,YAAY,MAAM,QAAQ,QAAQ,IAC5B,WACA,MAAM,QAAQ,SAAS,OAAO,IAC5B,SAAS,UACT,OAAO,KAAK,QAAQ,CAAC,CAAC,KAAK,UAAU,EAAE,KAAK,EAAE;CAC1D;CACA,MAAM,iBAAiB,MAAM,SAAS,aAAa,IAAI,IAAI,MAAM,KAAK,IAAI,KAAA;CAC1E,MAAM,cACF,KAAK,mCACJ,iBAAiB,CAAC,GAAG,cAAc,IAAK,WAAW,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,GAAA,CAEtF,QACI,UACI,CAAC,kBAAkB,eAAe,IAAI,IAAI,OAC1C,KAAK,mCAAmC,KAAA,KACrC,iCAAiC,IAAI,MAAM,gBACvD,CAAC,CACA,KAAK,UAAU;EACZ;EACA,aAAa,WAAW,MAAM,YAAY,QAAQ,SAAS,IAAI,CAAC,EAAE,SAAS;CAC/E,EAAE,CAAC,CACF,QAAQ,cAAc,qBAAqB,OAAO,SAAS,CAAC;CACjE,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,UAAU,CAAC,CAAC;CAC1D,MAAM,QAAQ,QAAQ;CACtB,MAAM,SACF,iBACM,aACA,WAAW,MACP,QACA,UAAU,KAAA,IAAY,KAAA,IAAY,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,CAC5E,EAAA,CACR,KAAK,cAAc,UAAU,IAAI;CACnC,MAAM,aAAa,MAAM,wBAAwB,KAAK,QAAQ,KAAK,EAAA,CAAG,QACjE,aAA4D,QAAQ,QAAQ,CACjF;CACA,MAAM,+BAAe,IAAI,IAAY;CACrC,KAAK,MAAM,YAAY,WACnB,KAAK,MAAM,aAAa,CAAC,GAAI,SAAS,UAAU,CAAC,GAAI,GAAI,SAAS,WAAW,CAAC,CAAE,GAAG;EAC/E,MAAM,OAAO,UAAU,eAAe,UAAU;EAChD,IAAI,MAAM,aAAa,IAAI,IAAI;CACnC;CAEJ,MAAM,mBAAmB,IAAI,IACzB,MAAM,QAAQ,IACV,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,OAAO,SAAS,CAAC,MAAM,MAAM,KAAK,OAAO,gBAAgB,IAAI,CAAC,CAAU,CAClG,CACJ;CACA,OAAO,UAAU,KAAK,aAClB,+CAA+C,UAAU,gBAAgB,CAC7E;AACJ"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SalesforceSObjectDescribe } from "@party-stack/salesforce-client";
|
|
2
|
-
import {
|
|
2
|
+
import { ActionType } from "@party-stack/ontology-spec/meta";
|
|
3
3
|
//#region src/meta/synthesizeCrudActionTypes.d.ts
|
|
4
|
-
export declare function synthesizeSalesforceCrudActionTypes(describe: SalesforceSObjectDescribe):
|
|
4
|
+
export declare function synthesizeSalesforceCrudActionTypes(describe: SalesforceSObjectDescribe): ActionType[];
|
|
5
5
|
//#endregion
|
|
6
6
|
//# sourceMappingURL=synthesizeCrudActionTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesizeCrudActionTypes.d.ts","names":[],"sources":["../../src/meta/synthesizeCrudActionTypes.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"synthesizeCrudActionTypes.d.ts","names":["MetaActionType"],"sources":["../../src/meta/synthesizeCrudActionTypes.ts"],"mappings":";;;wBAkGgB,oCAAoC,UAAU,4BAA4BA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesizeCrudActionTypes.js","names":[],"sources":["../../src/meta/synthesizeCrudActionTypes.ts"],"sourcesContent":["import { salesforceActionMeta } from \"../actionMetadata.js\";\nimport {\n salesforceCrudActionTypeId,\n salesforceCrudActionTypeName,\n type SalesforceCrudOperation,\n} from \"../utils/ids.js\";\nimport { convertSalesforceFieldType } from \"./convertMetaTypeDef.js\";\nimport type {
|
|
1
|
+
{"version":3,"file":"synthesizeCrudActionTypes.js","names":[],"sources":["../../src/meta/synthesizeCrudActionTypes.ts"],"sourcesContent":["import { salesforceActionMeta } from \"../actionMetadata.js\";\nimport {\n salesforceCrudActionTypeId,\n salesforceCrudActionTypeName,\n type SalesforceCrudOperation,\n} from \"../utils/ids.js\";\nimport { convertSalesforceFieldType } from \"./convertMetaTypeDef.js\";\nimport type { TypeDef } from \"@party-stack/ontology-spec\";\nimport type { ActionType as MetaActionType } from \"@party-stack/ontology-spec/meta\";\nimport type { SalesforceFieldDescribe, SalesforceSObjectDescribe } from \"@party-stack/salesforce-client\";\n\nconst COMPOUND_PARENT_TYPES = new Set([\"address\", \"location\"]);\n\nfunction optional(type: TypeDef): TypeDef {\n return type.kind === \"optional\" ? type : { kind: \"optional\", value: { type } };\n}\n\nfunction writableFieldParameter(field: SalesforceFieldDescribe, operation: \"create\" | \"update\") {\n let type = convertSalesforceFieldType(field);\n if (operation === \"update\" || (operation === \"create\" && field.defaultedOnCreate)) {\n type = optional(type);\n }\n return {\n name: field.name,\n displayName: field.label || field.name,\n description: field.inlineHelpText ?? undefined,\n type,\n };\n}\n\nfunction action(\n describe: SalesforceSObjectDescribe,\n operation: SalesforceCrudOperation,\n parameters: MetaActionType[\"parameters\"]\n): MetaActionType {\n const verb = operation === \"create\" ? \"Create\" : operation === \"update\" ? \"Update\" : \"Delete\";\n const values = parameters\n .filter((parameter) => parameter.name !== \"recordId\")\n .map((parameter) => ({\n property: [parameter.name],\n value: {\n kind: \"inputReference\" as const,\n value: { name: parameter.name },\n },\n }));\n const logic: MetaActionType[\"logic\"] =\n operation === \"create\"\n ? [\n {\n kind: \"createObject\",\n value: {\n objectType: describe.name,\n values,\n },\n },\n ]\n : operation === \"update\"\n ? [\n {\n kind: \"updateObject\",\n value: {\n object: {\n name: \"recordId\",\n },\n values,\n },\n },\n ]\n : [\n {\n kind: \"deleteObject\",\n value: {\n object: {\n name: \"recordId\",\n },\n },\n },\n ];\n return {\n id: salesforceCrudActionTypeId(operation, describe.name),\n meta: salesforceActionMeta({\n kind: \"crud\",\n objectType: describe.name,\n operation,\n }),\n name: salesforceCrudActionTypeName(operation, describe.name),\n displayName: `${verb} ${describe.label}`,\n parameters,\n logic,\n };\n}\n\nfunction isWritableField(field: SalesforceFieldDescribe, operation: \"create\" | \"update\"): boolean {\n if (COMPOUND_PARENT_TYPES.has(field.type)) return false;\n if (field.calculated || field.autoNumber) return false;\n return operation === \"create\" ? field.createable : field.updateable;\n}\n\nexport function synthesizeSalesforceCrudActionTypes(describe: SalesforceSObjectDescribe): MetaActionType[] {\n const actions: MetaActionType[] = [];\n if (describe.createable) {\n actions.push(\n action(\n describe,\n \"create\",\n describe.fields\n .filter((field) => isWritableField(field, \"create\"))\n .map((field) => writableFieldParameter(field, \"create\"))\n )\n );\n }\n if (describe.updateable) {\n actions.push(\n action(describe, \"update\", [\n {\n name: \"recordId\",\n displayName: `${describe.label} ID`,\n type: {\n kind: \"objectReference\",\n value: { objectType: describe.name },\n },\n },\n ...describe.fields\n .filter((field) => isWritableField(field, \"update\"))\n .map((field) => writableFieldParameter(field, \"update\")),\n ])\n );\n }\n if (describe.deletable) {\n actions.push(\n action(describe, \"delete\", [\n {\n name: \"recordId\",\n displayName: `${describe.label} ID`,\n type: {\n kind: \"objectReference\",\n value: { objectType: describe.name },\n },\n },\n ])\n );\n }\n return actions;\n}\n"],"mappings":";;;;AAWA,MAAM,wCAAwB,IAAI,IAAI,CAAC,WAAW,UAAU,CAAC;AAE7D,SAAS,SAAS,MAAwB;CACtC,OAAO,KAAK,SAAS,aAAa,OAAO;EAAE,MAAM;EAAY,OAAO,EAAE,KAAK;CAAE;AACjF;AAEA,SAAS,uBAAuB,OAAgC,WAAgC;CAC5F,IAAI,OAAO,2BAA2B,KAAK;CAC3C,IAAI,cAAc,YAAa,cAAc,YAAY,MAAM,mBAC3D,OAAO,SAAS,IAAI;CAExB,OAAO;EACH,MAAM,MAAM;EACZ,aAAa,MAAM,SAAS,MAAM;EAClC,aAAa,MAAM,kBAAkB,KAAA;EACrC;CACJ;AACJ;AAEA,SAAS,OACL,UACA,WACA,YACc;CACd,MAAM,OAAO,cAAc,WAAW,WAAW,cAAc,WAAW,WAAW;CACrF,MAAM,SAAS,WACV,QAAQ,cAAc,UAAU,SAAS,UAAU,CAAC,CACpD,KAAK,eAAe;EACjB,UAAU,CAAC,UAAU,IAAI;EACzB,OAAO;GACH,MAAM;GACN,OAAO,EAAE,MAAM,UAAU,KAAK;EAClC;CACJ,EAAE;CACN,MAAM,QACF,cAAc,WACR,CACI;EACI,MAAM;EACN,OAAO;GACH,YAAY,SAAS;GACrB;EACJ;CACJ,CACJ,IACA,cAAc,WACZ,CACI;EACI,MAAM;EACN,OAAO;GACH,QAAQ,EACJ,MAAM,WACV;GACA;EACJ;CACJ,CACJ,IACA,CACI;EACI,MAAM;EACN,OAAO,EACH,QAAQ,EACJ,MAAM,WACV,EACJ;CACJ,CACJ;CACZ,OAAO;EACH,IAAI,2BAA2B,WAAW,SAAS,IAAI;EACvD,MAAM,qBAAqB;GACvB,MAAM;GACN,YAAY,SAAS;GACrB;EACJ,CAAC;EACD,MAAM,6BAA6B,WAAW,SAAS,IAAI;EAC3D,aAAa,GAAG,KAAK,GAAG,SAAS;EACjC;EACA;CACJ;AACJ;AAEA,SAAS,gBAAgB,OAAgC,WAAyC;CAC9F,IAAI,sBAAsB,IAAI,MAAM,IAAI,GAAG,OAAO;CAClD,IAAI,MAAM,cAAc,MAAM,YAAY,OAAO;CACjD,OAAO,cAAc,WAAW,MAAM,aAAa,MAAM;AAC7D;AAEA,SAAgB,oCAAoC,UAAuD;CACvG,MAAM,UAA4B,CAAC;CACnC,IAAI,SAAS,YACT,QAAQ,KACJ,OACI,UACA,UACA,SAAS,OACJ,QAAQ,UAAU,gBAAgB,OAAO,QAAQ,CAAC,CAAC,CACnD,KAAK,UAAU,uBAAuB,OAAO,QAAQ,CAAC,CAC/D,CACJ;CAEJ,IAAI,SAAS,YACT,QAAQ,KACJ,OAAO,UAAU,UAAU,CACvB;EACI,MAAM;EACN,aAAa,GAAG,SAAS,MAAM;EAC/B,MAAM;GACF,MAAM;GACN,OAAO,EAAE,YAAY,SAAS,KAAK;EACvC;CACJ,GACA,GAAG,SAAS,OACP,QAAQ,UAAU,gBAAgB,OAAO,QAAQ,CAAC,CAAC,CACnD,KAAK,UAAU,uBAAuB,OAAO,QAAQ,CAAC,CAC/D,CAAC,CACL;CAEJ,IAAI,SAAS,WACT,QAAQ,KACJ,OAAO,UAAU,UAAU,CACvB;EACI,MAAM;EACN,aAAa,GAAG,SAAS,MAAM;EAC/B,MAAM;GACF,MAAM;GACN,OAAO,EAAE,YAAY,SAAS,KAAK;EACvC;CACJ,CACJ,CAAC,CACL;CAEJ,OAAO;AACX"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ServiceConnector } from "@party-stack/connect";
|
|
2
|
+
//#region src/serviceConnector.d.ts
|
|
3
|
+
export declare function makeSalesforceServiceConnector(options?: {
|
|
4
|
+
readonly loginUrl?: string;
|
|
5
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
6
|
+
}): ServiceConnector;
|
|
7
|
+
//#endregion
|
|
8
|
+
//# sourceMappingURL=serviceConnector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceConnector.d.ts","names":[],"sources":["../src/serviceConnector.ts"],"mappings":";;wBAKgB,+BACZ;WACa;WACA,eAAe,WAAW;IAExC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { ConnectError, makeOAuthService, withHttpAuthenticationErrors } from "@party-stack/connect";
|
|
2
|
+
import { Effect, Schema } from "effect";
|
|
3
|
+
import { BackendError } from "@party-stack/ontology-backend";
|
|
4
|
+
//#region src/serviceConnector.ts
|
|
5
|
+
function makeSalesforceServiceConnector(options = {}) {
|
|
6
|
+
const subject = (base, token) => Effect.gen(function* () {
|
|
7
|
+
const response = yield* Effect.tryPromise({
|
|
8
|
+
try: (signal) => (options.fetch ?? globalThis.fetch)(`${base}/services/oauth2/userinfo`, {
|
|
9
|
+
signal,
|
|
10
|
+
headers: {
|
|
11
|
+
Authorization: `Bearer ${token}`,
|
|
12
|
+
Accept: "application/json"
|
|
13
|
+
}
|
|
14
|
+
}),
|
|
15
|
+
catch: () => new ConnectError({
|
|
16
|
+
kind: "Provider",
|
|
17
|
+
retryable: true,
|
|
18
|
+
message: "Salesforce identity request failed."
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
if (!response.ok) return yield* new ConnectError({
|
|
22
|
+
kind: response.status === 401 ? "NeedsAuthentication" : "Provider",
|
|
23
|
+
retryable: response.status >= 500 || response.status === 429,
|
|
24
|
+
message: "Salesforce identity is unavailable."
|
|
25
|
+
});
|
|
26
|
+
const value = yield* Effect.tryPromise({
|
|
27
|
+
try: () => response.json(),
|
|
28
|
+
catch: () => new ConnectError({
|
|
29
|
+
kind: "Provider",
|
|
30
|
+
retryable: false,
|
|
31
|
+
message: "Salesforce identity response is invalid."
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
const identity = yield* Schema.decodeUnknownEffect(Schema.Struct({
|
|
35
|
+
user_id: Schema.optional(Schema.NonEmptyString),
|
|
36
|
+
sub: Schema.optional(Schema.NonEmptyString)
|
|
37
|
+
}))(value).pipe(Effect.mapError(() => new ConnectError({
|
|
38
|
+
kind: "Provider",
|
|
39
|
+
retryable: false,
|
|
40
|
+
message: "Salesforce identity response is invalid."
|
|
41
|
+
})));
|
|
42
|
+
const id = identity.user_id ?? identity.sub;
|
|
43
|
+
if (!id) return yield* new ConnectError({
|
|
44
|
+
kind: "Provider",
|
|
45
|
+
retryable: false,
|
|
46
|
+
message: "Salesforce identity has no user ID."
|
|
47
|
+
});
|
|
48
|
+
return id;
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
service: "salesforce",
|
|
52
|
+
displayName: "Salesforce",
|
|
53
|
+
defaultOAuthScopes: [
|
|
54
|
+
"api",
|
|
55
|
+
"refresh_token",
|
|
56
|
+
"openid"
|
|
57
|
+
],
|
|
58
|
+
oauth: Effect.fnUntraced(function* ({ application, serviceInstance, values }) {
|
|
59
|
+
const base = (options.loginUrl ?? serviceInstance.instanceUrl).replace(/\/+$/, "");
|
|
60
|
+
const secret = application.clientSecret ? yield* values.decrypt(Schema.String, application.clientSecret).pipe(Effect.mapError(() => new ConnectError({
|
|
61
|
+
kind: "Storage",
|
|
62
|
+
retryable: false,
|
|
63
|
+
message: "OAuth client secret is unavailable."
|
|
64
|
+
}))) : void 0;
|
|
65
|
+
return makeOAuthService({
|
|
66
|
+
issuer: base,
|
|
67
|
+
authorizationEndpoint: `${base}/services/oauth2/authorize`,
|
|
68
|
+
tokenEndpoint: `${base}/services/oauth2/token`,
|
|
69
|
+
revocationEndpoint: `${base}/services/oauth2/revoke`,
|
|
70
|
+
clientId: application.clientId,
|
|
71
|
+
clientAuthentication: secret ? {
|
|
72
|
+
method: "client_secret_post",
|
|
73
|
+
secret
|
|
74
|
+
} : { method: "none" },
|
|
75
|
+
scopes: application.scopes ?? [
|
|
76
|
+
"api",
|
|
77
|
+
"refresh_token",
|
|
78
|
+
"openid"
|
|
79
|
+
],
|
|
80
|
+
fetch: options.fetch,
|
|
81
|
+
resolveSubject: (token) => subject(base, token)
|
|
82
|
+
});
|
|
83
|
+
}),
|
|
84
|
+
apiKey: ({ apiKey, serviceInstance }) => subject((options.loginUrl ?? serviceInstance.instanceUrl).replace(/\/+$/, ""), apiKey).pipe(Effect.map((userId) => ({ userId }))),
|
|
85
|
+
acquire: Effect.fnUntraced(function* ({ connection, serviceInstance, credential, refreshCredential, handlers }) {
|
|
86
|
+
if (connection.objectType === "ExternalSessionConnection") return yield* new BackendError({
|
|
87
|
+
operation: "salesforce.acquire",
|
|
88
|
+
kind: "InvalidConfiguration",
|
|
89
|
+
retryable: false,
|
|
90
|
+
message: "Salesforce requires an OAuth or API-key connection."
|
|
91
|
+
});
|
|
92
|
+
return withHttpAuthenticationErrors({
|
|
93
|
+
fetch: Effect.fnUntraced(function* (request) {
|
|
94
|
+
if (new URL(request.url).origin !== new URL(serviceInstance.instanceUrl).origin) return yield* new BackendError({
|
|
95
|
+
operation: "salesforce.egress",
|
|
96
|
+
kind: "InvalidRequest",
|
|
97
|
+
retryable: false,
|
|
98
|
+
message: "Salesforce egress target is outside the configured instance."
|
|
99
|
+
});
|
|
100
|
+
const token = yield* credential;
|
|
101
|
+
const retry = connection.objectType === "OAuthConnection" ? request.clone() : void 0;
|
|
102
|
+
const send = (value, accessToken) => {
|
|
103
|
+
const headers = new Headers(value.headers);
|
|
104
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
105
|
+
return handlers.fetch(new Request(value, { headers }));
|
|
106
|
+
};
|
|
107
|
+
const response = yield* send(request, token);
|
|
108
|
+
if (response.status !== 401 || !retry) return response;
|
|
109
|
+
if (response.body) yield* Effect.promise(() => response.body.cancel()).pipe(Effect.ignoreCause);
|
|
110
|
+
return yield* send(retry, yield* refreshCredential(token));
|
|
111
|
+
}),
|
|
112
|
+
createWebSocket: () => Effect.fail(new BackendError({
|
|
113
|
+
operation: "salesforce.egress",
|
|
114
|
+
kind: "NotImplemented",
|
|
115
|
+
retryable: false,
|
|
116
|
+
message: "Salesforce WebSocket egress is not implemented."
|
|
117
|
+
}))
|
|
118
|
+
});
|
|
119
|
+
})
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { makeSalesforceServiceConnector };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=serviceConnector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceConnector.js","names":[],"sources":["../src/serviceConnector.ts"],"sourcesContent":["import { ConnectError, makeOAuthService, withHttpAuthenticationErrors } from \"@party-stack/connect\";\nimport { BackendError } from \"@party-stack/ontology-backend\";\nimport { Effect, Schema } from \"effect\";\nimport type { ServiceConnector } from \"@party-stack/connect\";\n\nexport function makeSalesforceServiceConnector(\n options: {\n readonly loginUrl?: string;\n readonly fetch?: typeof globalThis.fetch;\n } = {}\n): ServiceConnector {\n const subject = (base: string, token: string) =>\n Effect.gen(function* () {\n const response = yield* Effect.tryPromise({\n try: (signal) =>\n (options.fetch ?? globalThis.fetch)(`${base}/services/oauth2/userinfo`, {\n signal,\n headers: { Authorization: `Bearer ${token}`, Accept: \"application/json\" },\n }),\n catch: () =>\n new ConnectError({\n kind: \"Provider\",\n retryable: true,\n message: \"Salesforce identity request failed.\",\n }),\n });\n if (!response.ok)\n return yield* new ConnectError({\n kind: response.status === 401 ? \"NeedsAuthentication\" : \"Provider\",\n retryable: response.status >= 500 || response.status === 429,\n message: \"Salesforce identity is unavailable.\",\n });\n const value = yield* Effect.tryPromise({\n try: () => response.json(),\n catch: () =>\n new ConnectError({\n kind: \"Provider\",\n retryable: false,\n message: \"Salesforce identity response is invalid.\",\n }),\n });\n const identity = yield* Schema.decodeUnknownEffect(\n Schema.Struct({\n user_id: Schema.optional(Schema.NonEmptyString),\n sub: Schema.optional(Schema.NonEmptyString),\n })\n )(value).pipe(\n Effect.mapError(\n () =>\n new ConnectError({\n kind: \"Provider\",\n retryable: false,\n message: \"Salesforce identity response is invalid.\",\n })\n )\n );\n const id = identity.user_id ?? identity.sub;\n if (!id)\n return yield* new ConnectError({\n kind: \"Provider\",\n retryable: false,\n message: \"Salesforce identity has no user ID.\",\n });\n return id;\n });\n return {\n service: \"salesforce\",\n displayName: \"Salesforce\",\n defaultOAuthScopes: [\"api\", \"refresh_token\", \"openid\"],\n oauth: Effect.fnUntraced(function* ({ application, serviceInstance, values }) {\n const base = (options.loginUrl ?? serviceInstance.instanceUrl).replace(/\\/+$/, \"\");\n const secret = application.clientSecret\n ? yield* values.decrypt(Schema.String, application.clientSecret).pipe(\n Effect.mapError(\n () =>\n new ConnectError({\n kind: \"Storage\",\n retryable: false,\n message: \"OAuth client secret is unavailable.\",\n })\n )\n )\n : undefined;\n return makeOAuthService({\n issuer: base,\n authorizationEndpoint: `${base}/services/oauth2/authorize`,\n tokenEndpoint: `${base}/services/oauth2/token`,\n revocationEndpoint: `${base}/services/oauth2/revoke`,\n clientId: application.clientId,\n clientAuthentication: secret ? { method: \"client_secret_post\", secret } : { method: \"none\" },\n scopes: application.scopes ?? [\"api\", \"refresh_token\", \"openid\"],\n fetch: options.fetch,\n resolveSubject: (token) => subject(base, token),\n });\n }),\n apiKey: ({ apiKey, serviceInstance }) =>\n subject((options.loginUrl ?? serviceInstance.instanceUrl).replace(/\\/+$/, \"\"), apiKey).pipe(\n Effect.map((userId) => ({ userId }))\n ),\n acquire: Effect.fnUntraced(function* ({\n connection,\n serviceInstance,\n credential,\n refreshCredential,\n handlers,\n }) {\n if (connection.objectType === \"ExternalSessionConnection\")\n return yield* new BackendError({\n operation: \"salesforce.acquire\",\n kind: \"InvalidConfiguration\",\n retryable: false,\n message: \"Salesforce requires an OAuth or API-key connection.\",\n });\n return withHttpAuthenticationErrors({\n fetch: Effect.fnUntraced(function* (request: Request) {\n if (new URL(request.url).origin !== new URL(serviceInstance.instanceUrl).origin)\n return yield* new BackendError({\n operation: \"salesforce.egress\",\n kind: \"InvalidRequest\",\n retryable: false,\n message: \"Salesforce egress target is outside the configured instance.\",\n });\n const token = yield* credential;\n // Salesforce can omit token lifetime. Preserve its one retry\n // after a 401, with refresh owned by Connect's single authority.\n const retry = connection.objectType === \"OAuthConnection\" ? request.clone() : undefined;\n const send = (value: Request, accessToken: string) => {\n const headers = new Headers(value.headers);\n headers.set(\"Authorization\", `Bearer ${accessToken}`);\n return handlers.fetch(new Request(value, { headers }));\n };\n const response = yield* send(request, token);\n if (response.status !== 401 || !retry) return response;\n if (response.body)\n yield* Effect.promise(() => response.body!.cancel()).pipe(Effect.ignoreCause);\n return yield* send(retry, yield* refreshCredential(token));\n }),\n createWebSocket: () =>\n Effect.fail(\n new BackendError({\n operation: \"salesforce.egress\",\n kind: \"NotImplemented\",\n retryable: false,\n message: \"Salesforce WebSocket egress is not implemented.\",\n })\n ),\n });\n }),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/utils/AsyncIterable.d.ts
|
|
2
2
|
export declare function toArray<T>(asyncIterable: AsyncIterable<T>): Promise<T[]>;
|
|
3
|
-
export declare function fromPagination<C extends string | number, P, T>(getPage: (pageSize: number, pageToken?: C) => Promise<P>, getPageToken: (page: P) => C | undefined, getElements: (page: P) => T[] | Promise<T[]>, defaultPageSize: number, limit?: number): AsyncIterable<T>;
|
|
3
|
+
export declare function fromPagination<C extends string | number, P, T>(getPage: (pageSize: number, pageToken?: C) => Promise<P>, getPageToken: (page: P) => C | undefined, getElements: (page: P) => readonly T[] | Promise<readonly T[]>, defaultPageSize: number, limit?: number): AsyncIterable<T>;
|
|
4
4
|
//#endregion
|
|
5
5
|
//# sourceMappingURL=AsyncIterable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsyncIterable.d.ts","names":[],"sources":["../../src/utils/AsyncIterable.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"AsyncIterable.d.ts","names":[],"sources":["../../src/utils/AsyncIterable.ts"],"mappings":";wBAGsB,QAAQ,GAAG,eAAe,cAAc,KAAK,QAAQ;wBAQpD,eAAe,2BAA2B,GAAG,GAChE,UAAU,kBAAkB,YAAY,MAAM,QAAQ,IACtD,eAAe,MAAM,MAAM,eAC3B,cAAc,MAAM,eAAe,MAAM,iBAAiB,MAC1D,yBACA,iBACD,cAAc"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BackendError } from "@party-stack/ontology-backend";
|
|
1
2
|
//#region src/utils/AsyncIterable.ts
|
|
2
3
|
async function toArray(asyncIterable) {
|
|
3
4
|
const result = [];
|
|
@@ -5,10 +6,20 @@ async function toArray(asyncIterable) {
|
|
|
5
6
|
return result;
|
|
6
7
|
}
|
|
7
8
|
async function* fromPagination(getPage, getPageToken, getElements, defaultPageSize, limit = Infinity) {
|
|
9
|
+
const visited = /* @__PURE__ */ new Set();
|
|
8
10
|
let pageToken = void 0;
|
|
9
11
|
let hasMore = true;
|
|
10
12
|
let count = 0;
|
|
11
13
|
while (hasMore && count < limit) {
|
|
14
|
+
if (pageToken !== void 0) {
|
|
15
|
+
if (visited.has(pageToken)) throw new BackendError({
|
|
16
|
+
operation: "provider.pagination",
|
|
17
|
+
kind: "InvalidResponse",
|
|
18
|
+
message: "The provider repeated a pagination cursor.",
|
|
19
|
+
retryable: false
|
|
20
|
+
});
|
|
21
|
+
visited.add(pageToken);
|
|
22
|
+
}
|
|
12
23
|
const page = await getPage(Math.min(limit - count, defaultPageSize), pageToken);
|
|
13
24
|
const elements = await getElements(page);
|
|
14
25
|
for (const element of elements) yield element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsyncIterable.js","names":[],"sources":["../../src/utils/AsyncIterable.ts"],"sourcesContent":["// Replace later with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync\nexport async function toArray<T>(asyncIterable: AsyncIterable<T>): Promise<T[]> {\n const result = [];\n for await (const element of asyncIterable) {\n result.push(element);\n }\n return result;\n}\n\nexport async function* fromPagination<C extends string | number, P, T>(\n getPage: (pageSize: number, pageToken?: C) => Promise<P>,\n getPageToken: (page: P) => C | undefined,\n getElements: (page: P) => T[] | Promise<T[]>,\n defaultPageSize: number,\n limit: number = Infinity\n): AsyncIterable<T> {\n let pageToken: C | undefined = undefined;\n let hasMore = true;\n let count = 0;\n while (hasMore && count < limit) {\n const page = await getPage(Math.min(limit - count, defaultPageSize), pageToken);\n const elements = await getElements(page);\n for (const element of elements) {\n yield element;\n }\n count += elements.length;\n pageToken = getPageToken(page);\n if (pageToken === undefined) {\n hasMore = false;\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"AsyncIterable.js","names":[],"sources":["../../src/utils/AsyncIterable.ts"],"sourcesContent":["import { BackendError } from \"@party-stack/ontology-backend\";\n\n// Replace later with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync\nexport async function toArray<T>(asyncIterable: AsyncIterable<T>): Promise<T[]> {\n const result = [];\n for await (const element of asyncIterable) {\n result.push(element);\n }\n return result;\n}\n\nexport async function* fromPagination<C extends string | number, P, T>(\n getPage: (pageSize: number, pageToken?: C) => Promise<P>,\n getPageToken: (page: P) => C | undefined,\n getElements: (page: P) => readonly T[] | Promise<readonly T[]>,\n defaultPageSize: number,\n limit: number = Infinity\n): AsyncIterable<T> {\n const visited = new Set<C>();\n let pageToken: C | undefined = undefined;\n let hasMore = true;\n let count = 0;\n while (hasMore && count < limit) {\n if (pageToken !== undefined) {\n if (visited.has(pageToken))\n throw new BackendError({\n operation: \"provider.pagination\",\n kind: \"InvalidResponse\",\n message: \"The provider repeated a pagination cursor.\",\n retryable: false,\n });\n visited.add(pageToken);\n }\n const page = await getPage(Math.min(limit - count, defaultPageSize), pageToken);\n const elements = await getElements(page);\n for (const element of elements) {\n yield element;\n }\n count += elements.length;\n pageToken = getPageToken(page);\n if (pageToken === undefined) {\n hasMore = false;\n }\n }\n}\n"],"mappings":";;AAGA,eAAsB,QAAW,eAA+C;CAC5E,MAAM,SAAS,CAAC;CAChB,WAAW,MAAM,WAAW,eACxB,OAAO,KAAK,OAAO;CAEvB,OAAO;AACX;AAEA,gBAAuB,eACnB,SACA,cACA,aACA,iBACA,QAAgB,UACA;CAChB,MAAM,0BAAU,IAAI,IAAO;CAC3B,IAAI,YAA2B,KAAA;CAC/B,IAAI,UAAU;CACd,IAAI,QAAQ;CACZ,OAAO,WAAW,QAAQ,OAAO;EAC7B,IAAI,cAAc,KAAA,GAAW;GACzB,IAAI,QAAQ,IAAI,SAAS,GACrB,MAAM,IAAI,aAAa;IACnB,WAAW;IACX,MAAM;IACN,SAAS;IACT,WAAW;GACf,CAAC;GACL,QAAQ,IAAI,SAAS;EACzB;EACA,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,OAAO,eAAe,GAAG,SAAS;EAC9E,MAAM,WAAW,MAAM,YAAY,IAAI;EACvC,KAAK,MAAM,WAAW,UAClB,MAAM;EAEV,SAAS,SAAS;EAClB,YAAY,aAAa,IAAI;EAC7B,IAAI,cAAc,KAAA,GACd,UAAU;CAElB;AACJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@party-stack/salesforce-ontology",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"lib"
|
|
6
6
|
],
|
|
@@ -14,37 +14,33 @@
|
|
|
14
14
|
"types": "./lib/config/index.d.ts",
|
|
15
15
|
"default": "./lib/config/index.js"
|
|
16
16
|
},
|
|
17
|
-
"./installation": {
|
|
18
|
-
"types": "./lib/installation/index.d.ts",
|
|
19
|
-
"default": "./lib/installation/index.js"
|
|
20
|
-
},
|
|
21
17
|
"./meta": {
|
|
22
18
|
"types": "./lib/meta/index.d.ts",
|
|
23
19
|
"default": "./lib/meta/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./connect": {
|
|
22
|
+
"types": "./lib/connect.d.ts",
|
|
23
|
+
"default": "./lib/connect.js"
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@bobbyfidz/panic": "^0.1.0",
|
|
28
|
+
"effect": "^4.0.5",
|
|
28
29
|
"temporal-polyfill": "^0.3.0",
|
|
29
|
-
"@party-stack/
|
|
30
|
-
"@party-stack/errors": "0.2.1",
|
|
30
|
+
"@party-stack/connect": "0.2.0",
|
|
31
31
|
"@party-stack/icons-salesforce-lightning": "0.2.1",
|
|
32
|
-
"@party-stack/
|
|
33
|
-
"@party-stack/ontology": "0.
|
|
34
|
-
"@party-stack/
|
|
32
|
+
"@party-stack/ontology": "0.21.0",
|
|
33
|
+
"@party-stack/ontology-backend": "0.2.0",
|
|
34
|
+
"@party-stack/ontology-spec": "0.2.0",
|
|
35
|
+
"@party-stack/ontology-storage": "0.2.0",
|
|
36
|
+
"@party-stack/runtime": "0.5.0",
|
|
35
37
|
"@party-stack/salesforce-client": "0.1.2"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
38
|
-
"@tanstack/db": "0.
|
|
39
|
-
"@tanstack/query-core": "^5.102.8",
|
|
40
|
-
"@tanstack/query-db-collection": "1.4.4",
|
|
40
|
+
"@tanstack/db": "1.0.0-rc.1.4",
|
|
41
41
|
"typescript": "~7.0.2",
|
|
42
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.2.0",
|
|
42
43
|
"vite-plus": "1.2.0",
|
|
43
|
-
"@party-stack/build-config": "0.
|
|
44
|
-
},
|
|
45
|
-
"peerDependencies": {
|
|
46
|
-
"@tanstack/db": "0.14.0",
|
|
47
|
-
"@tanstack/query-core": "^5.102.8",
|
|
48
|
-
"@tanstack/query-db-collection": "1.4.4"
|
|
44
|
+
"@party-stack/build-config": "0.2.0"
|
|
49
45
|
}
|
|
50
46
|
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { LoadSubsetOptions } from "@tanstack/db";
|
|
2
|
-
//#region src/adapter/convertLoadSubsetOptions.d.ts
|
|
3
|
-
export type CompiledSoqlFilter = {
|
|
4
|
-
clause?: string;
|
|
5
|
-
alwaysFalse: boolean;
|
|
6
|
-
};
|
|
7
|
-
export declare function serializeSoqlLiteral(value: unknown): string;
|
|
8
|
-
export declare function isAlwaysFalseFilter(filter: CompiledSoqlFilter | undefined): boolean;
|
|
9
|
-
export declare function convertLoadSubsetFilter(filter: LoadSubsetOptions["where"]): CompiledSoqlFilter | undefined;
|
|
10
|
-
export declare function convertLoadSubsetOrderBy(orderBy: LoadSubsetOptions["orderBy"]): string | undefined;
|
|
11
|
-
export declare function buildSoqlQuery(opts: {
|
|
12
|
-
objectType: string;
|
|
13
|
-
selectedProperties: string[];
|
|
14
|
-
where?: CompiledSoqlFilter;
|
|
15
|
-
orderBy?: string;
|
|
16
|
-
limit?: number;
|
|
17
|
-
offset?: number;
|
|
18
|
-
}): string;
|
|
19
|
-
//#endregion
|
|
20
|
-
//# sourceMappingURL=convertLoadSubsetOptions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convertLoadSubsetOptions.d.ts","names":[],"sources":["../../src/adapter/convertLoadSubsetOptions.ts"],"mappings":";;YAKY;EACR;EACA;;wBAwDY,qBAAqB;wBA+BrB,oBAAoB,QAAQ;wBAsB5B,wBAAwB,QAAQ,6BAA6B;wBA8D7D,yBAAyB,SAAS;wBASlC,eAAe;EAC3B;EACA;EACA,QAAQ;EACR;EACA;EACA"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { parseOrderByExpression, parseWhereExpression } from "@tanstack/db";
|
|
2
|
-
import { Temporal } from "temporal-polyfill";
|
|
3
|
-
//#region src/adapter/convertLoadSubsetOptions.ts
|
|
4
|
-
const ALWAYS_FALSE = "__ALWAYS_FALSE__";
|
|
5
|
-
function quoteIdentifier(identifier) {
|
|
6
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) throw new Error(`Invalid Salesforce identifier "${identifier}".`);
|
|
7
|
-
return identifier;
|
|
8
|
-
}
|
|
9
|
-
function fieldPathToSoql(fieldPath) {
|
|
10
|
-
if (fieldPath.length === 0) throw new Error("Empty field path.");
|
|
11
|
-
return fieldPath.map((segment) => quoteIdentifier(String(segment))).join(".");
|
|
12
|
-
}
|
|
13
|
-
function escapeSoqlString(value) {
|
|
14
|
-
let escaped = "";
|
|
15
|
-
for (const character of value) switch (character) {
|
|
16
|
-
case "\\":
|
|
17
|
-
escaped += "\\\\";
|
|
18
|
-
break;
|
|
19
|
-
case "'":
|
|
20
|
-
escaped += "\\'";
|
|
21
|
-
break;
|
|
22
|
-
case "\b":
|
|
23
|
-
escaped += "\\b";
|
|
24
|
-
break;
|
|
25
|
-
case "\f":
|
|
26
|
-
escaped += "\\f";
|
|
27
|
-
break;
|
|
28
|
-
case "\n":
|
|
29
|
-
escaped += "\\n";
|
|
30
|
-
break;
|
|
31
|
-
case "\r":
|
|
32
|
-
escaped += "\\r";
|
|
33
|
-
break;
|
|
34
|
-
case " ":
|
|
35
|
-
escaped += "\\t";
|
|
36
|
-
break;
|
|
37
|
-
default: {
|
|
38
|
-
const codePoint = character.codePointAt(0);
|
|
39
|
-
if (codePoint < 32 || codePoint === 127) throw new Error(`Cannot serialize control character U+${codePoint.toString(16).padStart(4, "0")} to SOQL.`);
|
|
40
|
-
escaped += character;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return escaped;
|
|
44
|
-
}
|
|
45
|
-
function serializeSoqlLiteral(value) {
|
|
46
|
-
if (value === null || value === void 0) return "null";
|
|
47
|
-
if (typeof value === "boolean") return value ? "true" : "false";
|
|
48
|
-
if (typeof value === "number") {
|
|
49
|
-
if (!Number.isFinite(value)) throw new Error(`Cannot serialize non-finite number ${value} to SOQL.`);
|
|
50
|
-
return String(value);
|
|
51
|
-
}
|
|
52
|
-
if (typeof value === "bigint") return String(value);
|
|
53
|
-
if (value instanceof Date) return value.toISOString();
|
|
54
|
-
if (value instanceof Temporal.Instant) return value.toString();
|
|
55
|
-
if (value instanceof Temporal.PlainDate || value instanceof Temporal.PlainDateTime) return value.toString();
|
|
56
|
-
if (typeof value === "string") return `'${escapeSoqlString(value)}'`;
|
|
57
|
-
throw new Error(`Unsupported SOQL literal type: ${typeof value}`);
|
|
58
|
-
}
|
|
59
|
-
function isAlwaysFalseFilter(filter) {
|
|
60
|
-
return Boolean(filter?.alwaysFalse);
|
|
61
|
-
}
|
|
62
|
-
function convertInFilter(fieldOrValue, valuesOrField) {
|
|
63
|
-
if (!Array.isArray(valuesOrField)) throw new Error("Expected the second inArray argument to be an array or field path");
|
|
64
|
-
if (!Array.isArray(fieldOrValue)) return fieldOrValue == null ? ALWAYS_FALSE : `${fieldPathToSoql(valuesOrField)} INCLUDES (${serializeSoqlLiteral(fieldOrValue)})`;
|
|
65
|
-
const literals = valuesOrField.filter((entry) => entry !== null && entry !== void 0).map(serializeSoqlLiteral);
|
|
66
|
-
if (literals.length === 0) return ALWAYS_FALSE;
|
|
67
|
-
return `${fieldPathToSoql(fieldOrValue)} IN (${literals.join(", ")})`;
|
|
68
|
-
}
|
|
69
|
-
function convertLoadSubsetFilter(filter) {
|
|
70
|
-
if (!filter) return void 0;
|
|
71
|
-
const compiled = parseWhereExpression(filter, { handlers: {
|
|
72
|
-
and: (...filters) => {
|
|
73
|
-
if (filters.includes(ALWAYS_FALSE)) return ALWAYS_FALSE;
|
|
74
|
-
const clauses = filters.filter((clause) => clause.length > 0);
|
|
75
|
-
if (clauses.length === 0) return "";
|
|
76
|
-
if (clauses.length === 1) return clauses[0];
|
|
77
|
-
return `(${clauses.join(" AND ")})`;
|
|
78
|
-
},
|
|
79
|
-
or: (...filters) => {
|
|
80
|
-
if (filters.every((clause) => clause === ALWAYS_FALSE)) return ALWAYS_FALSE;
|
|
81
|
-
const clauses = filters.filter((clause) => clause !== ALWAYS_FALSE && clause.length > 0);
|
|
82
|
-
if (clauses.length === 0) return "";
|
|
83
|
-
if (clauses.length === 1) return clauses[0];
|
|
84
|
-
return `(${clauses.join(" OR ")})`;
|
|
85
|
-
},
|
|
86
|
-
not: (inner) => {
|
|
87
|
-
if (inner === ALWAYS_FALSE) return "";
|
|
88
|
-
if (!inner) return ALWAYS_FALSE;
|
|
89
|
-
return `(NOT ${inner})`;
|
|
90
|
-
},
|
|
91
|
-
eq: (field, value) => value == null ? `${fieldPathToSoql(field)} = null` : `${fieldPathToSoql(field)} = ${serializeSoqlLiteral(value)}`,
|
|
92
|
-
gt: (field, value) => value == null ? ALWAYS_FALSE : `${fieldPathToSoql(field)} > ${serializeSoqlLiteral(value)}`,
|
|
93
|
-
gte: (field, value) => value == null ? ALWAYS_FALSE : `${fieldPathToSoql(field)} >= ${serializeSoqlLiteral(value)}`,
|
|
94
|
-
lt: (field, value) => value == null ? ALWAYS_FALSE : `${fieldPathToSoql(field)} < ${serializeSoqlLiteral(value)}`,
|
|
95
|
-
lte: (field, value) => value == null ? ALWAYS_FALSE : `${fieldPathToSoql(field)} <= ${serializeSoqlLiteral(value)}`,
|
|
96
|
-
isUndefined: (field) => `${fieldPathToSoql(field)} = null`,
|
|
97
|
-
in: convertInFilter,
|
|
98
|
-
like: (field, value) => value === "%" ? "" : `${fieldPathToSoql(field)} LIKE ${serializeSoqlLiteral(value)}`,
|
|
99
|
-
ilike: (field, value) => value === "%" ? "" : `${fieldPathToSoql(field)} LIKE ${serializeSoqlLiteral(value)}`
|
|
100
|
-
} }) ?? void 0;
|
|
101
|
-
if (compiled === void 0) return void 0;
|
|
102
|
-
if (compiled === ALWAYS_FALSE) return { alwaysFalse: true };
|
|
103
|
-
return {
|
|
104
|
-
clause: compiled || void 0,
|
|
105
|
-
alwaysFalse: false
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
function convertLoadSubsetOrderBy(orderBy) {
|
|
109
|
-
if (!orderBy) return void 0;
|
|
110
|
-
const fields = parseOrderByExpression(orderBy).map((ordering) => {
|
|
111
|
-
return `${fieldPathToSoql(ordering.field)} ${ordering.direction.toUpperCase()}`;
|
|
112
|
-
});
|
|
113
|
-
return fields.length > 0 ? fields.join(", ") : void 0;
|
|
114
|
-
}
|
|
115
|
-
function buildSoqlQuery(opts) {
|
|
116
|
-
const objectType = quoteIdentifier(opts.objectType);
|
|
117
|
-
const clauses = [`SELECT ${opts.selectedProperties.map(quoteIdentifier).join(", ")} FROM ${objectType}`];
|
|
118
|
-
if (opts.where?.clause) clauses.push(`WHERE ${opts.where.clause}`);
|
|
119
|
-
if (opts.orderBy) clauses.push(`ORDER BY ${opts.orderBy}`);
|
|
120
|
-
if (opts.limit !== void 0) clauses.push(`LIMIT ${Math.max(0, Math.trunc(opts.limit))}`);
|
|
121
|
-
if (opts.offset !== void 0 && opts.offset > 0) clauses.push(`OFFSET ${Math.max(0, Math.trunc(opts.offset))}`);
|
|
122
|
-
return clauses.join(" ");
|
|
123
|
-
}
|
|
124
|
-
//#endregion
|
|
125
|
-
export { buildSoqlQuery, convertLoadSubsetFilter, convertLoadSubsetOrderBy, isAlwaysFalseFilter, serializeSoqlLiteral };
|
|
126
|
-
|
|
127
|
-
//# sourceMappingURL=convertLoadSubsetOptions.js.map
|