@party-stack/foundry-ontology 0.18.1 → 0.20.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 +56 -16
- package/lib/adapter/backend.d.ts +35 -0
- package/lib/adapter/backend.d.ts.map +1 -0
- package/lib/adapter/backend.js +210 -0
- package/lib/adapter/backend.js.map +1 -0
- package/lib/adapter/encrypted.d.ts +12 -0
- package/lib/adapter/encrypted.d.ts.map +1 -0
- package/lib/adapter/encrypted.js +79 -0
- package/lib/adapter/encrypted.js.map +1 -0
- package/lib/adapter/foundryActionError.d.ts +7 -0
- package/lib/adapter/foundryActionError.d.ts.map +1 -0
- package/lib/adapter/foundryActionError.js +61 -0
- package/lib/adapter/foundryActionError.js.map +1 -0
- package/lib/adapter/foundryActionValidation.d.ts +4 -3
- package/lib/adapter/foundryActionValidation.d.ts.map +1 -1
- package/lib/adapter/foundryActionValidation.js +71 -25
- package/lib/adapter/foundryActionValidation.js.map +1 -1
- package/lib/adapter/foundryCodec.d.ts +3 -5
- package/lib/adapter/foundryCodec.d.ts.map +1 -1
- package/lib/adapter/foundryCodec.js +19 -7
- package/lib/adapter/foundryCodec.js.map +1 -1
- package/lib/adapter/foundryObjectSearch.d.ts +13 -0
- package/lib/adapter/foundryObjectSearch.d.ts.map +1 -0
- package/lib/adapter/foundryObjectSearch.js +57 -0
- package/lib/adapter/foundryObjectSearch.js.map +1 -0
- package/lib/adapter/index.d.ts +3 -4
- package/lib/adapter/index.js +3 -4
- package/lib/adapter/likeFilter.d.ts +10 -0
- package/lib/adapter/likeFilter.d.ts.map +1 -0
- package/lib/adapter/likeFilter.js +87 -0
- package/lib/adapter/likeFilter.js.map +1 -0
- package/lib/adapter/makeFoundryOntologyBackend.d.ts +76 -0
- package/lib/adapter/makeFoundryOntologyBackend.d.ts.map +1 -0
- package/lib/adapter/makeFoundryOntologyBackend.js +505 -0
- package/lib/adapter/makeFoundryOntologyBackend.js.map +1 -0
- package/lib/adapter/subsetFilter.d.ts +14 -0
- package/lib/adapter/subsetFilter.d.ts.map +1 -0
- package/lib/adapter/subsetFilter.js +105 -0
- package/lib/adapter/subsetFilter.js.map +1 -0
- package/lib/adapter/uploads.d.ts +25 -0
- package/lib/adapter/uploads.d.ts.map +1 -0
- package/lib/adapter/uploads.js +78 -0
- package/lib/adapter/uploads.js.map +1 -0
- package/lib/backend.d.ts +80 -0
- package/lib/backend.d.ts.map +1 -0
- package/lib/backend.js +34 -0
- package/lib/backend.js.map +1 -0
- package/lib/config/index.d.ts +8 -12
- package/lib/config/index.d.ts.map +1 -1
- package/lib/config/index.js +49 -52
- package/lib/config/index.js.map +1 -1
- package/lib/connectionOptions.d.ts +9 -0
- package/lib/connectionOptions.d.ts.map +1 -0
- package/lib/connectionOptions.js +1 -0
- package/lib/context.d.ts +21 -0
- package/lib/context.d.ts.map +1 -0
- package/lib/context.js +16 -0
- package/lib/context.js.map +1 -0
- package/lib/index.d.ts +7 -7
- package/lib/index.js +6 -7
- package/lib/meta/backend.d.ts +10 -0
- package/lib/meta/backend.d.ts.map +1 -0
- package/lib/meta/backend.js +161 -0
- package/lib/meta/backend.js.map +1 -0
- package/lib/meta/convertMetaActionType.d.ts +3 -2
- package/lib/meta/convertMetaActionType.d.ts.map +1 -1
- package/lib/meta/convertMetaActionType.js +3 -3
- 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 +13 -13
- package/lib/meta/convertMetaLinkType.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 +5 -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.d.ts.map +1 -1
- package/lib/meta/convertMetaTypeDef.js +7 -1
- package/lib/meta/convertMetaTypeDef.js.map +1 -1
- package/lib/meta/convertMetaValueType.d.ts +2 -2
- package/lib/meta/convertMetaValueType.d.ts.map +1 -1
- package/lib/meta/convertMetaValueType.js.map +1 -1
- package/lib/meta/convertOmsActionParameterMetadata.d.ts +1 -1
- package/lib/meta/convertOmsActionParameterMetadata.js +1 -1
- package/lib/meta/convertOmsActionParameterMetadata.js.map +1 -1
- package/lib/meta/index.d.ts +2 -4
- package/lib/meta/index.js +2 -4
- package/lib/meta/listObjectTypes.d.ts +6 -0
- package/lib/meta/listObjectTypes.d.ts.map +1 -0
- package/lib/meta/listObjectTypes.js +13 -0
- package/lib/meta/listObjectTypes.js.map +1 -0
- package/lib/meta/loadActionTypeOmsMetadata.d.ts +1 -0
- package/lib/meta/loadActions.d.ts +7 -0
- package/lib/meta/loadActions.d.ts.map +1 -0
- package/lib/meta/loadActions.js +20 -0
- package/lib/meta/loadActions.js.map +1 -0
- package/lib/meta/loadEntities.d.ts +9 -0
- package/lib/meta/loadEntities.d.ts.map +1 -0
- package/lib/meta/loadEntities.js +73 -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 +18 -0
- package/lib/meta/loadQueryFunctions.js.map +1 -0
- package/lib/meta/planMetaLookup.d.ts +12 -0
- package/lib/meta/planMetaLookup.d.ts.map +1 -0
- package/lib/meta/planMetaLookup.js +44 -0
- package/lib/meta/planMetaLookup.js.map +1 -0
- package/lib/platform.d.ts +78 -0
- package/lib/platform.d.ts.map +1 -0
- package/lib/platform.js +116 -0
- package/lib/platform.js.map +1 -0
- package/lib/platformCollections.d.ts +68 -0
- package/lib/platformCollections.d.ts.map +1 -0
- package/lib/platformCollections.js +7 -0
- package/lib/platformCollections.js.map +1 -0
- package/lib/serviceConnector.d.ts +8 -0
- package/lib/serviceConnector.d.ts.map +1 -0
- package/lib/serviceConnector.js +105 -0
- package/lib/serviceConnector.js.map +1 -0
- package/lib/stagedWrites.d.ts +3 -2
- package/lib/stagedWrites.d.ts.map +1 -1
- package/lib/stagedWrites.js +30 -3
- package/lib/stagedWrites.js.map +1 -1
- package/lib/users/admin.d.ts +105 -0
- package/lib/users/admin.d.ts.map +1 -0
- package/lib/users/admin.js +35 -0
- package/lib/users/admin.js.map +1 -0
- package/lib/users/createFoundryUsersIntegration.d.ts +2 -2
- package/lib/users/createFoundryUsersIntegration.d.ts.map +1 -1
- package/lib/users/createFoundryUsersIntegration.js +4 -6
- package/lib/users/createFoundryUsersIntegration.js.map +1 -1
- package/lib/users/foundryUser.d.ts +2 -2
- package/lib/users/foundryUser.js +1 -1
- package/lib/users/foundryUser.js.map +1 -1
- package/lib/users/index.d.ts +2 -3
- package/lib/users/index.js +2 -3
- package/lib/users/loadUserSubset.d.ts +8 -0
- package/lib/users/loadUserSubset.d.ts.map +1 -0
- package/lib/users/loadUserSubset.js +166 -0
- package/lib/users/loadUserSubset.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 +17 -16
- package/lib/adapter/convertLoadSubsetOptions.d.ts +0 -8
- package/lib/adapter/convertLoadSubsetOptions.d.ts.map +0 -1
- package/lib/adapter/convertLoadSubsetOptions.js +0 -178
- package/lib/adapter/convertLoadSubsetOptions.js.map +0 -1
- package/lib/adapter/createFoundryOntologyBackendAdapter.d.ts +0 -29
- package/lib/adapter/createFoundryOntologyBackendAdapter.d.ts.map +0 -1
- package/lib/adapter/createFoundryOntologyBackendAdapter.js +0 -311
- package/lib/adapter/createFoundryOntologyBackendAdapter.js.map +0 -1
- package/lib/adapter/objectCollectionOptions.d.ts +0 -31
- package/lib/adapter/objectCollectionOptions.d.ts.map +0 -1
- package/lib/adapter/objectCollectionOptions.js +0 -448
- package/lib/adapter/objectCollectionOptions.js.map +0 -1
- package/lib/config/applyAttachmentConstraintOverrides.d.ts +0 -10
- package/lib/config/applyAttachmentConstraintOverrides.d.ts.map +0 -1
- package/lib/config/applyAttachmentConstraintOverrides.js +0 -50
- package/lib/config/applyAttachmentConstraintOverrides.js.map +0 -1
- package/lib/connection.d.ts +0 -38
- package/lib/connection.d.ts.map +0 -1
- package/lib/connection.js +0 -195
- package/lib/connection.js.map +0 -1
- package/lib/installation/createFoundryBackendInstallation.d.ts +0 -29
- package/lib/installation/createFoundryBackendInstallation.d.ts.map +0 -1
- package/lib/installation/createFoundryBackendInstallation.js +0 -60
- package/lib/installation/createFoundryBackendInstallation.js.map +0 -1
- package/lib/installation/index.d.ts +0 -2
- package/lib/installation/index.js +0 -2
- package/lib/meta/actionTypeCollectionOptions.d.ts +0 -14
- package/lib/meta/actionTypeCollectionOptions.d.ts.map +0 -1
- package/lib/meta/actionTypeCollectionOptions.js +0 -58
- package/lib/meta/actionTypeCollectionOptions.js.map +0 -1
- package/lib/meta/convertActionTypeLoadSubsetOptions.d.ts +0 -7
- package/lib/meta/convertActionTypeLoadSubsetOptions.d.ts.map +0 -1
- package/lib/meta/convertActionTypeLoadSubsetOptions.js +0 -84
- package/lib/meta/convertActionTypeLoadSubsetOptions.js.map +0 -1
- package/lib/meta/createFoundryMetaOntologyBackendAdapter.d.ts +0 -11
- package/lib/meta/createFoundryMetaOntologyBackendAdapter.d.ts.map +0 -1
- package/lib/meta/createFoundryMetaOntologyBackendAdapter.js +0 -43
- package/lib/meta/createFoundryMetaOntologyBackendAdapter.js.map +0 -1
- package/lib/meta/entityCollectionOptions.d.ts +0 -24
- package/lib/meta/entityCollectionOptions.d.ts.map +0 -1
- package/lib/meta/entityCollectionOptions.js +0 -69
- package/lib/meta/entityCollectionOptions.js.map +0 -1
- package/lib/meta/queryFunctionTypeCollectionOptions.d.ts +0 -12
- package/lib/meta/queryFunctionTypeCollectionOptions.d.ts.map +0 -1
- package/lib/meta/queryFunctionTypeCollectionOptions.js +0 -59
- package/lib/meta/queryFunctionTypeCollectionOptions.js.map +0 -1
- package/lib/users/createFoundryAdminOntologyRoute.d.ts +0 -55
- package/lib/users/createFoundryAdminOntologyRoute.d.ts.map +0 -1
- package/lib/users/createFoundryAdminOntologyRoute.js +0 -33
- package/lib/users/createFoundryAdminOntologyRoute.js.map +0 -1
- package/lib/users/userCollectionOptions.d.ts +0 -24
- package/lib/users/userCollectionOptions.d.ts.map +0 -1
- package/lib/users/userCollectionOptions.js +0 -94
- package/lib/users/userCollectionOptions.js.map +0 -1
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
import { FOUNDRY_CURRENT_USER_CONTEXT_FIELD } from "../context.js";
|
|
2
|
+
import { toFoundryActionTypeName } from "../utils/actionTypeName.js";
|
|
3
|
+
import { getFoundryAttachmentKind } from "../meta/foundryAttachmentMetadata.js";
|
|
4
|
+
import { getFoundryActionOverrideParameterMapping } from "../meta/convertMetaActionType.js";
|
|
5
|
+
import { makeFoundryBackend } from "./backend.js";
|
|
6
|
+
import { makeFoundryEncryptedValues } from "./encrypted.js";
|
|
7
|
+
import { foundryActionError } from "./foundryActionError.js";
|
|
8
|
+
import { getFoundryValidationIssues, loadFoundrySubmissionCriteria, validateFoundryActionDraftCriteria } from "./foundryActionValidation.js";
|
|
9
|
+
import { decodeFoundryMediaId, mediaReferenceToFoundryMediaId } from "./foundryMediaId.js";
|
|
10
|
+
import { createFoundryCodec } from "./foundryCodec.js";
|
|
11
|
+
import { uploadFoundryAttachment, uploadFoundryMedia } from "./uploads.js";
|
|
12
|
+
import { Effect, Redacted, Schema, Stream } from "effect";
|
|
13
|
+
import { invariant } from "@bobbyfidz/panic";
|
|
14
|
+
import { MediaSets } from "@osdk/foundry.mediasets";
|
|
15
|
+
import { Actions, Attachments, MediaReferenceProperties, Queries } from "@osdk/foundry.ontologies";
|
|
16
|
+
import { BackendError, classifyBackendFailure } from "@party-stack/ontology-backend";
|
|
17
|
+
import { certain, uncertain } from "@party-stack/ontology-spec";
|
|
18
|
+
import { resolveType, unwrapType } from "@party-stack/ontology-spec/utils";
|
|
19
|
+
import { byteChunks, byteSource, readableByteSource, scopedByteSource, sliceByteSource } from "@party-stack/ontology-storage/blobs";
|
|
20
|
+
import { Temporal } from "temporal-polyfill";
|
|
21
|
+
//#region src/adapter/makeFoundryOntologyBackend.ts
|
|
22
|
+
const attachmentFailure = (kind, message) => new BackendError({
|
|
23
|
+
operation: "foundry.attachment",
|
|
24
|
+
kind,
|
|
25
|
+
message,
|
|
26
|
+
retryable: false
|
|
27
|
+
});
|
|
28
|
+
function isFoundryAttachmentRid(value) {
|
|
29
|
+
return /^ri\.attachments\.[^.]+\.attachment\..+$/.test(value);
|
|
30
|
+
}
|
|
31
|
+
function isFoundryNotFoundError(error) {
|
|
32
|
+
if (typeof error !== "object" || error === null) return false;
|
|
33
|
+
const foundryError = error;
|
|
34
|
+
return foundryError.statusCode === 404 || foundryError.errorCode === "NOT_FOUND";
|
|
35
|
+
}
|
|
36
|
+
function serializeOverrideValue(value) {
|
|
37
|
+
if (typeof value === "string") return value;
|
|
38
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
|
|
39
|
+
if (value instanceof Date) return value.toISOString();
|
|
40
|
+
if (value instanceof Temporal.Instant) return value.toString();
|
|
41
|
+
if (value instanceof Temporal.PlainDate || value instanceof Temporal.PlainDateTime) return value.toString();
|
|
42
|
+
return JSON.stringify(value) ?? "";
|
|
43
|
+
}
|
|
44
|
+
function serializeActionExecutionTime(value) {
|
|
45
|
+
try {
|
|
46
|
+
const candidate = value instanceof Date ? value.toISOString() : String(value);
|
|
47
|
+
return Temporal.Instant.from(candidate).toString();
|
|
48
|
+
} catch (cause) {
|
|
49
|
+
throw new TypeError("Invalid action execution time: expected a Date or Temporal-like ISO instant.", { cause });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function getAttachmentName(attachment) {
|
|
53
|
+
if (typeof attachment !== "object" || attachment === null || Array.isArray(attachment)) return;
|
|
54
|
+
const name = attachment.name;
|
|
55
|
+
return typeof name === "string" ? name : void 0;
|
|
56
|
+
}
|
|
57
|
+
function getAttachmentProviderType(target) {
|
|
58
|
+
return getFoundryAttachmentKind(target?.meta);
|
|
59
|
+
}
|
|
60
|
+
function prepareFoundryActionInvocation(options) {
|
|
61
|
+
const actionType = options.ir.actionTypes.find((candidate) => candidate.name === options.name);
|
|
62
|
+
if (!actionType) throw new BackendError({
|
|
63
|
+
operation: "foundry.prepare",
|
|
64
|
+
kind: "InvalidRequest",
|
|
65
|
+
retryable: false,
|
|
66
|
+
actionOutcome: "not-committed",
|
|
67
|
+
message: `Unknown Foundry action type "${options.name}".`
|
|
68
|
+
});
|
|
69
|
+
const overrideMapping = getFoundryActionOverrideParameterMapping(actionType);
|
|
70
|
+
const parameterTypes = new Map(actionType.parameters.map((parameter) => [parameter.name, parameter.type]));
|
|
71
|
+
const parameters = {};
|
|
72
|
+
const uniqueIdentifierLinkIdValues = {};
|
|
73
|
+
let actionExecutionTime;
|
|
74
|
+
try {
|
|
75
|
+
for (const [parameterName, value] of Object.entries(options.parameters)) {
|
|
76
|
+
if (overrideMapping.uuidByParameterName.has(parameterName)) {
|
|
77
|
+
if (value !== void 0) uniqueIdentifierLinkIdValues[overrideMapping.uuidByParameterName.get(parameterName)] = serializeOverrideValue(value);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (overrideMapping.nowParameterName === parameterName) {
|
|
81
|
+
if (value !== void 0) actionExecutionTime = serializeActionExecutionTime(value);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (value !== void 0) {
|
|
85
|
+
const parameterType = parameterTypes.get(parameterName);
|
|
86
|
+
parameters[parameterName] = parameterType ? options.codec.encodeValue(parameterType, value) : value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch (cause) {
|
|
90
|
+
throw new BackendError({
|
|
91
|
+
operation: "foundry.prepare",
|
|
92
|
+
kind: "InvalidRequest",
|
|
93
|
+
retryable: false,
|
|
94
|
+
actionOutcome: "not-committed",
|
|
95
|
+
message: "Invalid action parameters.",
|
|
96
|
+
cause: Redacted.make(cause)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
parameters,
|
|
101
|
+
overrides: {
|
|
102
|
+
uniqueIdentifierLinkIdValues,
|
|
103
|
+
actionExecutionTime
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function withRequestSignal(client, signal) {
|
|
108
|
+
return signal ? {
|
|
109
|
+
...client,
|
|
110
|
+
fetch: (input, init) => client.fetch(input, {
|
|
111
|
+
...init,
|
|
112
|
+
signal: init?.signal ? AbortSignal.any([signal, init.signal]) : signal
|
|
113
|
+
})
|
|
114
|
+
} : client;
|
|
115
|
+
}
|
|
116
|
+
const makeFoundryOntologyBackend = Effect.fn("Foundry.makeBackend")(function* (opts) {
|
|
117
|
+
const context = opts.context ?? {};
|
|
118
|
+
const codec = yield* Effect.try({
|
|
119
|
+
try: () => createFoundryCodec(opts.ir),
|
|
120
|
+
catch: (cause) => new BackendError({
|
|
121
|
+
operation: "foundry.open",
|
|
122
|
+
kind: "InvalidConfiguration",
|
|
123
|
+
retryable: false,
|
|
124
|
+
message: "Invalid Foundry definition.",
|
|
125
|
+
cause: Redacted.make(cause)
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
const Validation = Schema.Struct({ result: Schema.Literals(["VALID", "INVALID"]) });
|
|
129
|
+
const ActionResponse = Schema.Struct({ validation: Schema.optional(Validation) });
|
|
130
|
+
const ValidationResponse = Schema.Struct({ validation: Validation });
|
|
131
|
+
const attachments = {
|
|
132
|
+
materializeAttachment: async (attachment, input, { target, signal }, client = opts.client) => {
|
|
133
|
+
invariant(target, "A property target must be passed to materializeAttachment in the Foundry adapter so that we know whether to target attachments or media.");
|
|
134
|
+
invariant(getAttachmentProviderType(target) === "attachment", "Foundry media references must be uploaded during action execution.");
|
|
135
|
+
const filename = byteSource(input).name ?? "";
|
|
136
|
+
if (!isFoundryAttachmentRid(attachment.id)) {
|
|
137
|
+
const uploaded = await uploadFoundryAttachment(client, input, {
|
|
138
|
+
filename,
|
|
139
|
+
signal
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
...attachment,
|
|
143
|
+
id: uploaded.rid
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
await Attachments.get(client, attachment.id);
|
|
148
|
+
return;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (!isFoundryNotFoundError(error)) throw error;
|
|
151
|
+
}
|
|
152
|
+
await uploadFoundryAttachment(client, input, {
|
|
153
|
+
filename,
|
|
154
|
+
rid: attachment.id,
|
|
155
|
+
signal
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
getAttachmentContent: async (attachment, readOptions) => {
|
|
159
|
+
const client = withRequestSignal(opts.client, readOptions?.signal);
|
|
160
|
+
const userContent = await opts.users?.getAttachmentContent?.(client, attachment);
|
|
161
|
+
if (userContent) return userContent;
|
|
162
|
+
if (decodeFoundryMediaId(attachment.id)) {
|
|
163
|
+
const source = attachment.source;
|
|
164
|
+
if (!source) throw attachmentFailure("InvalidRequest", "Media reads require an object property source.");
|
|
165
|
+
const response = await MediaReferenceProperties.getMediaContent(client, client.ontologyRid, source.objectType, String(source.primaryKey), source.property, { preview: true });
|
|
166
|
+
if (!response.body) throw attachmentFailure("InvalidResponse", "Foundry returned no media body.");
|
|
167
|
+
return readableByteSource(response.body, { type: response.headers.get("content-type") ?? attachment.type });
|
|
168
|
+
}
|
|
169
|
+
const contents = await Attachments.read(client, attachment.id);
|
|
170
|
+
if (!contents.body) throw attachmentFailure("InvalidResponse", "Foundry returned no attachment body.");
|
|
171
|
+
return readableByteSource(contents.body, { type: contents.headers.get("content-type") ?? attachment.type });
|
|
172
|
+
},
|
|
173
|
+
getAttachmentMetadata: async (attachment, selection, readOptions) => {
|
|
174
|
+
const client = withRequestSignal(opts.client, readOptions?.signal);
|
|
175
|
+
const userMetadata = await opts.users?.getAttachmentMetadata?.(client, attachment, selection);
|
|
176
|
+
if (userMetadata) return userMetadata;
|
|
177
|
+
const media = decodeFoundryMediaId(attachment.id);
|
|
178
|
+
if (media) {
|
|
179
|
+
const result = {};
|
|
180
|
+
if (attachment.type !== void 0) result.type = attachment.type;
|
|
181
|
+
if (selection.includes("dimensions")) {
|
|
182
|
+
const detailed = await MediaSets.metadata(client, media.mediaSetRid, media.mediaItemRid);
|
|
183
|
+
result.size = detailed.sizeBytes;
|
|
184
|
+
if (detailed.type === "imagery" && detailed.dimensions) result.dimensions = {
|
|
185
|
+
width: detailed.dimensions.width,
|
|
186
|
+
height: detailed.dimensions.height
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (!selection.filter((field) => result[field] === void 0).some((field) => field !== "dimensions")) return result;
|
|
190
|
+
const source = attachment.source;
|
|
191
|
+
if (!source) throw attachmentFailure("InvalidRequest", "Media reads require an object property source.");
|
|
192
|
+
const info = await MediaReferenceProperties.getMediaMetadata(client, client.ontologyRid, source.objectType, String(source.primaryKey), source.property, { preview: true });
|
|
193
|
+
return {
|
|
194
|
+
...result,
|
|
195
|
+
size: Number(info.sizeBytes),
|
|
196
|
+
type: info.mediaType,
|
|
197
|
+
name: info.path
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const metadata = await Attachments.get(client, attachment.id);
|
|
201
|
+
return {
|
|
202
|
+
size: Number(metadata.sizeBytes),
|
|
203
|
+
type: metadata.mediaType,
|
|
204
|
+
name: metadata.filename
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const submitAction = async (name, parameters, context, client = opts.client) => {
|
|
209
|
+
if (!opts.ir.actionTypes.some((action) => action.name === name)) throw new BackendError({
|
|
210
|
+
operation: "foundry.applyAction",
|
|
211
|
+
kind: "InvalidRequest",
|
|
212
|
+
retryable: false,
|
|
213
|
+
actionOutcome: "not-committed",
|
|
214
|
+
message: "Unknown Foundry action type."
|
|
215
|
+
});
|
|
216
|
+
const mediaReferences = /* @__PURE__ */ new Map();
|
|
217
|
+
const attachmentIdMappings = [];
|
|
218
|
+
const attachmentIds = /* @__PURE__ */ new Map();
|
|
219
|
+
await Promise.all([...new Map((context.attachmentUploads ?? []).map((upload) => [upload.attachment.id, upload])).values()].map(async (upload) => {
|
|
220
|
+
if (getAttachmentProviderType(upload.target) !== "media") {
|
|
221
|
+
const id = (await attachments.materializeAttachment(upload.attachment, upload.blob, {
|
|
222
|
+
target: upload.target,
|
|
223
|
+
signal: context.signal
|
|
224
|
+
}, client))?.id ?? upload.attachment.id;
|
|
225
|
+
attachmentIds.set(upload.attachment.id, id);
|
|
226
|
+
if (id !== upload.attachment.id) attachmentIdMappings.push({
|
|
227
|
+
localId: upload.attachment.id,
|
|
228
|
+
remoteId: id
|
|
229
|
+
});
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const reference = await uploadFoundryMedia(client, upload.blob, {
|
|
233
|
+
filename: getAttachmentName(upload.blob) ?? upload.attachment.id,
|
|
234
|
+
signal: context.signal
|
|
235
|
+
});
|
|
236
|
+
mediaReferences.set(upload.attachment.id, reference);
|
|
237
|
+
attachmentIdMappings.push({
|
|
238
|
+
localId: upload.attachment.id,
|
|
239
|
+
remoteId: mediaReferenceToFoundryMediaId(reference)
|
|
240
|
+
});
|
|
241
|
+
})).catch((cause) => {
|
|
242
|
+
const error = foundryActionError("foundry.upload", cause, opts.ir, name, parameters);
|
|
243
|
+
throw new BackendError({
|
|
244
|
+
operation: error.operation,
|
|
245
|
+
kind: error.kind,
|
|
246
|
+
message: error.message,
|
|
247
|
+
retryable: error.retryable,
|
|
248
|
+
issues: error.issues,
|
|
249
|
+
cause: error.cause,
|
|
250
|
+
actionOutcome: "not-committed"
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
const actionCodec = createFoundryCodec(opts.ir, {
|
|
254
|
+
resolveMediaReference: (id) => mediaReferences.get(id),
|
|
255
|
+
resolveAttachmentId: (id) => attachmentIds.get(id)
|
|
256
|
+
});
|
|
257
|
+
let invocation;
|
|
258
|
+
try {
|
|
259
|
+
invocation = prepareFoundryActionInvocation({
|
|
260
|
+
ir: opts.ir,
|
|
261
|
+
name,
|
|
262
|
+
parameters,
|
|
263
|
+
codec: actionCodec
|
|
264
|
+
});
|
|
265
|
+
} catch (cause) {
|
|
266
|
+
if (cause instanceof BackendError) throw cause;
|
|
267
|
+
throw new BackendError({
|
|
268
|
+
operation: "foundry.prepare",
|
|
269
|
+
kind: "InvalidRequest",
|
|
270
|
+
retryable: false,
|
|
271
|
+
actionOutcome: "not-committed",
|
|
272
|
+
message: "Invalid action parameters.",
|
|
273
|
+
cause: Redacted.make(cause)
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
let result;
|
|
277
|
+
try {
|
|
278
|
+
result = await Actions.applyWithOverrides(client, client.ontologyRid, toFoundryActionTypeName(name), {
|
|
279
|
+
request: {
|
|
280
|
+
options: {
|
|
281
|
+
mode: "VALIDATE_AND_EXECUTE",
|
|
282
|
+
returnEdits: "ALL_V2_WITH_DELETIONS"
|
|
283
|
+
},
|
|
284
|
+
parameters: invocation.parameters
|
|
285
|
+
},
|
|
286
|
+
overrides: invocation.overrides
|
|
287
|
+
}, { preview: true });
|
|
288
|
+
} catch (error) {
|
|
289
|
+
throw foundryActionError("foundry.applyAction", error, opts.ir, name, parameters);
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
Schema.decodeUnknownSync(ActionResponse)(result);
|
|
293
|
+
} catch (cause) {
|
|
294
|
+
throw new BackendError({
|
|
295
|
+
operation: "foundry.applyAction",
|
|
296
|
+
kind: "InvalidResponse",
|
|
297
|
+
retryable: false,
|
|
298
|
+
actionOutcome: "unknown",
|
|
299
|
+
message: "Foundry returned an invalid action response.",
|
|
300
|
+
cause: Redacted.make(cause)
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (result.validation?.result === "INVALID") throw new BackendError({
|
|
304
|
+
operation: "foundry.applyAction",
|
|
305
|
+
kind: "ValidationFailed",
|
|
306
|
+
message: "Submission failed validation.",
|
|
307
|
+
issues: getFoundryValidationIssues(result, parameters),
|
|
308
|
+
retryable: false,
|
|
309
|
+
actionOutcome: "not-committed"
|
|
310
|
+
});
|
|
311
|
+
return {
|
|
312
|
+
result,
|
|
313
|
+
attachmentIdMappings
|
|
314
|
+
};
|
|
315
|
+
};
|
|
316
|
+
const runQueryFunction = async (name, parameters, client = opts.client) => {
|
|
317
|
+
const queryFunctionType = opts.ir.queryFunctionTypes.find((candidate) => candidate.name === name);
|
|
318
|
+
if (!queryFunctionType) throw new BackendError({
|
|
319
|
+
operation: "foundry.queryFunction",
|
|
320
|
+
kind: "InvalidRequest",
|
|
321
|
+
retryable: false,
|
|
322
|
+
message: `Unknown Foundry query function type "${name}".`
|
|
323
|
+
});
|
|
324
|
+
const parameterTypes = new Map(queryFunctionType.parameters.map((parameter) => [parameter.name, parameter.type]));
|
|
325
|
+
const requestParameters = {};
|
|
326
|
+
for (const [parameterName, value] of Object.entries(parameters)) {
|
|
327
|
+
if (value === void 0) continue;
|
|
328
|
+
const parameterType = parameterTypes.get(parameterName);
|
|
329
|
+
requestParameters[parameterName] = parameterType ? codec.encodeValue(parameterType, value) : value;
|
|
330
|
+
}
|
|
331
|
+
const result = await Queries.execute(client, client.ontologyRid, name, { parameters: requestParameters });
|
|
332
|
+
try {
|
|
333
|
+
return codec.decodeValue(queryFunctionType.returnType, result.value);
|
|
334
|
+
} catch (cause) {
|
|
335
|
+
throw new BackendError({
|
|
336
|
+
operation: "foundry.queryFunction",
|
|
337
|
+
kind: "InvalidResponse",
|
|
338
|
+
retryable: false,
|
|
339
|
+
message: "Foundry returned an invalid query result.",
|
|
340
|
+
cause: Redacted.make(cause)
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const attempt = (operation, run) => Effect.tryPromise({
|
|
345
|
+
try: run,
|
|
346
|
+
catch: (cause) => classifyBackendFailure(operation, cause)
|
|
347
|
+
});
|
|
348
|
+
const validateAction = Effect.fn("Foundry.validateAction")(function* (name, parameters) {
|
|
349
|
+
const invocation = yield* Effect.try({
|
|
350
|
+
try: () => prepareFoundryActionInvocation({
|
|
351
|
+
ir: opts.ir,
|
|
352
|
+
name,
|
|
353
|
+
parameters,
|
|
354
|
+
codec
|
|
355
|
+
}),
|
|
356
|
+
catch: (cause) => foundryActionError("foundry.validateAction", cause, opts.ir, name, parameters)
|
|
357
|
+
});
|
|
358
|
+
const result = yield* Effect.tryPromise({
|
|
359
|
+
try: (signal) => Actions.applyWithOverrides(withRequestSignal(opts.client, signal), opts.client.ontologyRid, toFoundryActionTypeName(name), {
|
|
360
|
+
request: {
|
|
361
|
+
options: { mode: "VALIDATE_ONLY" },
|
|
362
|
+
parameters: invocation.parameters
|
|
363
|
+
},
|
|
364
|
+
overrides: invocation.overrides
|
|
365
|
+
}, { preview: true }),
|
|
366
|
+
catch: (cause) => foundryActionError("foundry.validateAction", cause, opts.ir, name, parameters)
|
|
367
|
+
});
|
|
368
|
+
const { validation } = yield* Schema.decodeUnknownEffect(ValidationResponse)(result).pipe(Effect.mapError((cause) => new BackendError({
|
|
369
|
+
operation: "foundry.validateAction",
|
|
370
|
+
kind: "InvalidResponse",
|
|
371
|
+
retryable: false,
|
|
372
|
+
actionOutcome: "not-committed",
|
|
373
|
+
message: "Foundry returned an invalid validation response.",
|
|
374
|
+
cause: Redacted.make(cause)
|
|
375
|
+
})));
|
|
376
|
+
return certain(validation.result === "VALID" ? {
|
|
377
|
+
kind: "ok",
|
|
378
|
+
value: void 0
|
|
379
|
+
} : {
|
|
380
|
+
kind: "err",
|
|
381
|
+
value: getFoundryValidationIssues(result, parameters)
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
const validateActionDraft = Effect.fn("Foundry.validateActionDraft")(function* (name, parameters, live) {
|
|
385
|
+
const action = opts.ir.actionTypes.find((candidate) => candidate.name === name);
|
|
386
|
+
if (!action) return yield* new BackendError({
|
|
387
|
+
operation: "foundry.validateActionDraft",
|
|
388
|
+
kind: "InvalidRequest",
|
|
389
|
+
message: "Unknown action type.",
|
|
390
|
+
retryable: false
|
|
391
|
+
});
|
|
392
|
+
const knownParameters = /* @__PURE__ */ new Set([...Object.entries(parameters).flatMap(([key, value]) => value === void 0 ? [] : [key]), ...live.knownParameters]);
|
|
393
|
+
const missing = action.parameters.filter((parameter) => parameters[parameter.name] === void 0 && knownParameters.has(parameter.name) && !unwrapType(resolveType(opts.ir, parameter.type)).isOptional);
|
|
394
|
+
if (missing.length) return certain({
|
|
395
|
+
kind: "err",
|
|
396
|
+
value: missing.map((parameter) => ({
|
|
397
|
+
message: "A value is required.",
|
|
398
|
+
path: [parameter.name],
|
|
399
|
+
code: "required",
|
|
400
|
+
category: "input",
|
|
401
|
+
source: "parameter",
|
|
402
|
+
messageSource: "standard"
|
|
403
|
+
}))
|
|
404
|
+
});
|
|
405
|
+
if (!action.parameters.some((parameter) => parameters[parameter.name] === void 0 && !knownParameters.has(parameter.name))) return yield* validateAction(name, parameters);
|
|
406
|
+
const value = live.context?.[FOUNDRY_CURRENT_USER_CONTEXT_FIELD];
|
|
407
|
+
const userId = typeof value === "string" ? value : void 0;
|
|
408
|
+
if (!userId) return uncertain();
|
|
409
|
+
return yield* Effect.tryPromise({
|
|
410
|
+
try: async (signal) => validateFoundryActionDraftCriteria({
|
|
411
|
+
client: withRequestSignal(opts.client, signal),
|
|
412
|
+
criteria: await loadFoundrySubmissionCriteria({
|
|
413
|
+
client: withRequestSignal(opts.client, signal),
|
|
414
|
+
actionTypeName: name,
|
|
415
|
+
userId
|
|
416
|
+
}),
|
|
417
|
+
userId,
|
|
418
|
+
parameters,
|
|
419
|
+
knownParameters
|
|
420
|
+
}),
|
|
421
|
+
catch: (cause) => foundryActionError("foundry.validateActionDraft", cause, opts.ir, name, parameters)
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
return yield* makeFoundryBackend({
|
|
425
|
+
client: opts.client,
|
|
426
|
+
ir: opts.ir,
|
|
427
|
+
context,
|
|
428
|
+
watch: opts.watch,
|
|
429
|
+
encrypted: makeFoundryEncryptedValues(opts.client, opts.ir),
|
|
430
|
+
users: opts.users && {
|
|
431
|
+
objectType: opts.users.objectType,
|
|
432
|
+
loadSubset: (query, signal) => opts.users.loadSubset(opts.client, query, signal)
|
|
433
|
+
},
|
|
434
|
+
submitAction: (invocation, signal) => submitAction(invocation.name, invocation.parameters, {
|
|
435
|
+
signal,
|
|
436
|
+
attachmentUploads: invocation.attachmentUploads ? [...invocation.attachmentUploads] : void 0
|
|
437
|
+
}, withRequestSignal(opts.client, signal)),
|
|
438
|
+
decodeObject: (objectType, value) => codec.decodeObject(objectType, value),
|
|
439
|
+
queryFunction: (name, parameters, signal) => runQueryFunction(name, parameters, withRequestSignal(opts.client, signal)),
|
|
440
|
+
attachments: {
|
|
441
|
+
stage: (value, blob, settings) => attempt("attachment.stage", async (signal) => {
|
|
442
|
+
const target = settings?.target;
|
|
443
|
+
if (!target || getAttachmentProviderType(target) === "media") throw new BackendError({
|
|
444
|
+
operation: "attachment.stage",
|
|
445
|
+
kind: "NotImplemented",
|
|
446
|
+
retryable: false,
|
|
447
|
+
message: "This attachment target must be uploaded during action execution."
|
|
448
|
+
});
|
|
449
|
+
return await attachments.materializeAttachment(value, blob, {
|
|
450
|
+
target,
|
|
451
|
+
signal
|
|
452
|
+
}, withRequestSignal(opts.client, signal)) ?? value;
|
|
453
|
+
}),
|
|
454
|
+
read: (value, range) => scopedByteSource(Effect.gen(function* () {
|
|
455
|
+
if (range && (!Number.isSafeInteger(range.offset ?? 0) || (range.offset ?? 0) < 0 || range.length !== void 0 && (!Number.isSafeInteger(range.length) || range.length < 0))) return yield* new BackendError({
|
|
456
|
+
operation: "attachment.read",
|
|
457
|
+
kind: "InvalidRequest",
|
|
458
|
+
message: "Invalid byte range.",
|
|
459
|
+
retryable: false
|
|
460
|
+
});
|
|
461
|
+
const download = yield* Effect.acquireRelease(Effect.sync(() => new AbortController()), (controller) => Effect.sync(() => controller.abort()));
|
|
462
|
+
const blob = yield* attempt("attachment.read", (signal) => attachments.getAttachmentContent(value, { signal: AbortSignal.any([signal, download.signal]) }));
|
|
463
|
+
return range ? sliceByteSource(blob, range.offset ?? 0, range.length) : byteSource(blob);
|
|
464
|
+
})),
|
|
465
|
+
metadata: (value, settings) => Effect.gen(function* () {
|
|
466
|
+
const meta = yield* attempt("attachment.metadata", async (signal) => await attachments.getAttachmentMetadata?.(value, settings?.select ?? [
|
|
467
|
+
"size",
|
|
468
|
+
"type",
|
|
469
|
+
"name"
|
|
470
|
+
], { signal }) ?? {});
|
|
471
|
+
if (settings?.select || meta.size !== void 0 && meta.type !== void 0) return {
|
|
472
|
+
size: meta.size,
|
|
473
|
+
type: meta.type,
|
|
474
|
+
name: meta.name,
|
|
475
|
+
dimensions: meta.dimensions ?? void 0
|
|
476
|
+
};
|
|
477
|
+
const download = yield* Effect.acquireRelease(Effect.sync(() => new AbortController()), (controller) => Effect.sync(() => controller.abort()));
|
|
478
|
+
const blob = yield* attempt("attachment.read", (signal) => attachments.getAttachmentContent(value, { signal: AbortSignal.any([signal, download.signal]) }));
|
|
479
|
+
const source = byteSource(blob);
|
|
480
|
+
return {
|
|
481
|
+
size: source.size ?? (yield* byteChunks(source).pipe(Stream.runFold(() => 0, (total, chunk) => total + chunk.length), Effect.mapError((cause) => new BackendError({
|
|
482
|
+
operation: "attachment.metadata",
|
|
483
|
+
kind: "Unavailable",
|
|
484
|
+
message: "Attachment metadata is unavailable.",
|
|
485
|
+
retryable: true,
|
|
486
|
+
cause
|
|
487
|
+
})))),
|
|
488
|
+
type: source.type,
|
|
489
|
+
name: meta.name,
|
|
490
|
+
dimensions: meta.dimensions ?? void 0
|
|
491
|
+
};
|
|
492
|
+
}).pipe(Effect.scoped)
|
|
493
|
+
}
|
|
494
|
+
}).pipe(Effect.map((native) => ({
|
|
495
|
+
...native,
|
|
496
|
+
validateAction: (name, parameters, settings) => settings?.knownParameters ? validateActionDraft(name, parameters, {
|
|
497
|
+
context,
|
|
498
|
+
knownParameters: settings.knownParameters
|
|
499
|
+
}) : validateAction(name, parameters)
|
|
500
|
+
})));
|
|
501
|
+
});
|
|
502
|
+
//#endregion
|
|
503
|
+
export { isFoundryNotFoundError, makeFoundryOntologyBackend };
|
|
504
|
+
|
|
505
|
+
//# sourceMappingURL=makeFoundryOntologyBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makeFoundryOntologyBackend.js","names":[],"sources":["../../src/adapter/makeFoundryOntologyBackend.ts"],"sourcesContent":["import { invariant } from \"@bobbyfidz/panic\";\nimport { MediaSets } from \"@osdk/foundry.mediasets\";\nimport {\n Actions,\n AttachmentRid,\n Attachments,\n MediaReferenceProperties,\n Queries,\n} from \"@osdk/foundry.ontologies\";\nimport { BackendError, classifyBackendFailure } from \"@party-stack/ontology-backend\";\nimport { certain, uncertain, type OntologyIR } from \"@party-stack/ontology-spec\";\nimport { resolveType, unwrapType } from \"@party-stack/ontology-spec/utils\";\nimport {\n byteSource,\n byteChunks,\n readableByteSource,\n sliceByteSource,\n scopedByteSource,\n type ByteInput,\n} from \"@party-stack/ontology-storage/blobs\";\nimport { Effect, Stream, Schema, Redacted, type Types } from \"effect\";\nimport { Temporal } from \"temporal-polyfill\";\nimport { FOUNDRY_CURRENT_USER_CONTEXT_FIELD } from \"../context.js\";\nimport { getFoundryActionOverrideParameterMapping } from \"../meta/convertMetaActionType.js\";\nimport { getFoundryAttachmentKind } from \"../meta/foundryAttachmentMetadata.js\";\nimport { toFoundryActionTypeName } from \"../utils/actionTypeName.js\";\nimport { makeFoundryBackend } from \"./backend.js\";\nimport { makeFoundryEncryptedValues } from \"./encrypted.js\";\nimport { foundryActionError } from \"./foundryActionError.js\";\nimport {\n getFoundryValidationIssues,\n loadFoundrySubmissionCriteria,\n validateFoundryActionDraftCriteria,\n} from \"./foundryActionValidation.js\";\nimport { createFoundryCodec } from \"./foundryCodec.js\";\nimport { decodeFoundryMediaId, mediaReferenceToFoundryMediaId } from \"./foundryMediaId.js\";\nimport { uploadFoundryMedia, uploadFoundryAttachment } from \"./uploads.js\";\nimport type { OntologyClient } from \"@party-stack/foundry-client\";\nimport type {\n BackendAttachments,\n BackendSnapshot,\n ValidationReport,\n ActionReceipt,\n} from \"@party-stack/ontology-backend\";\ntype PartialAttachmentMetadata = Types.Mutable<Effect.Success<ReturnType<BackendAttachments[\"metadata\"]>>>;\ntype OntologyAttachmentIdMapping = NonNullable<ActionReceipt[\"attachmentIdMappings\"]>[number];\nimport type { attachment } from \"@party-stack/ontology-spec/values\";\nimport type { Query } from \"@party-stack/ontology-storage\";\n\nconst attachmentFailure = (kind: \"InvalidRequest\" | \"InvalidResponse\", message: string) =>\n new BackendError({\n operation: \"foundry.attachment\",\n kind,\n message,\n retryable: false,\n });\n\nfunction isFoundryAttachmentRid(value: string): value is AttachmentRid {\n return /^ri\\.attachments\\.[^.]+\\.attachment\\..+$/.test(value);\n}\n\nexport function isFoundryNotFoundError(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n const foundryError = error as {\n statusCode?: unknown;\n errorCode?: unknown;\n };\n return foundryError.statusCode === 404 || foundryError.errorCode === \"NOT_FOUND\";\n}\n\nexport interface FoundryUsersIntegration {\n objectType: string;\n loadSubset(client: OntologyClient, query: Query, signal: AbortSignal): Promise<BackendSnapshot>;\n getAttachmentContent?(client: OntologyClient, attachment: attachment): Promise<ByteInput | undefined>;\n getAttachmentMetadata?(\n client: OntologyClient,\n attachment: attachment,\n selection: readonly (keyof PartialAttachmentMetadata)[]\n ): Promise<PartialAttachmentMetadata | undefined>;\n}\n\ntype ApplyActionResult = Awaited<ReturnType<typeof Actions.applyWithOverrides>> & {\n operationId?: string;\n};\n\nfunction serializeOverrideValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n return String(value);\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (value instanceof Temporal.Instant) {\n return value.toString();\n }\n if (value instanceof Temporal.PlainDate || value instanceof Temporal.PlainDateTime) {\n return value.toString();\n }\n return JSON.stringify(value) ?? \"\";\n}\n\nfunction serializeActionExecutionTime(value: unknown): string {\n try {\n const candidate = value instanceof Date ? value.toISOString() : String(value);\n return Temporal.Instant.from(candidate).toString();\n } catch (cause) {\n throw new TypeError(\"Invalid action execution time: expected a Date or Temporal-like ISO instant.\", {\n cause,\n });\n }\n}\n\nfunction getAttachmentName(attachment: unknown): string | undefined {\n if (typeof attachment !== \"object\" || attachment === null || Array.isArray(attachment)) {\n return undefined;\n }\n const name = (attachment as Record<string, unknown>).name;\n return typeof name === \"string\" ? name : undefined;\n}\n\nfunction getAttachmentProviderType(\n target: { meta?: Record<string, unknown> } | undefined\n): \"attachment\" | \"media\" {\n return getFoundryAttachmentKind(target?.meta);\n}\n\nfunction prepareFoundryActionInvocation(options: {\n ir: OntologyIR;\n name: string;\n parameters: Record<string, unknown>;\n codec: ReturnType<typeof createFoundryCodec>;\n}): {\n parameters: Record<string, unknown>;\n overrides: {\n uniqueIdentifierLinkIdValues: Record<string, string>;\n actionExecutionTime?: string;\n };\n} {\n const actionType = options.ir.actionTypes.find((candidate) => candidate.name === options.name);\n if (!actionType) {\n throw new BackendError({\n operation: \"foundry.prepare\",\n kind: \"InvalidRequest\",\n retryable: false,\n actionOutcome: \"not-committed\",\n message: `Unknown Foundry action type \"${options.name}\".`,\n });\n }\n const overrideMapping = getFoundryActionOverrideParameterMapping(actionType);\n const parameterTypes = new Map(\n actionType.parameters.map((parameter) => [parameter.name, parameter.type])\n );\n const parameters: Record<string, unknown> = {};\n const uniqueIdentifierLinkIdValues: Record<string, string> = {};\n let actionExecutionTime: string | undefined;\n\n try {\n for (const [parameterName, value] of Object.entries(options.parameters)) {\n if (overrideMapping.uuidByParameterName.has(parameterName)) {\n if (value !== undefined) {\n uniqueIdentifierLinkIdValues[overrideMapping.uuidByParameterName.get(parameterName)!] =\n serializeOverrideValue(value);\n }\n continue;\n }\n if (overrideMapping.nowParameterName === parameterName) {\n if (value !== undefined) {\n actionExecutionTime = serializeActionExecutionTime(value);\n }\n continue;\n }\n if (value !== undefined) {\n const parameterType = parameterTypes.get(parameterName);\n parameters[parameterName] = parameterType\n ? options.codec.encodeValue(parameterType, value)\n : value;\n }\n }\n } catch (cause) {\n throw new BackendError({\n operation: \"foundry.prepare\",\n kind: \"InvalidRequest\",\n retryable: false,\n actionOutcome: \"not-committed\",\n message: \"Invalid action parameters.\",\n cause: Redacted.make(cause),\n });\n }\n\n return {\n parameters,\n overrides: {\n uniqueIdentifierLinkIdValues,\n actionExecutionTime,\n },\n };\n}\n\nexport interface FoundryOntologyBackendOptions {\n client: OntologyClient;\n ir: OntologyIR;\n users?: FoundryUsersIntegration;\n watch?: boolean;\n context?: Record<string, unknown>;\n}\n\nfunction withRequestSignal(client: OntologyClient, signal?: AbortSignal): OntologyClient {\n return signal\n ? {\n ...client,\n fetch: (input, init) =>\n client.fetch(input, {\n ...init,\n signal: init?.signal ? AbortSignal.any([signal, init.signal]) : signal,\n }),\n }\n : client;\n}\n\nexport const makeFoundryOntologyBackend = Effect.fn(\"Foundry.makeBackend\")(function* (\n opts: FoundryOntologyBackendOptions\n) {\n const context = opts.context ?? {};\n const codec = yield* Effect.try({\n try: () => createFoundryCodec(opts.ir),\n catch: (cause) =>\n new BackendError({\n operation: \"foundry.open\",\n kind: \"InvalidConfiguration\",\n retryable: false,\n message: \"Invalid Foundry definition.\",\n cause: Redacted.make(cause),\n }),\n });\n const Validation = Schema.Struct({ result: Schema.Literals([\"VALID\", \"INVALID\"]) });\n const ActionResponse = Schema.Struct({ validation: Schema.optional(Validation) });\n const ValidationResponse = Schema.Struct({ validation: Validation });\n const attachments = {\n materializeAttachment: async (\n attachment: attachment,\n input: ByteInput,\n {\n target,\n signal,\n }: { target?: import(\"@party-stack/ontology-spec\").AttachmentTypeDef; signal?: AbortSignal },\n client = opts.client\n ) => {\n invariant(\n target,\n \"A property target must be passed to materializeAttachment in the Foundry adapter so that we know whether to target attachments or media.\"\n );\n invariant(\n getAttachmentProviderType(target) === \"attachment\",\n \"Foundry media references must be uploaded during action execution.\"\n );\n const filename = byteSource(input).name ?? \"\";\n if (!isFoundryAttachmentRid(attachment.id)) {\n const uploaded = await uploadFoundryAttachment(client, input, { filename, signal });\n return {\n ...attachment,\n id: uploaded.rid,\n };\n }\n try {\n await Attachments.get(client, attachment.id);\n return;\n } catch (error) {\n if (!isFoundryNotFoundError(error)) {\n throw error;\n }\n }\n await uploadFoundryAttachment(client, input, { filename, rid: attachment.id, signal });\n },\n getAttachmentContent: async (attachment: attachment, readOptions?: { signal?: AbortSignal }) => {\n const client = withRequestSignal(opts.client, readOptions?.signal);\n const userContent = await opts.users?.getAttachmentContent?.(client, attachment);\n if (userContent) return userContent;\n const media = decodeFoundryMediaId(attachment.id);\n if (media) {\n const source = attachment.source;\n if (!source)\n throw attachmentFailure(\n \"InvalidRequest\",\n \"Media reads require an object property source.\"\n );\n const response = await MediaReferenceProperties.getMediaContent(\n client,\n client.ontologyRid,\n source.objectType,\n String(source.primaryKey),\n source.property,\n { preview: true }\n );\n if (!response.body)\n throw attachmentFailure(\"InvalidResponse\", \"Foundry returned no media body.\");\n return readableByteSource(response.body, {\n type: response.headers.get(\"content-type\") ?? attachment.type,\n });\n }\n const contents = await Attachments.read(client, attachment.id);\n if (!contents.body)\n throw attachmentFailure(\"InvalidResponse\", \"Foundry returned no attachment body.\");\n return readableByteSource(contents.body, {\n type: contents.headers.get(\"content-type\") ?? attachment.type,\n });\n },\n getAttachmentMetadata: async (\n attachment: attachment,\n selection: readonly (keyof PartialAttachmentMetadata)[],\n readOptions?: { signal?: AbortSignal }\n ): Promise<PartialAttachmentMetadata> => {\n const client = withRequestSignal(opts.client, readOptions?.signal);\n const userMetadata = await opts.users?.getAttachmentMetadata?.(client, attachment, selection);\n if (userMetadata) return userMetadata;\n const media = decodeFoundryMediaId(attachment.id);\n if (media) {\n const result: PartialAttachmentMetadata = {};\n if (attachment.type !== undefined) {\n result.type = attachment.type;\n }\n if (selection.includes(\"dimensions\")) {\n const detailed = await MediaSets.metadata(client, media.mediaSetRid, media.mediaItemRid);\n result.size = detailed.sizeBytes;\n if (detailed.type === \"imagery\" && detailed.dimensions) {\n result.dimensions = {\n width: detailed.dimensions.width,\n height: detailed.dimensions.height,\n };\n }\n }\n const missingMetadata = selection.filter((field) => result[field] === undefined);\n const needsBasicMetadata = missingMetadata.some((field) => field !== \"dimensions\");\n if (!needsBasicMetadata) return result;\n\n const source = attachment.source;\n if (!source)\n throw attachmentFailure(\n \"InvalidRequest\",\n \"Media reads require an object property source.\"\n );\n const info = await MediaReferenceProperties.getMediaMetadata(\n client,\n client.ontologyRid,\n source.objectType,\n String(source.primaryKey),\n source.property,\n { preview: true }\n );\n return {\n ...result,\n size: Number(info.sizeBytes),\n type: info.mediaType,\n name: info.path,\n };\n }\n const metadata = await Attachments.get(client, attachment.id);\n return {\n size: Number(metadata.sizeBytes),\n type: metadata.mediaType,\n name: metadata.filename,\n };\n },\n };\n\n // Submission only calls provider APIs; Replica owns read-back and confirmation.\n const submitAction = async (\n name: string,\n parameters: Record<string, unknown>,\n context: {\n attachmentUploads?: readonly import(\"@party-stack/ontology-backend\").AttachmentUpload[];\n signal?: AbortSignal;\n },\n client = opts.client\n ) => {\n if (!opts.ir.actionTypes.some((action) => action.name === name))\n throw new BackendError({\n operation: \"foundry.applyAction\",\n kind: \"InvalidRequest\",\n retryable: false,\n actionOutcome: \"not-committed\",\n message: \"Unknown Foundry action type.\",\n });\n const mediaReferences = new Map<string, Awaited<ReturnType<typeof MediaSets.uploadMedia>>>();\n const attachmentIdMappings: OntologyAttachmentIdMapping[] = [];\n const attachmentIds = new Map<string, string>();\n await Promise.all(\n [\n ...new Map(\n (context.attachmentUploads ?? []).map((upload) => [upload.attachment.id, upload])\n ).values(),\n ].map(async (upload) => {\n if (getAttachmentProviderType(upload.target) !== \"media\") {\n const result = await attachments.materializeAttachment(\n upload.attachment,\n upload.blob,\n {\n target: upload.target,\n signal: context.signal,\n },\n client\n );\n const id = result?.id ?? upload.attachment.id;\n attachmentIds.set(upload.attachment.id, id);\n if (id !== upload.attachment.id)\n attachmentIdMappings.push({ localId: upload.attachment.id, remoteId: id });\n return;\n }\n const reference = await uploadFoundryMedia(client, upload.blob, {\n filename: getAttachmentName(upload.blob) ?? upload.attachment.id,\n signal: context.signal,\n });\n mediaReferences.set(upload.attachment.id, reference);\n attachmentIdMappings.push({\n localId: upload.attachment.id,\n remoteId: mediaReferenceToFoundryMediaId(reference),\n });\n })\n ).catch((cause) => {\n const error = foundryActionError(\"foundry.upload\", cause, opts.ir, name, parameters);\n throw new BackendError({\n operation: error.operation,\n kind: error.kind,\n message: error.message,\n retryable: error.retryable,\n issues: error.issues,\n cause: error.cause,\n actionOutcome: \"not-committed\",\n });\n });\n const actionCodec = createFoundryCodec(opts.ir, {\n resolveMediaReference: (id) => mediaReferences.get(id),\n resolveAttachmentId: (id) => attachmentIds.get(id),\n });\n let invocation: ReturnType<typeof prepareFoundryActionInvocation>;\n try {\n invocation = prepareFoundryActionInvocation({\n ir: opts.ir,\n name,\n parameters,\n codec: actionCodec,\n });\n } catch (cause) {\n if (cause instanceof BackendError) throw cause;\n throw new BackendError({\n operation: \"foundry.prepare\",\n kind: \"InvalidRequest\",\n retryable: false,\n actionOutcome: \"not-committed\",\n message: \"Invalid action parameters.\",\n cause: Redacted.make(cause),\n });\n }\n\n let result: ApplyActionResult;\n try {\n result = await Actions.applyWithOverrides(\n client,\n client.ontologyRid,\n toFoundryActionTypeName(name),\n {\n request: {\n options: {\n mode: \"VALIDATE_AND_EXECUTE\",\n returnEdits: \"ALL_V2_WITH_DELETIONS\",\n },\n parameters: invocation.parameters,\n },\n overrides: invocation.overrides,\n },\n // oxlint-disable-next-line typescript/no-unsafe-argument\n {\n preview: true,\n // oxlint-disable-next-line typescript/no-explicit-any\n }\n );\n } catch (error) {\n throw foundryActionError(\"foundry.applyAction\", error, opts.ir, name, parameters);\n }\n try {\n Schema.decodeUnknownSync(ActionResponse)(result);\n } catch (cause) {\n throw new BackendError({\n operation: \"foundry.applyAction\",\n kind: \"InvalidResponse\",\n retryable: false,\n actionOutcome: \"unknown\",\n message: \"Foundry returned an invalid action response.\",\n cause: Redacted.make(cause),\n });\n }\n if (result.validation?.result === \"INVALID\") {\n throw new BackendError({\n operation: \"foundry.applyAction\",\n kind: \"ValidationFailed\",\n message: \"Submission failed validation.\",\n issues: getFoundryValidationIssues(result, parameters),\n retryable: false,\n actionOutcome: \"not-committed\",\n });\n }\n return { result, attachmentIdMappings };\n };\n\n const runQueryFunction = async (\n name: string,\n parameters: Record<string, unknown>,\n client = opts.client\n ) => {\n const queryFunctionType = opts.ir.queryFunctionTypes.find((candidate) => candidate.name === name);\n if (!queryFunctionType) {\n throw new BackendError({\n operation: \"foundry.queryFunction\",\n kind: \"InvalidRequest\",\n retryable: false,\n message: `Unknown Foundry query function type \"${name}\".`,\n });\n }\n\n const parameterTypes = new Map(\n queryFunctionType.parameters.map((parameter) => [parameter.name, parameter.type])\n );\n const requestParameters: Record<string, unknown> = {};\n for (const [parameterName, value] of Object.entries(parameters)) {\n if (value === undefined) continue;\n const parameterType = parameterTypes.get(parameterName);\n requestParameters[parameterName] = parameterType\n ? codec.encodeValue(parameterType, value)\n : value;\n }\n\n const result = await Queries.execute(client, client.ontologyRid, name, {\n parameters: requestParameters,\n });\n\n try {\n return codec.decodeValue(queryFunctionType.returnType, result.value);\n } catch (cause) {\n throw new BackendError({\n operation: \"foundry.queryFunction\",\n kind: \"InvalidResponse\",\n retryable: false,\n message: \"Foundry returned an invalid query result.\",\n cause: Redacted.make(cause),\n });\n }\n };\n const attempt = <A>(operation: string, run: (signal: AbortSignal) => Promise<A>) =>\n Effect.tryPromise({\n try: run,\n catch: (cause) => classifyBackendFailure(operation, cause),\n });\n const validateAction = Effect.fn(\"Foundry.validateAction\")(function* (\n name: string,\n parameters: Record<string, unknown>\n ): Effect.fn.Return<ValidationReport, BackendError> {\n const invocation = yield* Effect.try({\n try: () => prepareFoundryActionInvocation({ ir: opts.ir, name, parameters, codec }),\n catch: (cause) => foundryActionError(\"foundry.validateAction\", cause, opts.ir, name, parameters),\n });\n const result = yield* Effect.tryPromise({\n try: (signal) =>\n Actions.applyWithOverrides(\n withRequestSignal(opts.client, signal),\n opts.client.ontologyRid,\n toFoundryActionTypeName(name),\n {\n request: {\n options: { mode: \"VALIDATE_ONLY\" },\n parameters: invocation.parameters,\n },\n overrides: invocation.overrides,\n },\n { preview: true }\n ),\n catch: (cause) => foundryActionError(\"foundry.validateAction\", cause, opts.ir, name, parameters),\n });\n const { validation } = yield* Schema.decodeUnknownEffect(ValidationResponse)(result).pipe(\n Effect.mapError(\n (cause) =>\n new BackendError({\n operation: \"foundry.validateAction\",\n kind: \"InvalidResponse\",\n retryable: false,\n actionOutcome: \"not-committed\",\n message: \"Foundry returned an invalid validation response.\",\n cause: Redacted.make(cause),\n })\n )\n );\n return certain(\n validation.result === \"VALID\"\n ? { kind: \"ok\" as const, value: undefined }\n : { kind: \"err\" as const, value: getFoundryValidationIssues(result, parameters) }\n );\n });\n const validateActionDraft = Effect.fn(\"Foundry.validateActionDraft\")(function* (\n name: string,\n parameters: Record<string, unknown>,\n live: { knownParameters: readonly string[]; context?: Record<string, unknown> }\n ): Effect.fn.Return<ValidationReport, BackendError> {\n const action = opts.ir.actionTypes.find((candidate) => candidate.name === name);\n if (!action)\n return yield* new BackendError({\n operation: \"foundry.validateActionDraft\",\n kind: \"InvalidRequest\",\n message: \"Unknown action type.\",\n retryable: false,\n });\n const knownParameters = new Set([\n ...Object.entries(parameters).flatMap(([key, value]) => (value === undefined ? [] : [key])),\n ...live.knownParameters,\n ]);\n const missing = action.parameters.filter(\n (parameter) =>\n parameters[parameter.name] === undefined &&\n knownParameters.has(parameter.name) &&\n !unwrapType(resolveType(opts.ir, parameter.type)).isOptional\n );\n if (missing.length)\n return certain({\n kind: \"err\" as const,\n value: missing.map((parameter) => ({\n message: \"A value is required.\",\n path: [parameter.name],\n code: \"required\",\n category: \"input\" as const,\n source: \"parameter\" as const,\n messageSource: \"standard\" as const,\n })),\n });\n if (\n !action.parameters.some(\n (parameter) =>\n parameters[parameter.name] === undefined && !knownParameters.has(parameter.name)\n )\n )\n return yield* validateAction(name, parameters);\n const value = live.context?.[FOUNDRY_CURRENT_USER_CONTEXT_FIELD];\n const userId = typeof value === \"string\" ? value : undefined;\n if (!userId) return uncertain();\n return yield* Effect.tryPromise({\n try: async (signal) =>\n validateFoundryActionDraftCriteria({\n client: withRequestSignal(opts.client, signal),\n criteria: await loadFoundrySubmissionCriteria({\n client: withRequestSignal(opts.client, signal),\n actionTypeName: name,\n userId,\n }),\n userId,\n parameters,\n knownParameters,\n }),\n catch: (cause) =>\n foundryActionError(\"foundry.validateActionDraft\", cause, opts.ir, name, parameters),\n });\n });\n return yield* makeFoundryBackend({\n client: opts.client,\n ir: opts.ir,\n context,\n watch: opts.watch,\n encrypted: makeFoundryEncryptedValues(opts.client, opts.ir),\n users: opts.users && {\n objectType: opts.users.objectType,\n loadSubset: (query, signal) => opts.users!.loadSubset(opts.client, query, signal),\n },\n submitAction: (invocation, signal) =>\n submitAction(\n invocation.name,\n invocation.parameters,\n {\n signal,\n attachmentUploads: invocation.attachmentUploads\n ? [...invocation.attachmentUploads]\n : undefined,\n },\n withRequestSignal(opts.client, signal)\n ),\n decodeObject: (objectType, value) => codec.decodeObject(objectType, value),\n queryFunction: (name, parameters, signal) =>\n runQueryFunction(name, parameters, withRequestSignal(opts.client, signal)),\n attachments: {\n stage: (value, blob, settings) =>\n attempt(\"attachment.stage\", async (signal) => {\n const target = settings?.target;\n if (!target || getAttachmentProviderType(target) === \"media\")\n throw new BackendError({\n operation: \"attachment.stage\",\n kind: \"NotImplemented\",\n retryable: false,\n message: \"This attachment target must be uploaded during action execution.\",\n });\n return (\n (await attachments.materializeAttachment(\n value,\n blob,\n { target, signal },\n withRequestSignal(opts.client, signal)\n )) ?? value\n );\n }),\n read: (value, range) =>\n scopedByteSource(\n Effect.gen(function* () {\n if (\n range &&\n (!Number.isSafeInteger(range.offset ?? 0) ||\n (range.offset ?? 0) < 0 ||\n (range.length !== undefined &&\n (!Number.isSafeInteger(range.length) || range.length < 0)))\n )\n return yield* new BackendError({\n operation: \"attachment.read\",\n kind: \"InvalidRequest\",\n message: \"Invalid byte range.\",\n retryable: false,\n });\n // Fetch resolves at headers; retain cancellation through body consumption.\n const download = yield* Effect.acquireRelease(\n Effect.sync(() => new AbortController()),\n (controller) => Effect.sync(() => controller.abort())\n );\n const blob = yield* attempt(\"attachment.read\", (signal) =>\n attachments.getAttachmentContent(value, {\n signal: AbortSignal.any([signal, download.signal]),\n })\n );\n return range\n ? sliceByteSource(blob, range.offset ?? 0, range.length)\n : byteSource(blob);\n })\n ),\n metadata: (value, settings) =>\n Effect.gen(function* () {\n const meta = yield* attempt(\n \"attachment.metadata\",\n async (signal) =>\n (await attachments.getAttachmentMetadata?.(\n value,\n settings?.select ?? [\"size\", \"type\", \"name\"],\n { signal }\n )) ?? {}\n );\n if (settings?.select || (meta.size !== undefined && meta.type !== undefined))\n return {\n size: meta.size,\n type: meta.type,\n name: meta.name,\n dimensions: meta.dimensions ?? undefined,\n };\n // Fetch resolves at headers; retain cancellation through body consumption.\n const download = yield* Effect.acquireRelease(\n Effect.sync(() => new AbortController()),\n (controller) => Effect.sync(() => controller.abort())\n );\n const blob = yield* attempt(\"attachment.read\", (signal) =>\n attachments.getAttachmentContent(value, {\n signal: AbortSignal.any([signal, download.signal]),\n })\n );\n const source = byteSource(blob);\n const size =\n source.size ??\n (yield* byteChunks(source).pipe(\n Stream.runFold(\n () => 0,\n (total, chunk) => total + chunk.length\n ),\n Effect.mapError(\n (cause) =>\n new BackendError({\n operation: \"attachment.metadata\",\n kind: \"Unavailable\",\n message: \"Attachment metadata is unavailable.\",\n retryable: true,\n cause,\n })\n )\n ));\n return {\n size,\n type: source.type,\n name: meta.name,\n dimensions: meta.dimensions ?? undefined,\n };\n }).pipe(Effect.scoped),\n },\n }).pipe(\n Effect.map((native) => ({\n ...native,\n validateAction: (\n name: string,\n parameters: Record<string, unknown>,\n settings?: { readonly knownParameters?: readonly string[] }\n ) =>\n settings?.knownParameters\n ? validateActionDraft(name, parameters, {\n context,\n knownParameters: settings.knownParameters,\n })\n : validateAction(name, parameters),\n }))\n );\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SearchJsonQueryV2 } from "@osdk/foundry.ontologies";
|
|
2
|
+
import { Predicate } from "@party-stack/ontology-storage";
|
|
3
|
+
//#region src/adapter/subsetFilter.d.ts
|
|
4
|
+
export declare const subsetFilter: (predicate: Predicate | undefined) => SearchJsonQueryV2 | undefined;
|
|
5
|
+
/** Report effective placement, including supported OR branches that could not safely be sent. */
|
|
6
|
+
export declare function analyzeSubsetFilter(predicate: Predicate | undefined): {
|
|
7
|
+
query: SearchJsonQueryV2 | undefined;
|
|
8
|
+
predicates: {
|
|
9
|
+
readonly path: readonly number[];
|
|
10
|
+
readonly execution: "adapter" | "candidate" | "engine" | "source";
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
//# sourceMappingURL=subsetFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subsetFilter.d.ts","names":[],"sources":["../../src/adapter/subsetFilter.ts"],"mappings":";;;qBAkFa,eAAY,WAAe,0BAAwB;;wBAIhD,oBAAoB,WAAW;SAAA"}
|