@party-stack/foundry-ontology 0.19.0 → 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.
Files changed (202) hide show
  1. package/README.md +53 -32
  2. package/lib/adapter/backend.d.ts +35 -0
  3. package/lib/adapter/backend.d.ts.map +1 -0
  4. package/lib/adapter/backend.js +210 -0
  5. package/lib/adapter/backend.js.map +1 -0
  6. package/lib/adapter/encrypted.d.ts +12 -0
  7. package/lib/adapter/encrypted.d.ts.map +1 -0
  8. package/lib/adapter/encrypted.js +79 -0
  9. package/lib/adapter/encrypted.js.map +1 -0
  10. package/lib/adapter/foundryActionError.d.ts +7 -0
  11. package/lib/adapter/foundryActionError.d.ts.map +1 -0
  12. package/lib/adapter/foundryActionError.js +61 -0
  13. package/lib/adapter/foundryActionError.js.map +1 -0
  14. package/lib/adapter/foundryActionValidation.d.ts +4 -3
  15. package/lib/adapter/foundryActionValidation.d.ts.map +1 -1
  16. package/lib/adapter/foundryActionValidation.js +71 -25
  17. package/lib/adapter/foundryActionValidation.js.map +1 -1
  18. package/lib/adapter/foundryCodec.d.ts +2 -5
  19. package/lib/adapter/foundryCodec.d.ts.map +1 -1
  20. package/lib/adapter/foundryCodec.js +19 -7
  21. package/lib/adapter/foundryCodec.js.map +1 -1
  22. package/lib/adapter/foundryObjectSearch.d.ts +13 -0
  23. package/lib/adapter/foundryObjectSearch.d.ts.map +1 -0
  24. package/lib/adapter/foundryObjectSearch.js +57 -0
  25. package/lib/adapter/foundryObjectSearch.js.map +1 -0
  26. package/lib/adapter/index.d.ts +3 -4
  27. package/lib/adapter/index.js +3 -4
  28. package/lib/adapter/likeFilter.d.ts +10 -0
  29. package/lib/adapter/likeFilter.d.ts.map +1 -0
  30. package/lib/adapter/likeFilter.js +87 -0
  31. package/lib/adapter/likeFilter.js.map +1 -0
  32. package/lib/adapter/makeFoundryOntologyBackend.d.ts +76 -0
  33. package/lib/adapter/makeFoundryOntologyBackend.d.ts.map +1 -0
  34. package/lib/adapter/makeFoundryOntologyBackend.js +505 -0
  35. package/lib/adapter/makeFoundryOntologyBackend.js.map +1 -0
  36. package/lib/adapter/subsetFilter.d.ts +14 -0
  37. package/lib/adapter/subsetFilter.d.ts.map +1 -0
  38. package/lib/adapter/subsetFilter.js +105 -0
  39. package/lib/adapter/subsetFilter.js.map +1 -0
  40. package/lib/adapter/uploads.d.ts +25 -0
  41. package/lib/adapter/uploads.d.ts.map +1 -0
  42. package/lib/adapter/uploads.js +78 -0
  43. package/lib/adapter/uploads.js.map +1 -0
  44. package/lib/backend.d.ts +80 -0
  45. package/lib/backend.d.ts.map +1 -0
  46. package/lib/backend.js +34 -0
  47. package/lib/backend.js.map +1 -0
  48. package/lib/config/index.d.ts +8 -12
  49. package/lib/config/index.d.ts.map +1 -1
  50. package/lib/config/index.js +49 -52
  51. package/lib/config/index.js.map +1 -1
  52. package/lib/connectionOptions.d.ts +9 -0
  53. package/lib/connectionOptions.d.ts.map +1 -0
  54. package/lib/connectionOptions.js +1 -0
  55. package/lib/context.d.ts +21 -0
  56. package/lib/context.d.ts.map +1 -0
  57. package/lib/context.js +16 -0
  58. package/lib/context.js.map +1 -0
  59. package/lib/index.d.ts +7 -7
  60. package/lib/index.js +6 -7
  61. package/lib/meta/backend.d.ts +10 -0
  62. package/lib/meta/backend.d.ts.map +1 -0
  63. package/lib/meta/backend.js +161 -0
  64. package/lib/meta/backend.js.map +1 -0
  65. package/lib/meta/convertMetaActionType.d.ts +3 -2
  66. package/lib/meta/convertMetaActionType.d.ts.map +1 -1
  67. package/lib/meta/convertMetaActionType.js +3 -3
  68. package/lib/meta/convertMetaActionType.js.map +1 -1
  69. package/lib/meta/convertMetaLinkType.d.ts +2 -2
  70. package/lib/meta/convertMetaLinkType.d.ts.map +1 -1
  71. package/lib/meta/convertMetaLinkType.js +13 -13
  72. package/lib/meta/convertMetaLinkType.js.map +1 -1
  73. package/lib/meta/convertMetaObjectType.d.ts +2 -2
  74. package/lib/meta/convertMetaObjectType.d.ts.map +1 -1
  75. package/lib/meta/convertMetaObjectType.js +5 -1
  76. package/lib/meta/convertMetaObjectType.js.map +1 -1
  77. package/lib/meta/convertMetaQueryFunctionType.d.ts +1 -1
  78. package/lib/meta/convertMetaQueryFunctionType.js.map +1 -1
  79. package/lib/meta/convertMetaTypeDef.d.ts +1 -1
  80. package/lib/meta/convertMetaTypeDef.d.ts.map +1 -1
  81. package/lib/meta/convertMetaTypeDef.js +7 -1
  82. package/lib/meta/convertMetaTypeDef.js.map +1 -1
  83. package/lib/meta/convertMetaValueType.d.ts +2 -2
  84. package/lib/meta/convertMetaValueType.d.ts.map +1 -1
  85. package/lib/meta/convertMetaValueType.js.map +1 -1
  86. package/lib/meta/convertOmsActionParameterMetadata.d.ts +1 -1
  87. package/lib/meta/convertOmsActionParameterMetadata.js +1 -1
  88. package/lib/meta/convertOmsActionParameterMetadata.js.map +1 -1
  89. package/lib/meta/index.d.ts +2 -4
  90. package/lib/meta/index.js +2 -4
  91. package/lib/meta/listObjectTypes.d.ts +6 -0
  92. package/lib/meta/listObjectTypes.d.ts.map +1 -0
  93. package/lib/meta/listObjectTypes.js +13 -0
  94. package/lib/meta/listObjectTypes.js.map +1 -0
  95. package/lib/meta/loadActions.d.ts +7 -0
  96. package/lib/meta/loadActions.d.ts.map +1 -0
  97. package/lib/meta/loadActions.js +20 -0
  98. package/lib/meta/loadActions.js.map +1 -0
  99. package/lib/meta/loadEntities.d.ts +9 -0
  100. package/lib/meta/loadEntities.d.ts.map +1 -0
  101. package/lib/meta/loadEntities.js +73 -0
  102. package/lib/meta/loadEntities.js.map +1 -0
  103. package/lib/meta/loadQueryFunctions.d.ts +11 -0
  104. package/lib/meta/loadQueryFunctions.d.ts.map +1 -0
  105. package/lib/meta/loadQueryFunctions.js +18 -0
  106. package/lib/meta/loadQueryFunctions.js.map +1 -0
  107. package/lib/meta/planMetaLookup.d.ts +12 -0
  108. package/lib/meta/planMetaLookup.d.ts.map +1 -0
  109. package/lib/meta/planMetaLookup.js +44 -0
  110. package/lib/meta/planMetaLookup.js.map +1 -0
  111. package/lib/platform.d.ts +78 -0
  112. package/lib/platform.d.ts.map +1 -0
  113. package/lib/platform.js +116 -0
  114. package/lib/platform.js.map +1 -0
  115. package/lib/platformCollections.d.ts +68 -0
  116. package/lib/platformCollections.d.ts.map +1 -0
  117. package/lib/platformCollections.js +7 -0
  118. package/lib/platformCollections.js.map +1 -0
  119. package/lib/serviceConnector.d.ts +8 -0
  120. package/lib/serviceConnector.d.ts.map +1 -0
  121. package/lib/serviceConnector.js +105 -0
  122. package/lib/serviceConnector.js.map +1 -0
  123. package/lib/stagedWrites.d.ts +3 -2
  124. package/lib/stagedWrites.d.ts.map +1 -1
  125. package/lib/stagedWrites.js +30 -3
  126. package/lib/stagedWrites.js.map +1 -1
  127. package/lib/users/admin.d.ts +105 -0
  128. package/lib/users/admin.d.ts.map +1 -0
  129. package/lib/users/admin.js +35 -0
  130. package/lib/users/admin.js.map +1 -0
  131. package/lib/users/createFoundryUsersIntegration.d.ts +2 -2
  132. package/lib/users/createFoundryUsersIntegration.d.ts.map +1 -1
  133. package/lib/users/createFoundryUsersIntegration.js +4 -6
  134. package/lib/users/createFoundryUsersIntegration.js.map +1 -1
  135. package/lib/users/foundryUser.d.ts +2 -2
  136. package/lib/users/foundryUser.js +1 -1
  137. package/lib/users/foundryUser.js.map +1 -1
  138. package/lib/users/index.d.ts +2 -3
  139. package/lib/users/index.js +2 -3
  140. package/lib/users/loadUserSubset.d.ts +8 -0
  141. package/lib/users/loadUserSubset.d.ts.map +1 -0
  142. package/lib/users/loadUserSubset.js +166 -0
  143. package/lib/users/loadUserSubset.js.map +1 -0
  144. package/lib/utils/AsyncIterable.d.ts +1 -1
  145. package/lib/utils/AsyncIterable.d.ts.map +1 -1
  146. package/lib/utils/AsyncIterable.js +11 -0
  147. package/lib/utils/AsyncIterable.js.map +1 -1
  148. package/package.json +16 -15
  149. package/lib/adapter/convertLoadSubsetOptions.d.ts +0 -8
  150. package/lib/adapter/convertLoadSubsetOptions.d.ts.map +0 -1
  151. package/lib/adapter/convertLoadSubsetOptions.js +0 -178
  152. package/lib/adapter/convertLoadSubsetOptions.js.map +0 -1
  153. package/lib/adapter/createFoundryOntologyBackendAdapter.d.ts +0 -29
  154. package/lib/adapter/createFoundryOntologyBackendAdapter.d.ts.map +0 -1
  155. package/lib/adapter/createFoundryOntologyBackendAdapter.js +0 -311
  156. package/lib/adapter/createFoundryOntologyBackendAdapter.js.map +0 -1
  157. package/lib/adapter/objectCollectionOptions.d.ts +0 -33
  158. package/lib/adapter/objectCollectionOptions.d.ts.map +0 -1
  159. package/lib/adapter/objectCollectionOptions.js +0 -482
  160. package/lib/adapter/objectCollectionOptions.js.map +0 -1
  161. package/lib/config/applyAttachmentConstraintOverrides.d.ts +0 -10
  162. package/lib/config/applyAttachmentConstraintOverrides.d.ts.map +0 -1
  163. package/lib/config/applyAttachmentConstraintOverrides.js +0 -50
  164. package/lib/config/applyAttachmentConstraintOverrides.js.map +0 -1
  165. package/lib/connection.d.ts +0 -38
  166. package/lib/connection.d.ts.map +0 -1
  167. package/lib/connection.js +0 -195
  168. package/lib/connection.js.map +0 -1
  169. package/lib/installation/createFoundryBackendInstallation.d.ts +0 -29
  170. package/lib/installation/createFoundryBackendInstallation.d.ts.map +0 -1
  171. package/lib/installation/createFoundryBackendInstallation.js +0 -60
  172. package/lib/installation/createFoundryBackendInstallation.js.map +0 -1
  173. package/lib/installation/index.d.ts +0 -2
  174. package/lib/installation/index.js +0 -1
  175. package/lib/meta/actionTypeCollectionOptions.d.ts +0 -14
  176. package/lib/meta/actionTypeCollectionOptions.d.ts.map +0 -1
  177. package/lib/meta/actionTypeCollectionOptions.js +0 -58
  178. package/lib/meta/actionTypeCollectionOptions.js.map +0 -1
  179. package/lib/meta/convertActionTypeLoadSubsetOptions.d.ts +0 -7
  180. package/lib/meta/convertActionTypeLoadSubsetOptions.d.ts.map +0 -1
  181. package/lib/meta/convertActionTypeLoadSubsetOptions.js +0 -84
  182. package/lib/meta/convertActionTypeLoadSubsetOptions.js.map +0 -1
  183. package/lib/meta/createFoundryMetaOntologyBackendAdapter.d.ts +0 -11
  184. package/lib/meta/createFoundryMetaOntologyBackendAdapter.d.ts.map +0 -1
  185. package/lib/meta/createFoundryMetaOntologyBackendAdapter.js +0 -43
  186. package/lib/meta/createFoundryMetaOntologyBackendAdapter.js.map +0 -1
  187. package/lib/meta/entityCollectionOptions.d.ts +0 -25
  188. package/lib/meta/entityCollectionOptions.d.ts.map +0 -1
  189. package/lib/meta/entityCollectionOptions.js +0 -69
  190. package/lib/meta/entityCollectionOptions.js.map +0 -1
  191. package/lib/meta/queryFunctionTypeCollectionOptions.d.ts +0 -12
  192. package/lib/meta/queryFunctionTypeCollectionOptions.d.ts.map +0 -1
  193. package/lib/meta/queryFunctionTypeCollectionOptions.js +0 -59
  194. package/lib/meta/queryFunctionTypeCollectionOptions.js.map +0 -1
  195. package/lib/users/createFoundryAdminOntologyRoute.d.ts +0 -55
  196. package/lib/users/createFoundryAdminOntologyRoute.d.ts.map +0 -1
  197. package/lib/users/createFoundryAdminOntologyRoute.js +0 -33
  198. package/lib/users/createFoundryAdminOntologyRoute.js.map +0 -1
  199. package/lib/users/userCollectionOptions.d.ts +0 -25
  200. package/lib/users/userCollectionOptions.d.ts.map +0 -1
  201. package/lib/users/userCollectionOptions.js +0 -94
  202. package/lib/users/userCollectionOptions.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"foundryActionValidation.d.ts","names":[],"sources":["../../src/adapter/foundryActionValidation.ts"],"mappings":";;;;;;iBAgBiB;EACb,WAAW;EACX;;wBAmBkB,8BAA8B;EAChD,QAAQ;EACR;EACA;IACA,QAAQ;wBAsSU,mCAAmC;EACrD,QAAQ;EACR,UAAU;EACV;EACA,YAAY;EACZ,kBAAkB;IAClB,QAAQ,UAAU,sBAAsB;wBAqE5B,2BAA2B,QAAQ,4BAA4B"}
1
+ {"version":3,"file":"foundryActionValidation.d.ts","names":[],"sources":["../../src/adapter/foundryActionValidation.ts"],"mappings":";;;;;;;iBAeiB;EACb,WAAW;EACX;;wBAmBkB,8BAA8B;EAChD,QAAQ;EACR;EACA;IACA,QAAQ;wBAsSU,mCAAmC;EACrD,QAAQ;EACR,UAAU;EACV;EACA,YAAY;EACZ,kBAAkB;IAClB,QAAQ,UAAU,sBAAsB;wBAkH5B,2BACZ,QAAQ,2BACR,aAAa,0BACd"}
@@ -1,8 +1,8 @@
1
- import { fromPagination, toArray } from "../utils/AsyncIterable.js";
2
1
  import { toFoundryActionTypeName } from "../utils/actionTypeName.js";
3
- import { ActionTypesV2 } from "@osdk/foundry.ontologies";
2
+ import { fromPagination, toArray } from "../utils/AsyncIterable.js";
4
3
  import { invariant } from "@bobbyfidz/panic";
5
- import { certain, uncertain } from "@party-stack/ontology";
4
+ import { ActionTypesV2 } from "@osdk/foundry.ontologies";
5
+ import { certain, uncertain } from "@party-stack/ontology-spec";
6
6
  import { bulkLoadOntologyEntities } from "@osdk/client.unstable";
7
7
  import { GroupMemberships, Users } from "@osdk/foundry.admin";
8
8
  //#region src/adapter/foundryActionValidation.ts
@@ -195,38 +195,84 @@ async function validateFoundryActionDraftCriteria(options) {
195
195
  value: errors
196
196
  }) : uncertain();
197
197
  }
198
- function collectRegexIssue(constraint, issues, path) {
199
- if (constraint.configuredFailureMessage) issues.push({
200
- message: constraint.configuredFailureMessage,
201
- path
198
+ function collectConstraintIssues(constraints, value, path, issues) {
199
+ const add = (code, message, category = "input", configured = false) => issues.push({
200
+ code,
201
+ message,
202
+ path,
203
+ category,
204
+ source: "parameter",
205
+ messageSource: configured ? "configured" : "standard"
202
206
  });
203
- }
204
- function collectStructIssues(constraint, issues, path) {
205
- for (const [fieldName, field] of Object.entries(constraint.structFields)) {
206
- if (field.result !== "INVALID") continue;
207
- for (const fieldConstraint of field.evaluatedConstraints) if (fieldConstraint.type === "stringRegexMatch") collectRegexIssue(fieldConstraint, issues, [...path, fieldName]);
208
- }
209
- }
210
- function collectParameterConstraintIssues(constraint, issues, path) {
211
- switch (constraint.type) {
207
+ for (const constraint of constraints) switch (constraint.type) {
208
+ case "struct":
209
+ for (const [key, field] of Object.entries(constraint.structFields)) {
210
+ if (field.result !== "INVALID") continue;
211
+ const item = value !== null && typeof value === "object" ? value[key] : void 0;
212
+ collectConstraintIssues(field.evaluatedConstraints, item, [...path, key], issues);
213
+ }
214
+ break;
215
+ case "array":
216
+ for (const [index, entry] of constraint.entries.entries()) collectConstraintIssues([entry], Array.isArray(value) ? value[index] : void 0, [...path, index], issues);
217
+ break;
218
+ case "objectQueryResult":
219
+ add("InvalidObjectReference", "Choose a valid value.", "reference");
220
+ break;
221
+ case "groupMember":
222
+ case "objectPropertyValue":
223
+ case "oneOf":
224
+ add("selection", "The selected value is not valid.", "custom");
225
+ break;
212
226
  case "stringRegexMatch":
213
- collectRegexIssue(constraint, issues, path);
227
+ add("format", constraint.configuredFailureMessage ?? "Enter a value in the required format.", "input", Boolean(constraint.configuredFailureMessage));
214
228
  break;
215
- case "struct":
216
- collectStructIssues(constraint, issues, path);
229
+ case "range":
230
+ case "stringLength":
231
+ case "arraySize": {
232
+ const size = constraint.type === "range" ? value : constraint.type === "stringLength" && typeof value === "string" ? value.length : constraint.type === "arraySize" && Array.isArray(value) ? value.length : void 0;
233
+ if (typeof size === "number" && (typeof constraint.lt === "number" && size >= constraint.lt || typeof constraint.lte === "number" && size > constraint.lte || typeof constraint.gt === "number" && size <= constraint.gt || typeof constraint.gte === "number" && size < constraint.gte)) add(constraint.type, constraint.type === "range" ? "Enter a value within the allowed range." : constraint.type === "stringLength" ? "Enter text of an allowed length." : "Choose an allowed number of items.");
217
234
  break;
218
- case "array": for (const [index, entry] of constraint.entries.entries()) collectStructIssues(entry, issues, [...path, index]);
235
+ }
219
236
  }
220
237
  }
221
- function getFoundryValidationIssues(result) {
238
+ function getFoundryValidationIssues(result, parameters) {
222
239
  const validation = result.validation;
223
240
  if (!validation || validation.result !== "INVALID") return [];
224
- const issues = validation.submissionCriteria.flatMap((criterion) => criterion.result === "INVALID" && criterion.configuredFailureMessage ? [{ message: criterion.configuredFailureMessage }] : []);
225
- for (const [parameterName, parameter] of Object.entries(validation.parameters)) {
241
+ const issues = validation.submissionCriteria.flatMap((criterion) => criterion.result === "INVALID" && criterion.configuredFailureMessage ? [{
242
+ message: criterion.configuredFailureMessage,
243
+ code: "custom",
244
+ category: "custom",
245
+ source: "submission",
246
+ messageSource: "configured"
247
+ }] : []);
248
+ for (const [name, parameter] of Object.entries(validation.parameters)) {
226
249
  if (parameter.result !== "INVALID") continue;
227
- for (const constraint of parameter.evaluatedConstraints) collectParameterConstraintIssues(constraint, issues, [parameterName]);
250
+ const before = issues.length;
251
+ if (parameter.required && parameters && parameters[name] === void 0 && parameter.defaultValue === void 0) issues.push({
252
+ message: "A value is required.",
253
+ path: [name],
254
+ code: "required",
255
+ category: "input",
256
+ source: "parameter",
257
+ messageSource: "standard"
258
+ });
259
+ else collectConstraintIssues(parameter.evaluatedConstraints, parameters?.[name], [name], issues);
260
+ if (issues.length === before) issues.push({
261
+ message: "Enter a valid value.",
262
+ path: [name],
263
+ code: "invalid",
264
+ category: "input",
265
+ source: "parameter",
266
+ messageSource: "standard"
267
+ });
228
268
  }
229
- return issues.length > 0 ? issues : [{ message: "Invalid Action arguments." }];
269
+ return issues.length ? issues : [{
270
+ message: "Submission failed validation.",
271
+ code: "custom",
272
+ category: "custom",
273
+ source: "submission",
274
+ messageSource: "standard"
275
+ }];
230
276
  }
231
277
  //#endregion
232
278
  export { getFoundryValidationIssues, loadFoundrySubmissionCriteria, validateFoundryActionDraftCriteria };
@@ -1 +1 @@
1
- {"version":3,"file":"foundryActionValidation.js","names":["AsyncIterable.toArray","AsyncIterable.fromPagination"],"sources":["../../src/adapter/foundryActionValidation.ts"],"sourcesContent":["import { invariant } from \"@bobbyfidz/panic\";\nimport { bulkLoadOntologyEntities, type Condition, type ConditionValue } from \"@osdk/client.unstable\";\nimport { GroupMemberships, Users } from \"@osdk/foundry.admin\";\nimport {\n ActionTypesV2,\n type ParameterEvaluatedConstraint,\n type StringRegexMatchConstraint,\n type StructEvaluatedConstraint,\n type SyncApplyActionResponseV2,\n} from \"@osdk/foundry.ontologies\";\nimport { certain, uncertain, type Uncertain, type ValidationIssue } from \"@party-stack/ontology\";\nimport { toFoundryActionTypeName } from \"../utils/actionTypeName.js\";\nimport * as AsyncIterable from \"../utils/AsyncIterable.js\";\nimport type { OntologyClient } from \"@party-stack/foundry-client\";\nimport type { Result } from \"@party-stack/ontology/values\";\n\nexport interface FoundrySubmissionCriterion {\n condition: Condition;\n failureMessage: string;\n}\n\nfunction valuesEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) && Array.isArray(right)) {\n return left.length === right.length && left.every((value, index) => valuesEqual(value, right[index]));\n }\n if (typeof left === \"object\" && left !== null && typeof right === \"object\" && right !== null) {\n const leftEntries = Object.entries(left);\n const rightRecord = right as Record<string, unknown>;\n return (\n leftEntries.length === Object.keys(rightRecord).length &&\n leftEntries.every(([key, value]) => valuesEqual(value, rightRecord[key]))\n );\n }\n return false;\n}\n\nexport async function loadFoundrySubmissionCriteria(options: {\n client: OntologyClient;\n actionTypeName: string;\n userId: string;\n}): Promise<FoundrySubmissionCriterion[]> {\n const actionType = await ActionTypesV2.get(\n options.client,\n options.client.ontologyRid,\n toFoundryActionTypeName(options.actionTypeName)\n );\n const response = await bulkLoadOntologyEntities(\n {\n ...options.client,\n servicePath: \"ontology-metadata/api\",\n },\n options.userId,\n {\n actionTypes: [{ rid: actionType.rid }],\n datasourceTypes: [],\n interfaceTypes: [],\n linkTypes: [],\n objectTypes: [],\n sharedPropertyTypes: [],\n typeGroups: [],\n }\n );\n const loaded = response.actionTypes[0];\n invariant(loaded, `Foundry action type \"${options.actionTypeName}\" was not returned by metadata.`);\n return Object.values(loaded.actionType.actionTypeLogic.validation.actionTypeLevelValidation.rules).map(\n (rule) => ({\n condition: rule.condition,\n failureMessage: rule.displayMetadata.failureMessage,\n })\n );\n}\n\ninterface EvaluationContext {\n client: OntologyClient;\n userId: string;\n parameters: Record<string, unknown>;\n knownParameters: ReadonlySet<string>;\n groupIds: () => Promise<string[]>;\n markings: () => Promise<string[]>;\n user: () => ReturnType<typeof Users.get>;\n}\n\nfunction createEvaluationContext(options: {\n client: OntologyClient;\n userId: string;\n parameters: Record<string, unknown>;\n knownParameters?: ReadonlySet<string>;\n}): EvaluationContext {\n let groupIds: Promise<string[]> | undefined;\n let markings: Promise<string[]> | undefined;\n let user: ReturnType<typeof Users.get> | undefined;\n\n return {\n ...options,\n knownParameters: options.knownParameters ?? new Set(Object.keys(options.parameters)),\n groupIds: () => {\n groupIds ??= loadGroupIds(options.client, options.userId);\n return groupIds;\n },\n markings: () => {\n markings ??= Users.getMarkings(options.client, options.userId).then((response) => response.view);\n return markings;\n },\n user: () => {\n user ??= Users.get(options.client, options.userId);\n return user;\n },\n };\n}\n\nasync function loadGroupIds(client: OntologyClient, userId: string): Promise<string[]> {\n return AsyncIterable.toArray(\n AsyncIterable.fromPagination(\n (pageSize, pageToken: string | undefined) =>\n GroupMemberships.list(client, userId, {\n pageSize,\n pageToken,\n transitive: true,\n }),\n (page) => page.nextPageToken,\n (page) => page.data.map((membership) => membership.groupId),\n 1_000\n )\n );\n}\n\nfunction evaluateStaticValue(value: ConditionValue & { type: \"staticValue\" }): Uncertain<unknown> {\n const staticValue = value.staticValue;\n switch (staticValue.type) {\n case \"boolean\":\n return certain(staticValue.boolean);\n case \"integer\":\n return certain(staticValue.integer);\n case \"long\":\n return certain(staticValue.long);\n case \"double\":\n return certain(staticValue.double);\n case \"string\":\n return certain(staticValue.string);\n case \"timestamp\":\n return certain(staticValue.timestamp);\n case \"booleanList\":\n return certain(staticValue.booleanList.booleans);\n case \"integerList\":\n return certain(staticValue.integerList.integers);\n case \"longList\":\n return certain(staticValue.longList.longs);\n case \"doubleList\":\n return certain(staticValue.doubleList.doubles);\n case \"stringList\":\n return certain(staticValue.stringList.strings);\n case \"timestampList\":\n return certain(staticValue.timestampList.timestamps);\n case \"decimal\":\n return certain(staticValue.decimal.decimalValue);\n case \"decimalList\":\n return certain(staticValue.decimalList.decimals);\n case \"date\":\n return certain(staticValue.date.dateValue);\n case \"dateList\":\n return certain(staticValue.dateList.dates);\n case \"marking\":\n return certain(staticValue.marking.marking);\n case \"markingList\":\n return certain(staticValue.markingList.markings);\n case \"attachment\":\n return certain(staticValue.attachment.attachment);\n case \"attachmentList\":\n return certain(staticValue.attachmentList.attachments);\n case \"objectType\":\n return certain(staticValue.objectType.objectTypeId);\n case \"null\":\n return certain(null);\n default:\n return uncertain();\n }\n}\n\nasync function evaluateUserProperty(\n value: ConditionValue & { type: \"userProperty\" },\n context: EvaluationContext\n): Promise<Uncertain<unknown>> {\n switch (value.userProperty.propertyValue.type) {\n case \"userId\":\n return certain(context.userId);\n case \"groupIds\":\n return certain(await context.groupIds());\n case \"organizationMarkingIds\":\n return certain(await context.markings());\n case \"userName\":\n return certain((await context.user()).username);\n case \"userAttributes\": {\n const user = await context.user();\n return certain(user.attributes[value.userProperty.propertyValue.userAttributes.attributeKey]);\n }\n case \"groupNames\":\n return uncertain();\n }\n}\n\nasync function evaluateConditionValue(\n value: ConditionValue,\n context: EvaluationContext\n): Promise<Uncertain<unknown>> {\n switch (value.type) {\n case \"staticValue\":\n return evaluateStaticValue(value);\n case \"userProperty\":\n return evaluateUserProperty(value, context);\n case \"parameterId\": {\n const parameterName = value.parameterId;\n const parameterValue = context.parameters[parameterName];\n return parameterValue !== undefined || context.knownParameters.has(parameterName)\n ? certain(parameterValue)\n : uncertain();\n }\n case \"parameterLength\": {\n const parameterName = value.parameterLength.parameterId;\n const parameterValue = context.parameters[parameterName];\n return typeof parameterValue === \"string\" || Array.isArray(parameterValue)\n ? certain(parameterValue.length)\n : uncertain();\n }\n case \"objectParameterPropertyValue\":\n case \"interfaceParameterPropertyValue\":\n case \"interfaceParameterPropertyValueV2\":\n return uncertain();\n }\n}\n\nfunction evaluateOrderedComparison(\n operator: \"LESS_THAN\" | \"LESS_THAN_EQUALS\" | \"GREATER_THAN\" | \"GREATER_THAN_EQUALS\",\n left: unknown,\n right: unknown\n): Uncertain<boolean> {\n if (\n !(\n (typeof left === \"number\" && typeof right === \"number\") ||\n (typeof left === \"string\" && typeof right === \"string\")\n )\n ) {\n return uncertain();\n }\n switch (operator) {\n case \"LESS_THAN\":\n return certain(left < right);\n case \"LESS_THAN_EQUALS\":\n return certain(left <= right);\n case \"GREATER_THAN\":\n return certain(left > right);\n case \"GREATER_THAN_EQUALS\":\n return certain(left >= right);\n }\n}\n\nasync function evaluateCondition(\n condition: Condition,\n context: EvaluationContext\n): Promise<Uncertain<boolean>> {\n switch (condition.type) {\n case \"true\":\n return certain(true);\n case \"redacted\":\n return uncertain();\n case \"and\": {\n const results = await Promise.all(\n condition.and.conditions.map((child) => evaluateCondition(child, context))\n );\n if (results.some((result) => result.certain && !result.value)) {\n return certain(false);\n }\n return results.some((result) => !result.certain) ? uncertain() : certain(true);\n }\n case \"or\": {\n const results = await Promise.all(\n condition.or.conditions.map((child) => evaluateCondition(child, context))\n );\n if (results.some((result) => result.certain && result.value)) {\n return certain(true);\n }\n return results.some((result) => !result.certain) ? uncertain() : certain(false);\n }\n case \"not\": {\n const result = await evaluateCondition(condition.not.condition, context);\n return result.certain ? certain(!result.value) : result;\n }\n case \"comparison\": {\n const [left, right] = await Promise.all([\n evaluateConditionValue(condition.comparison.left, context),\n evaluateConditionValue(condition.comparison.right, context),\n ]);\n if (!left.certain || !right.certain) {\n return uncertain();\n }\n switch (condition.comparison.operator) {\n case \"EQUALS\":\n return certain(valuesEqual(left.value, right.value));\n case \"NOT_EQUALS\":\n return certain(!valuesEqual(left.value, right.value));\n case \"INTERSECTS\": {\n const leftValues = Array.isArray(left.value) ? left.value : [left.value];\n const rightValues = new Set(Array.isArray(right.value) ? right.value : [right.value]);\n return certain(leftValues.some((entry) => rightValues.has(entry)));\n }\n case \"LESS_THAN\":\n case \"LESS_THAN_EQUALS\":\n case \"GREATER_THAN\":\n case \"GREATER_THAN_EQUALS\":\n return evaluateOrderedComparison(condition.comparison.operator, left.value, right.value);\n case \"IS_OF_OBJECT_TYPE\":\n return uncertain();\n default:\n return uncertain();\n }\n }\n case \"regex\": {\n const value = await evaluateConditionValue(condition.regex.value, context);\n if (!value.certain) return value;\n if (typeof value.value !== \"string\") {\n return uncertain();\n }\n try {\n return certain(new RegExp(condition.regex.regex).test(value.value));\n } catch {\n return uncertain();\n }\n }\n case \"markings\":\n return uncertain();\n case \"executionContext\":\n return uncertain();\n }\n}\n\nexport async function validateFoundryActionDraftCriteria(options: {\n client: OntologyClient;\n criteria: FoundrySubmissionCriterion[];\n userId: string;\n parameters: Record<string, unknown>;\n knownParameters?: ReadonlySet<string>;\n}): Promise<Uncertain<Result<void, readonly ValidationIssue[]>>> {\n const context = createEvaluationContext(options);\n const evaluated = await Promise.all(\n options.criteria.map(async (criterion) => ({\n criterion,\n result: await evaluateCondition(criterion.condition, context),\n }))\n );\n const errors = evaluated\n .filter(({ result }) => result.certain && !result.value)\n .map(({ criterion }) => ({\n message: `Impossible submission criterion: ${criterion.failureMessage}`,\n }));\n return errors.length > 0\n ? certain({\n kind: \"err\",\n value: errors,\n })\n : uncertain();\n}\n\nfunction collectRegexIssue(\n constraint: StringRegexMatchConstraint,\n issues: ValidationIssue[],\n path: readonly (string | number)[]\n): void {\n if (constraint.configuredFailureMessage) {\n issues.push({\n message: constraint.configuredFailureMessage,\n path,\n });\n }\n}\n\nfunction collectStructIssues(\n constraint: StructEvaluatedConstraint,\n issues: ValidationIssue[],\n path: readonly (string | number)[]\n): void {\n for (const [fieldName, field] of Object.entries(constraint.structFields)) {\n if (field.result !== \"INVALID\") continue;\n for (const fieldConstraint of field.evaluatedConstraints) {\n if (fieldConstraint.type === \"stringRegexMatch\") {\n collectRegexIssue(fieldConstraint, issues, [...path, fieldName]);\n }\n }\n }\n}\n\nfunction collectParameterConstraintIssues(\n constraint: ParameterEvaluatedConstraint,\n issues: ValidationIssue[],\n path: readonly (string | number)[]\n): void {\n switch (constraint.type) {\n case \"stringRegexMatch\":\n collectRegexIssue(constraint, issues, path);\n break;\n case \"struct\":\n collectStructIssues(constraint, issues, path);\n break;\n case \"array\":\n for (const [index, entry] of constraint.entries.entries()) {\n collectStructIssues(entry, issues, [...path, index]);\n }\n break;\n }\n}\n\nexport function getFoundryValidationIssues(result: SyncApplyActionResponseV2): ValidationIssue[] {\n const validation = result.validation;\n if (!validation || validation.result !== \"INVALID\") return [];\n\n const issues = validation.submissionCriteria.flatMap((criterion) =>\n criterion.result === \"INVALID\" && criterion.configuredFailureMessage\n ? [{ message: criterion.configuredFailureMessage }]\n : []\n );\n for (const [parameterName, parameter] of Object.entries(validation.parameters)) {\n if (parameter.result !== \"INVALID\") continue;\n for (const constraint of parameter.evaluatedConstraints) {\n collectParameterConstraintIssues(constraint, issues, [parameterName]);\n }\n }\n return issues.length > 0 ? issues : [{ message: \"Invalid Action arguments.\" }];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"foundryActionValidation.js","names":["AsyncIterable.toArray","AsyncIterable.fromPagination"],"sources":["../../src/adapter/foundryActionValidation.ts"],"sourcesContent":["import { invariant } from \"@bobbyfidz/panic\";\nimport { bulkLoadOntologyEntities, type Condition, type ConditionValue } from \"@osdk/client.unstable\";\nimport { GroupMemberships, Users } from \"@osdk/foundry.admin\";\nimport {\n ActionTypesV2,\n type ParameterEvaluatedConstraint,\n type SyncApplyActionResponseV2,\n} from \"@osdk/foundry.ontologies\";\nimport { certain, uncertain, type Uncertain } from \"@party-stack/ontology-spec\";\nimport { toFoundryActionTypeName } from \"../utils/actionTypeName.js\";\nimport * as AsyncIterable from \"../utils/AsyncIterable.js\";\nimport type { OntologyClient } from \"@party-stack/foundry-client\";\nimport type { ValidationIssue } from \"@party-stack/ontology-backend\";\nimport type { Result } from \"@party-stack/ontology-spec/values\";\n\nexport interface FoundrySubmissionCriterion {\n condition: Condition;\n failureMessage: string;\n}\n\nfunction valuesEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (Array.isArray(left) && Array.isArray(right)) {\n return left.length === right.length && left.every((value, index) => valuesEqual(value, right[index]));\n }\n if (typeof left === \"object\" && left !== null && typeof right === \"object\" && right !== null) {\n const leftEntries = Object.entries(left);\n const rightRecord = right as Record<string, unknown>;\n return (\n leftEntries.length === Object.keys(rightRecord).length &&\n leftEntries.every(([key, value]) => valuesEqual(value, rightRecord[key]))\n );\n }\n return false;\n}\n\nexport async function loadFoundrySubmissionCriteria(options: {\n client: OntologyClient;\n actionTypeName: string;\n userId: string;\n}): Promise<FoundrySubmissionCriterion[]> {\n const actionType = await ActionTypesV2.get(\n options.client,\n options.client.ontologyRid,\n toFoundryActionTypeName(options.actionTypeName)\n );\n const response = await bulkLoadOntologyEntities(\n {\n ...options.client,\n servicePath: \"ontology-metadata/api\",\n },\n options.userId,\n {\n actionTypes: [{ rid: actionType.rid }],\n datasourceTypes: [],\n interfaceTypes: [],\n linkTypes: [],\n objectTypes: [],\n sharedPropertyTypes: [],\n typeGroups: [],\n }\n );\n const loaded = response.actionTypes[0];\n invariant(loaded, `Foundry action type \"${options.actionTypeName}\" was not returned by metadata.`);\n return Object.values(loaded.actionType.actionTypeLogic.validation.actionTypeLevelValidation.rules).map(\n (rule) => ({\n condition: rule.condition,\n failureMessage: rule.displayMetadata.failureMessage,\n })\n );\n}\n\ninterface EvaluationContext {\n client: OntologyClient;\n userId: string;\n parameters: Record<string, unknown>;\n knownParameters: ReadonlySet<string>;\n groupIds: () => Promise<string[]>;\n markings: () => Promise<string[]>;\n user: () => ReturnType<typeof Users.get>;\n}\n\nfunction createEvaluationContext(options: {\n client: OntologyClient;\n userId: string;\n parameters: Record<string, unknown>;\n knownParameters?: ReadonlySet<string>;\n}): EvaluationContext {\n let groupIds: Promise<string[]> | undefined;\n let markings: Promise<string[]> | undefined;\n let user: ReturnType<typeof Users.get> | undefined;\n\n return {\n ...options,\n knownParameters: options.knownParameters ?? new Set(Object.keys(options.parameters)),\n groupIds: () => {\n groupIds ??= loadGroupIds(options.client, options.userId);\n return groupIds;\n },\n markings: () => {\n markings ??= Users.getMarkings(options.client, options.userId).then((response) => response.view);\n return markings;\n },\n user: () => {\n user ??= Users.get(options.client, options.userId);\n return user;\n },\n };\n}\n\nasync function loadGroupIds(client: OntologyClient, userId: string): Promise<string[]> {\n return AsyncIterable.toArray(\n AsyncIterable.fromPagination(\n (pageSize, pageToken: string | undefined) =>\n GroupMemberships.list(client, userId, {\n pageSize,\n pageToken,\n transitive: true,\n }),\n (page) => page.nextPageToken,\n (page) => page.data.map((membership) => membership.groupId),\n 1_000\n )\n );\n}\n\nfunction evaluateStaticValue(value: ConditionValue & { type: \"staticValue\" }): Uncertain<unknown> {\n const staticValue = value.staticValue;\n switch (staticValue.type) {\n case \"boolean\":\n return certain(staticValue.boolean);\n case \"integer\":\n return certain(staticValue.integer);\n case \"long\":\n return certain(staticValue.long);\n case \"double\":\n return certain(staticValue.double);\n case \"string\":\n return certain(staticValue.string);\n case \"timestamp\":\n return certain(staticValue.timestamp);\n case \"booleanList\":\n return certain(staticValue.booleanList.booleans);\n case \"integerList\":\n return certain(staticValue.integerList.integers);\n case \"longList\":\n return certain(staticValue.longList.longs);\n case \"doubleList\":\n return certain(staticValue.doubleList.doubles);\n case \"stringList\":\n return certain(staticValue.stringList.strings);\n case \"timestampList\":\n return certain(staticValue.timestampList.timestamps);\n case \"decimal\":\n return certain(staticValue.decimal.decimalValue);\n case \"decimalList\":\n return certain(staticValue.decimalList.decimals);\n case \"date\":\n return certain(staticValue.date.dateValue);\n case \"dateList\":\n return certain(staticValue.dateList.dates);\n case \"marking\":\n return certain(staticValue.marking.marking);\n case \"markingList\":\n return certain(staticValue.markingList.markings);\n case \"attachment\":\n return certain(staticValue.attachment.attachment);\n case \"attachmentList\":\n return certain(staticValue.attachmentList.attachments);\n case \"objectType\":\n return certain(staticValue.objectType.objectTypeId);\n case \"null\":\n return certain(null);\n default:\n return uncertain();\n }\n}\n\nasync function evaluateUserProperty(\n value: ConditionValue & { type: \"userProperty\" },\n context: EvaluationContext\n): Promise<Uncertain<unknown>> {\n switch (value.userProperty.propertyValue.type) {\n case \"userId\":\n return certain(context.userId);\n case \"groupIds\":\n return certain(await context.groupIds());\n case \"organizationMarkingIds\":\n return certain(await context.markings());\n case \"userName\":\n return certain((await context.user()).username);\n case \"userAttributes\": {\n const user = await context.user();\n return certain(user.attributes[value.userProperty.propertyValue.userAttributes.attributeKey]);\n }\n case \"groupNames\":\n return uncertain();\n }\n}\n\nasync function evaluateConditionValue(\n value: ConditionValue,\n context: EvaluationContext\n): Promise<Uncertain<unknown>> {\n switch (value.type) {\n case \"staticValue\":\n return evaluateStaticValue(value);\n case \"userProperty\":\n return evaluateUserProperty(value, context);\n case \"parameterId\": {\n const parameterName = value.parameterId;\n const parameterValue = context.parameters[parameterName];\n return parameterValue !== undefined || context.knownParameters.has(parameterName)\n ? certain(parameterValue)\n : uncertain();\n }\n case \"parameterLength\": {\n const parameterName = value.parameterLength.parameterId;\n const parameterValue = context.parameters[parameterName];\n return typeof parameterValue === \"string\" || Array.isArray(parameterValue)\n ? certain(parameterValue.length)\n : uncertain();\n }\n case \"objectParameterPropertyValue\":\n case \"interfaceParameterPropertyValue\":\n case \"interfaceParameterPropertyValueV2\":\n return uncertain();\n }\n}\n\nfunction evaluateOrderedComparison(\n operator: \"LESS_THAN\" | \"LESS_THAN_EQUALS\" | \"GREATER_THAN\" | \"GREATER_THAN_EQUALS\",\n left: unknown,\n right: unknown\n): Uncertain<boolean> {\n if (\n !(\n (typeof left === \"number\" && typeof right === \"number\") ||\n (typeof left === \"string\" && typeof right === \"string\")\n )\n ) {\n return uncertain();\n }\n switch (operator) {\n case \"LESS_THAN\":\n return certain(left < right);\n case \"LESS_THAN_EQUALS\":\n return certain(left <= right);\n case \"GREATER_THAN\":\n return certain(left > right);\n case \"GREATER_THAN_EQUALS\":\n return certain(left >= right);\n }\n}\n\nasync function evaluateCondition(\n condition: Condition,\n context: EvaluationContext\n): Promise<Uncertain<boolean>> {\n switch (condition.type) {\n case \"true\":\n return certain(true);\n case \"redacted\":\n return uncertain();\n case \"and\": {\n const results = await Promise.all(\n condition.and.conditions.map((child) => evaluateCondition(child, context))\n );\n if (results.some((result) => result.certain && !result.value)) {\n return certain(false);\n }\n return results.some((result) => !result.certain) ? uncertain() : certain(true);\n }\n case \"or\": {\n const results = await Promise.all(\n condition.or.conditions.map((child) => evaluateCondition(child, context))\n );\n if (results.some((result) => result.certain && result.value)) {\n return certain(true);\n }\n return results.some((result) => !result.certain) ? uncertain() : certain(false);\n }\n case \"not\": {\n const result = await evaluateCondition(condition.not.condition, context);\n return result.certain ? certain(!result.value) : result;\n }\n case \"comparison\": {\n const [left, right] = await Promise.all([\n evaluateConditionValue(condition.comparison.left, context),\n evaluateConditionValue(condition.comparison.right, context),\n ]);\n if (!left.certain || !right.certain) {\n return uncertain();\n }\n switch (condition.comparison.operator) {\n case \"EQUALS\":\n return certain(valuesEqual(left.value, right.value));\n case \"NOT_EQUALS\":\n return certain(!valuesEqual(left.value, right.value));\n case \"INTERSECTS\": {\n const leftValues = Array.isArray(left.value) ? left.value : [left.value];\n const rightValues = new Set(Array.isArray(right.value) ? right.value : [right.value]);\n return certain(leftValues.some((entry) => rightValues.has(entry)));\n }\n case \"LESS_THAN\":\n case \"LESS_THAN_EQUALS\":\n case \"GREATER_THAN\":\n case \"GREATER_THAN_EQUALS\":\n return evaluateOrderedComparison(condition.comparison.operator, left.value, right.value);\n case \"IS_OF_OBJECT_TYPE\":\n return uncertain();\n default:\n return uncertain();\n }\n }\n case \"regex\": {\n const value = await evaluateConditionValue(condition.regex.value, context);\n if (!value.certain) return value;\n if (typeof value.value !== \"string\") {\n return uncertain();\n }\n try {\n return certain(new RegExp(condition.regex.regex).test(value.value));\n } catch {\n return uncertain();\n }\n }\n case \"markings\":\n return uncertain();\n case \"executionContext\":\n return uncertain();\n }\n}\n\nexport async function validateFoundryActionDraftCriteria(options: {\n client: OntologyClient;\n criteria: FoundrySubmissionCriterion[];\n userId: string;\n parameters: Record<string, unknown>;\n knownParameters?: ReadonlySet<string>;\n}): Promise<Uncertain<Result<void, readonly ValidationIssue[]>>> {\n const context = createEvaluationContext(options);\n const evaluated = await Promise.all(\n options.criteria.map(async (criterion) => ({\n criterion,\n result: await evaluateCondition(criterion.condition, context),\n }))\n );\n const errors = evaluated\n .filter(({ result }) => result.certain && !result.value)\n .map(({ criterion }) => ({\n message: `Impossible submission criterion: ${criterion.failureMessage}`,\n }));\n return errors.length > 0\n ? certain({\n kind: \"err\",\n value: errors,\n })\n : uncertain();\n}\n\nfunction collectConstraintIssues(\n constraints: readonly ParameterEvaluatedConstraint[],\n value: unknown,\n path: readonly (string | number)[],\n issues: ValidationIssue[]\n): void {\n const add = (\n code: string,\n message: string,\n category: \"input\" | \"reference\" | \"custom\" = \"input\",\n configured = false\n ) =>\n issues.push({\n code,\n message,\n path,\n category,\n source: \"parameter\",\n messageSource: configured ? \"configured\" : \"standard\",\n });\n for (const constraint of constraints) {\n switch (constraint.type) {\n case \"struct\":\n for (const [key, field] of Object.entries(constraint.structFields)) {\n if (field.result !== \"INVALID\") continue;\n const item =\n value !== null && typeof value === \"object\"\n ? (value as Record<string, unknown>)[key]\n : undefined;\n collectConstraintIssues(field.evaluatedConstraints, item, [...path, key], issues);\n }\n break;\n case \"array\":\n for (const [index, entry] of constraint.entries.entries())\n collectConstraintIssues(\n [entry],\n Array.isArray(value) ? value[index] : undefined,\n [...path, index],\n issues\n );\n break;\n case \"objectQueryResult\":\n add(\"InvalidObjectReference\", \"Choose a valid value.\", \"reference\");\n break;\n case \"groupMember\":\n case \"objectPropertyValue\":\n case \"oneOf\":\n add(\"selection\", \"The selected value is not valid.\", \"custom\");\n break;\n case \"stringRegexMatch\":\n add(\n \"format\",\n constraint.configuredFailureMessage ?? \"Enter a value in the required format.\",\n \"input\",\n Boolean(constraint.configuredFailureMessage)\n );\n break;\n case \"range\":\n case \"stringLength\":\n case \"arraySize\": {\n const size =\n constraint.type === \"range\"\n ? value\n : constraint.type === \"stringLength\" && typeof value === \"string\"\n ? value.length\n : constraint.type === \"arraySize\" && Array.isArray(value)\n ? value.length\n : undefined;\n // These are applicable constraints, not individual failed results. Only report\n // a particular bound when the submitted value proves it was violated.\n const failed =\n typeof size === \"number\" &&\n ((typeof constraint.lt === \"number\" && size >= constraint.lt) ||\n (typeof constraint.lte === \"number\" && size > constraint.lte) ||\n (typeof constraint.gt === \"number\" && size <= constraint.gt) ||\n (typeof constraint.gte === \"number\" && size < constraint.gte));\n if (failed)\n add(\n constraint.type,\n constraint.type === \"range\"\n ? \"Enter a value within the allowed range.\"\n : constraint.type === \"stringLength\"\n ? \"Enter text of an allowed length.\"\n : \"Choose an allowed number of items.\"\n );\n break;\n }\n case \"unevaluable\":\n break;\n }\n }\n}\n\nexport function getFoundryValidationIssues(\n result: SyncApplyActionResponseV2,\n parameters?: Record<string, unknown>\n): ValidationIssue[] {\n const validation = result.validation;\n if (!validation || validation.result !== \"INVALID\") return [];\n const issues: ValidationIssue[] = validation.submissionCriteria.flatMap((criterion) =>\n criterion.result === \"INVALID\" && criterion.configuredFailureMessage\n ? [\n {\n message: criterion.configuredFailureMessage,\n code: \"custom\",\n category: \"custom\" as const,\n source: \"submission\" as const,\n messageSource: \"configured\" as const,\n },\n ]\n : []\n );\n for (const [name, parameter] of Object.entries(validation.parameters)) {\n if (parameter.result !== \"INVALID\") continue;\n const before = issues.length;\n if (\n parameter.required &&\n parameters &&\n parameters[name] === undefined &&\n parameter.defaultValue === undefined\n )\n issues.push({\n message: \"A value is required.\",\n path: [name],\n code: \"required\",\n category: \"input\",\n source: \"parameter\",\n messageSource: \"standard\",\n });\n else collectConstraintIssues(parameter.evaluatedConstraints, parameters?.[name], [name], issues);\n if (issues.length === before)\n issues.push({\n message: \"Enter a valid value.\",\n path: [name],\n code: \"invalid\",\n category: \"input\",\n source: \"parameter\",\n messageSource: \"standard\",\n });\n }\n return issues.length\n ? issues\n : [\n {\n message: \"Submission failed validation.\",\n code: \"custom\",\n category: \"custom\",\n source: \"submission\",\n messageSource: \"standard\",\n },\n ];\n}\n"],"mappings":"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"}
@@ -1,12 +1,8 @@
1
1
  import { OntologyObjectV2 } from "@osdk/foundry.ontologies";
2
- import { OntologyIR, TypeDef } from "@party-stack/ontology";
2
+ import { OntologyIR, TypeDef } from "@party-stack/ontology-spec";
3
3
  import { MediaReference } from "@osdk/foundry.core";
4
4
  //#region src/adapter/foundryCodec.d.ts
5
5
  type FoundryObjectRecord = Record<string, unknown>;
6
- /** @deprecated Use {@link FoundryCodec} instead. */
7
- export type FoundryObjectDecoder = FoundryCodec;
8
- /** @deprecated Use {@link createFoundryCodec} instead. */
9
- export declare const createFoundryObjectDecoder: typeof createFoundryCodec;
10
6
  export interface FoundryCodec {
11
7
  decodeObject: (objectType: string, object: OntologyObjectV2 | FoundryObjectRecord) => FoundryObjectRecord;
12
8
  decodeEditObject: (objectType: string, object: FoundryObjectRecord) => FoundryObjectRecord;
@@ -15,6 +11,7 @@ export interface FoundryCodec {
15
11
  }
16
12
  export declare function createFoundryCodec(ir: OntologyIR, options?: {
17
13
  resolveMediaReference?: (id: string) => MediaReference | undefined;
14
+ resolveAttachmentId?: (id: string) => string | undefined;
18
15
  }): FoundryCodec;
19
16
  //#endregion
20
17
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"foundryCodec.d.ts","names":[],"sources":["../../src/adapter/foundryCodec.ts"],"mappings":";;;;KAWK,sBAAsB;;YAEf,uBAAuB;;qBAGtB,mCAA0B;iBAEtB;EACb,eAAe,oBAAoB,QAAQ,mBAAmB,wBAAwB;EACtF,mBAAmB,oBAAoB,QAAQ,wBAAwB;EACvE,cAAc,MAAM,SAAS;EAC7B,cAAc,MAAM,SAAS;;wBAGjB,mBACZ,IAAI,YACJ;EACI,yBAAyB,eAAe;IAE7C"}
1
+ {"version":3,"file":"foundryCodec.d.ts","names":[],"sources":["../../src/adapter/foundryCodec.ts"],"mappings":";;;;KAcK,sBAAsB;iBACV;EACb,eAAe,oBAAoB,QAAQ,mBAAmB,wBAAwB;EACtF,mBAAmB,oBAAoB,QAAQ,wBAAwB;EACvE,cAAc,MAAM,SAAS;EAC7B,cAAc,MAAM,SAAS;;wBAGjB,mBACZ,IAAI,YACJ;EACI,yBAAyB,eAAe;EACxC,uBAAuB;IAE5B"}
@@ -1,9 +1,9 @@
1
1
  import { getFoundryAttachmentKind } from "../meta/foundryAttachmentMetadata.js";
2
+ import { decodeFoundryCiphertext, encodeFoundryCiphertext } from "./encrypted.js";
2
3
  import { decodeFoundryMediaId, foundryMediaIdToReference, mediaReferenceToFoundryMediaId } from "./foundryMediaId.js";
4
+ import { Schema } from "effect";
3
5
  import { Temporal } from "temporal-polyfill";
4
6
  //#region src/adapter/foundryCodec.ts
5
- /** @deprecated Use {@link createFoundryCodec} instead. */
6
- const createFoundryObjectDecoder = createFoundryCodec;
7
7
  function createFoundryCodec(ir, options) {
8
8
  const objectTypes = new Map(ir.objectTypes.map((objectType) => [objectType.name, objectType]));
9
9
  const namedTypes = new Map(ir.types.map((type) => [type.name, type.type]));
@@ -30,6 +30,7 @@ function createFoundryCodec(ir, options) {
30
30
  if (value === void 0 || value === null) return value;
31
31
  if (context.editHistory) value = unwrapEditHistoryValue(resolvedType, value);
32
32
  switch (resolvedType.kind) {
33
+ case "encrypted": return decodeFoundryCiphertext(value, context.source);
33
34
  case "string": return value;
34
35
  case "boolean": return typeof value === "string" ? value === "true" : value;
35
36
  case "integer":
@@ -59,11 +60,21 @@ function createFoundryCodec(ir, options) {
59
60
  }
60
61
  };
61
62
  const decodeObjectType = (objectType, object, editHistory = false) => {
63
+ const keyProperty = objectType.properties.find((property) => property.name === objectType.primaryKey);
64
+ const primaryKey = keyProperty ? decodeValue(keyProperty.type, object[objectType.primaryKey], {
65
+ editHistory,
66
+ optional: false
67
+ }) : void 0;
62
68
  return Object.fromEntries(Object.entries(object).map(([key, value]) => {
63
69
  const property = objectType.properties.find((candidate) => candidate.name === key);
64
70
  return [key, property ? decodeValue(property.type, value, {
65
71
  editHistory,
66
- optional: false
72
+ optional: false,
73
+ source: Schema.is(Schema.Union([Schema.String, Schema.Finite]))(primaryKey) ? {
74
+ objectType: objectType.name,
75
+ primaryKey,
76
+ property: key
77
+ } : void 0
67
78
  }) : value];
68
79
  }));
69
80
  };
@@ -72,6 +83,7 @@ function createFoundryCodec(ir, options) {
72
83
  if (value === null) return null;
73
84
  const resolvedType = resolveType(type);
74
85
  switch (resolvedType.kind) {
86
+ case "encrypted": return encodeFoundryCiphertext(value);
75
87
  case "string":
76
88
  case "boolean":
77
89
  case "integer":
@@ -83,7 +95,7 @@ function createFoundryCodec(ir, options) {
83
95
  if (value instanceof Temporal.PlainDateTime) return value.toString();
84
96
  return value;
85
97
  case "geopoint": return encodeGeoPoint(value);
86
- case "attachment": return encodeAttachment(value, resolvedType.value.meta, options?.resolveMediaReference);
98
+ case "attachment": return encodeAttachment(value, resolvedType.value.meta, options?.resolveMediaReference, options?.resolveAttachmentId);
87
99
  case "objectReference":
88
100
  case "unknown": return value;
89
101
  case "list": return Array.isArray(value) ? value.map((item) => encodeValue(resolvedType.value.elementType, item)) : value;
@@ -182,10 +194,10 @@ function decodeMediaReference(value) {
182
194
  type: mediaReference.mimeType
183
195
  };
184
196
  }
185
- function encodeAttachment(value, meta, resolveMediaReference) {
197
+ function encodeAttachment(value, meta, resolveMediaReference, resolveAttachmentId) {
186
198
  if (!isPlainObject(value)) return value;
187
199
  if (typeof value.id !== "string") throw new Error("Invalid Foundry attachment value: expected an attachment with a string id.");
188
- if (getFoundryAttachmentKind(meta) !== "media") return value.id;
200
+ if (getFoundryAttachmentKind(meta) !== "media") return resolveAttachmentId?.(value.id) ?? value.id;
189
201
  const resolved = resolveMediaReference?.(value.id);
190
202
  if (resolved) return resolved;
191
203
  const id = decodeFoundryMediaId(value.id);
@@ -197,6 +209,6 @@ function isPlainObject(value) {
197
209
  return typeof value === "object" && value !== null && !Array.isArray(value);
198
210
  }
199
211
  //#endregion
200
- export { createFoundryCodec, createFoundryObjectDecoder };
212
+ export { createFoundryCodec };
201
213
 
202
214
  //# sourceMappingURL=foundryCodec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"foundryCodec.js","names":[],"sources":["../../src/adapter/foundryCodec.ts"],"sourcesContent":["import { Temporal } from \"temporal-polyfill\";\nimport { getFoundryAttachmentKind } from \"../meta/foundryAttachmentMetadata.js\";\nimport {\n decodeFoundryMediaId,\n foundryMediaIdToReference,\n mediaReferenceToFoundryMediaId,\n} from \"./foundryMediaId.js\";\nimport type { MediaReference } from \"@osdk/foundry.core\";\nimport type { AttachmentProperty, OntologyObjectV2 } from \"@osdk/foundry.ontologies\";\nimport type { ObjectTypeDef, OntologyIR, TypeDef } from \"@party-stack/ontology\";\n\ntype FoundryObjectRecord = Record<string, unknown>;\n/** @deprecated Use {@link FoundryCodec} instead. */\nexport type FoundryObjectDecoder = FoundryCodec;\n\n/** @deprecated Use {@link createFoundryCodec} instead. */\nexport const createFoundryObjectDecoder = createFoundryCodec;\n\nexport interface FoundryCodec {\n decodeObject: (objectType: string, object: OntologyObjectV2 | FoundryObjectRecord) => FoundryObjectRecord;\n decodeEditObject: (objectType: string, object: FoundryObjectRecord) => FoundryObjectRecord;\n decodeValue: (type: TypeDef, value: unknown) => unknown;\n encodeValue: (type: TypeDef, value: unknown) => unknown;\n}\n\nexport function createFoundryCodec(\n ir: OntologyIR,\n options?: {\n resolveMediaReference?: (id: string) => MediaReference | undefined;\n }\n): FoundryCodec {\n const objectTypes = new Map(ir.objectTypes.map((objectType) => [objectType.name, objectType]));\n const namedTypes = new Map(ir.types.map((type) => [type.name, type.type]));\n\n const resolveType = (type: TypeDef, seen = new Set<string>()): TypeDef => {\n if (type.kind !== \"ref\") {\n return type;\n }\n\n const name = type.value.name;\n if (seen.has(name)) {\n throw new Error(`Circular ontology type reference \"${name}\".`);\n }\n\n const resolved = namedTypes.get(name);\n if (!resolved) {\n throw new Error(`Unknown ontology type reference \"${name}\".`);\n }\n\n return resolveType(resolved, new Set([...seen, name]));\n };\n\n const decodeValue = (\n type: TypeDef,\n value: unknown,\n context: { editHistory: boolean; optional: boolean } = {\n editHistory: false,\n optional: false,\n }\n ): unknown => {\n const resolvedType = resolveType(type);\n\n if (resolvedType.kind === \"optional\") {\n if (\n value === undefined ||\n value === null ||\n (context.editHistory && isNullEditHistoryValue(value))\n ) {\n return undefined;\n }\n return decodeValue(resolvedType.value.type, value, {\n ...context,\n optional: true,\n });\n }\n\n if (value === undefined || value === null) {\n return value;\n }\n if (context.editHistory) {\n value = unwrapEditHistoryValue(resolvedType, value);\n }\n\n switch (resolvedType.kind) {\n case \"string\":\n return value;\n case \"boolean\":\n return typeof value === \"string\" ? value === \"true\" : value;\n case \"integer\":\n case \"float\":\n case \"double\":\n return typeof value === \"string\" ? Number(value) : value;\n case \"date\":\n return typeof value === \"string\" ? Temporal.PlainDate.from(value) : value;\n case \"timestamp\":\n if (typeof value === \"string\") return Temporal.Instant.from(value);\n if (typeof value === \"number\") return Temporal.Instant.fromEpochMilliseconds(value);\n return value;\n case \"geopoint\":\n return decodeGeoPoint(value);\n case \"attachment\":\n return decodeAttachment(value, resolvedType.value.meta, context.optional);\n case \"objectReference\":\n return value;\n case \"list\":\n return Array.isArray(value)\n ? value.map((item) => decodeValue(resolvedType.value.elementType, item, context))\n : value;\n case \"map\":\n if (!isPlainObject(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => [\n decodeValue(resolvedType.value.keyType, key, context),\n decodeValue(resolvedType.value.valueType, entryValue, context),\n ])\n );\n case \"struct\":\n if (!isPlainObject(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => {\n const field = resolvedType.value.fields.find((candidate) => candidate.name === key);\n return [key, field ? decodeValue(field.type, entryValue, context) : entryValue];\n })\n );\n case \"union\":\n case \"result\":\n return value;\n case \"ref\":\n return decodeValue(resolveType(resolvedType), value);\n }\n };\n\n const decodeObjectType = (\n objectType: ObjectTypeDef,\n object: FoundryObjectRecord,\n editHistory = false\n ): FoundryObjectRecord => {\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => {\n const property = objectType.properties.find((candidate) => candidate.name === key);\n return [\n key,\n property\n ? decodeValue(property.type, value, {\n editHistory,\n optional: false,\n })\n : value,\n ];\n })\n );\n };\n\n const encodeValue = (type: TypeDef, value: unknown): unknown => {\n if (value === undefined) return undefined;\n if (value === null) return null;\n\n const resolvedType = resolveType(type);\n\n switch (resolvedType.kind) {\n case \"string\":\n case \"boolean\":\n case \"integer\":\n case \"float\":\n case \"double\":\n return value;\n case \"date\":\n return value instanceof Temporal.PlainDate ? value.toString() : value;\n case \"timestamp\":\n if (value instanceof Temporal.Instant) return value.toString();\n if (value instanceof Temporal.PlainDateTime) return value.toString();\n return value;\n case \"geopoint\":\n return encodeGeoPoint(value);\n case \"attachment\":\n return encodeAttachment(value, resolvedType.value.meta, options?.resolveMediaReference);\n case \"objectReference\":\n case \"unknown\":\n return value;\n case \"list\":\n return Array.isArray(value)\n ? value.map((item) => encodeValue(resolvedType.value.elementType, item))\n : value;\n case \"map\":\n if (!isPlainObject(value)) return value;\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => [\n key,\n encodeValue(resolvedType.value.valueType, entryValue),\n ])\n );\n case \"struct\":\n if (!isPlainObject(value)) return value;\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => {\n const field = resolvedType.value.fields.find((f) => f.name === key);\n return [key, field ? encodeValue(field.type, entryValue) : entryValue];\n })\n );\n case \"optional\":\n return encodeValue(resolvedType.value.type, value);\n case \"union\":\n case \"result\":\n return value;\n case \"ref\":\n return encodeValue(resolveType(resolvedType), value);\n }\n };\n\n return {\n decodeObject: (objectTypeName, object) => {\n const objectType = objectTypes.get(objectTypeName);\n if (!objectType) {\n return object;\n }\n\n return decodeObjectType(objectType, object);\n },\n decodeEditObject: (objectTypeName, object) => {\n const objectType = objectTypes.get(objectTypeName);\n if (!objectType) {\n return object;\n }\n\n return decodeObjectType(objectType, object, true);\n },\n decodeValue,\n encodeValue,\n };\n}\n\nfunction encodeGeoPoint(value: unknown): unknown {\n if (isPlainObject(value) && typeof value.lat === \"number\" && typeof value.lon === \"number\") {\n return { type: \"Point\", coordinates: [value.lon, value.lat] };\n }\n return value;\n}\n\nfunction decodeGeoPoint(value: unknown): unknown {\n if (isPlainObject(value) && value.type === \"Point\" && Array.isArray(value.coordinates)) {\n const coordinates = value.coordinates as unknown[];\n const lon = coordinates[0];\n const lat = coordinates[1];\n if (typeof lat === \"number\" && typeof lon === \"number\") {\n return { lat, lon };\n }\n }\n\n if (isPlainObject(value) && typeof value.lat === \"number\" && typeof value.lon === \"number\") {\n return value;\n }\n\n return value;\n}\n\nfunction isNullEditHistoryValue(value: unknown): boolean {\n return value === \"NullPropertyValue{}\";\n}\n\nfunction unwrapEditHistoryValue(type: TypeDef, value: unknown): unknown {\n if (\n isPlainObject(value) &&\n typeof value.type === \"string\" &&\n \"value\" in value &&\n [\n \"stringValue\",\n \"integerValue\",\n \"doubleValue\",\n \"longValue\",\n \"booleanValue\",\n \"dateValue\",\n \"timestampValue\",\n ].includes(value.type)\n ) {\n return value.value;\n }\n if (type.kind === \"geopoint\" && typeof value === \"string\") {\n const match = /^GeoPointPropertyValue\\{latitude:\\s*(-?[\\d.]+),\\s*longitude:\\s*(-?[\\d.]+)\\}$/.exec(\n value\n );\n if (match) {\n return {\n lat: Number(match[1]),\n lon: Number(match[2]),\n };\n }\n }\n if (\n type.kind === \"attachment\" &&\n getFoundryAttachmentKind(type.value.meta) !== \"media\" &&\n isPlainObject(value) &&\n value.type === \"attachment\" &&\n typeof value.attachment === \"string\"\n ) {\n return { rid: value.attachment };\n }\n if (\n type.kind === \"attachment\" &&\n getFoundryAttachmentKind(type.value.meta) === \"media\" &&\n isPlainObject(value) &&\n value.type === \"mediaReference\" &&\n isPlainObject(value.mediaReference)\n ) {\n return value.mediaReference;\n }\n return value;\n}\n\nfunction decodeAttachment(\n value: unknown,\n meta: Record<string, unknown> | undefined,\n optional: boolean\n): unknown {\n const kind = getFoundryAttachmentKind(meta);\n const decoded = kind === \"media\" ? decodeMediaReference(value) : decodeFoundryAttachment(value);\n if (decoded !== undefined || optional) {\n return decoded;\n }\n throw new Error(`Invalid required Foundry ${kind} value.`);\n}\n\nfunction decodeFoundryAttachment(value: unknown): unknown {\n const attachment = value as Partial<AttachmentProperty>;\n if (typeof attachment?.rid !== \"string\") {\n return undefined;\n }\n return { id: attachment.rid };\n}\n\nfunction decodeMediaReference(value: unknown): unknown {\n if (\n !isPlainObject(value) ||\n typeof value.mimeType !== \"string\" ||\n !isPlainObject(value.reference) ||\n value.reference.type !== \"mediaSetViewItem\" ||\n !isPlainObject(value.reference.mediaSetViewItem)\n ) {\n return undefined;\n }\n const mediaReference = value as unknown as MediaReference;\n const id = mediaReferenceToFoundryMediaId(mediaReference);\n if (!decodeFoundryMediaId(id)) {\n return undefined;\n }\n return {\n id,\n type: mediaReference.mimeType,\n };\n}\n\nfunction encodeAttachment(\n value: unknown,\n meta?: Record<string, unknown>,\n resolveMediaReference?: (id: string) => MediaReference | undefined\n): unknown {\n if (!isPlainObject(value)) {\n return value;\n }\n if (typeof value.id !== \"string\") {\n throw new Error(\"Invalid Foundry attachment value: expected an attachment with a string id.\");\n }\n if (getFoundryAttachmentKind(meta) !== \"media\") {\n return value.id;\n }\n const resolved = resolveMediaReference?.(value.id);\n if (resolved) return resolved;\n const id = decodeFoundryMediaId(value.id);\n if (!id) {\n throw new Error(`Invalid Foundry media attachment id \"${value.id}\".`);\n }\n if (typeof value.type !== \"string\") {\n throw new Error(`Foundry media attachment \"${value.id}\" is missing its MIME type.`);\n }\n return foundryMediaIdToReference(id, value.type);\n}\n\nfunction isPlainObject(value: unknown): value is FoundryObjectRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;;;;AAgBA,MAAa,6BAA6B;AAS1C,SAAgB,mBACZ,IACA,SAGY;CACZ,MAAM,cAAc,IAAI,IAAI,GAAG,YAAY,KAAK,eAAe,CAAC,WAAW,MAAM,UAAU,CAAC,CAAC;CAC7F,MAAM,aAAa,IAAI,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC;CAEzE,MAAM,eAAe,MAAe,uBAAO,IAAI,IAAY,MAAe;EACtE,IAAI,KAAK,SAAS,OACd,OAAO;EAGX,MAAM,OAAO,KAAK,MAAM;EACxB,IAAI,KAAK,IAAI,IAAI,GACb,MAAM,IAAI,MAAM,qCAAqC,KAAK,GAAG;EAGjE,MAAM,WAAW,WAAW,IAAI,IAAI;EACpC,IAAI,CAAC,UACD,MAAM,IAAI,MAAM,oCAAoC,KAAK,GAAG;EAGhE,OAAO,YAAY,0BAAU,IAAI,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;CACzD;CAEA,MAAM,eACF,MACA,OACA,UAAuD;EACnD,aAAa;EACb,UAAU;CACd,MACU;EACV,MAAM,eAAe,YAAY,IAAI;EAErC,IAAI,aAAa,SAAS,YAAY;GAClC,IACI,UAAU,KAAA,KACV,UAAU,QACT,QAAQ,eAAe,uBAAuB,KAAK,GAEpD;GAEJ,OAAO,YAAY,aAAa,MAAM,MAAM,OAAO;IAC/C,GAAG;IACH,UAAU;GACd,CAAC;EACL;EAEA,IAAI,UAAU,KAAA,KAAa,UAAU,MACjC,OAAO;EAEX,IAAI,QAAQ,aACR,QAAQ,uBAAuB,cAAc,KAAK;EAGtD,QAAQ,aAAa,MAArB;GACI,KAAK,UACD,OAAO;GACX,KAAK,WACD,OAAO,OAAO,UAAU,WAAW,UAAU,SAAS;GAC1D,KAAK;GACL,KAAK;GACL,KAAK,UACD,OAAO,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI;GACvD,KAAK,QACD,OAAO,OAAO,UAAU,WAAW,SAAS,UAAU,KAAK,KAAK,IAAI;GACxE,KAAK;IACD,IAAI,OAAO,UAAU,UAAU,OAAO,SAAS,QAAQ,KAAK,KAAK;IACjE,IAAI,OAAO,UAAU,UAAU,OAAO,SAAS,QAAQ,sBAAsB,KAAK;IAClF,OAAO;GACX,KAAK,YACD,OAAO,eAAe,KAAK;GAC/B,KAAK,cACD,OAAO,iBAAiB,OAAO,aAAa,MAAM,MAAM,QAAQ,QAAQ;GAC5E,KAAK,mBACD,OAAO;GACX,KAAK,QACD,OAAO,MAAM,QAAQ,KAAK,IACpB,MAAM,KAAK,SAAS,YAAY,aAAa,MAAM,aAAa,MAAM,OAAO,CAAC,IAC9E;GACV,KAAK;IACD,IAAI,CAAC,cAAc,KAAK,GACpB,OAAO;IAEX,OAAO,OAAO,YACV,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,gBAAgB,CAC7C,YAAY,aAAa,MAAM,SAAS,KAAK,OAAO,GACpD,YAAY,aAAa,MAAM,WAAW,YAAY,OAAO,CACjE,CAAC,CACL;GACJ,KAAK;IACD,IAAI,CAAC,cAAc,KAAK,GACpB,OAAO;IAEX,OAAO,OAAO,YACV,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,gBAAgB;KAC7C,MAAM,QAAQ,aAAa,MAAM,OAAO,MAAM,cAAc,UAAU,SAAS,GAAG;KAClF,OAAO,CAAC,KAAK,QAAQ,YAAY,MAAM,MAAM,YAAY,OAAO,IAAI,UAAU;IAClF,CAAC,CACL;GACJ,KAAK;GACL,KAAK,UACD,OAAO;GACX,KAAK,OACD,OAAO,YAAY,YAAY,YAAY,GAAG,KAAK;EAC3D;CACJ;CAEA,MAAM,oBACF,YACA,QACA,cAAc,UACQ;EACtB,OAAO,OAAO,YACV,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;GACzC,MAAM,WAAW,WAAW,WAAW,MAAM,cAAc,UAAU,SAAS,GAAG;GACjF,OAAO,CACH,KACA,WACM,YAAY,SAAS,MAAM,OAAO;IAC9B;IACA,UAAU;GACd,CAAC,IACD,KACV;EACJ,CAAC,CACL;CACJ;CAEA,MAAM,eAAe,MAAe,UAA4B;EAC5D,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAChC,IAAI,UAAU,MAAM,OAAO;EAE3B,MAAM,eAAe,YAAY,IAAI;EAErC,QAAQ,aAAa,MAArB;GACI,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,UACD,OAAO;GACX,KAAK,QACD,OAAO,iBAAiB,SAAS,YAAY,MAAM,SAAS,IAAI;GACpE,KAAK;IACD,IAAI,iBAAiB,SAAS,SAAS,OAAO,MAAM,SAAS;IAC7D,IAAI,iBAAiB,SAAS,eAAe,OAAO,MAAM,SAAS;IACnE,OAAO;GACX,KAAK,YACD,OAAO,eAAe,KAAK;GAC/B,KAAK,cACD,OAAO,iBAAiB,OAAO,aAAa,MAAM,MAAM,SAAS,qBAAqB;GAC1F,KAAK;GACL,KAAK,WACD,OAAO;GACX,KAAK,QACD,OAAO,MAAM,QAAQ,KAAK,IACpB,MAAM,KAAK,SAAS,YAAY,aAAa,MAAM,aAAa,IAAI,CAAC,IACrE;GACV,KAAK;IACD,IAAI,CAAC,cAAc,KAAK,GAAG,OAAO;IAClC,OAAO,OAAO,YACV,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,gBAAgB,CAC7C,KACA,YAAY,aAAa,MAAM,WAAW,UAAU,CACxD,CAAC,CACL;GACJ,KAAK;IACD,IAAI,CAAC,cAAc,KAAK,GAAG,OAAO;IAClC,OAAO,OAAO,YACV,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,gBAAgB;KAC7C,MAAM,QAAQ,aAAa,MAAM,OAAO,MAAM,MAAM,EAAE,SAAS,GAAG;KAClE,OAAO,CAAC,KAAK,QAAQ,YAAY,MAAM,MAAM,UAAU,IAAI,UAAU;IACzE,CAAC,CACL;GACJ,KAAK,YACD,OAAO,YAAY,aAAa,MAAM,MAAM,KAAK;GACrD,KAAK;GACL,KAAK,UACD,OAAO;GACX,KAAK,OACD,OAAO,YAAY,YAAY,YAAY,GAAG,KAAK;EAC3D;CACJ;CAEA,OAAO;EACH,eAAe,gBAAgB,WAAW;GACtC,MAAM,aAAa,YAAY,IAAI,cAAc;GACjD,IAAI,CAAC,YACD,OAAO;GAGX,OAAO,iBAAiB,YAAY,MAAM;EAC9C;EACA,mBAAmB,gBAAgB,WAAW;GAC1C,MAAM,aAAa,YAAY,IAAI,cAAc;GACjD,IAAI,CAAC,YACD,OAAO;GAGX,OAAO,iBAAiB,YAAY,QAAQ,IAAI;EACpD;EACA;EACA;CACJ;AACJ;AAEA,SAAS,eAAe,OAAyB;CAC7C,IAAI,cAAc,KAAK,KAAK,OAAO,MAAM,QAAQ,YAAY,OAAO,MAAM,QAAQ,UAC9E,OAAO;EAAE,MAAM;EAAS,aAAa,CAAC,MAAM,KAAK,MAAM,GAAG;CAAE;CAEhE,OAAO;AACX;AAEA,SAAS,eAAe,OAAyB;CAC7C,IAAI,cAAc,KAAK,KAAK,MAAM,SAAS,WAAW,MAAM,QAAQ,MAAM,WAAW,GAAG;EACpF,MAAM,cAAc,MAAM;EAC1B,MAAM,MAAM,YAAY;EACxB,MAAM,MAAM,YAAY;EACxB,IAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,UAC1C,OAAO;GAAE;GAAK;EAAI;CAE1B;CAEA,IAAI,cAAc,KAAK,KAAK,OAAO,MAAM,QAAQ,YAAY,OAAO,MAAM,QAAQ,UAC9E,OAAO;CAGX,OAAO;AACX;AAEA,SAAS,uBAAuB,OAAyB;CACrD,OAAO,UAAU;AACrB;AAEA,SAAS,uBAAuB,MAAe,OAAyB;CACpE,IACI,cAAc,KAAK,KACnB,OAAO,MAAM,SAAS,YACtB,WAAW,SACX;EACI;EACA;EACA;EACA;EACA;EACA;EACA;CACJ,CAAC,CAAC,SAAS,MAAM,IAAI,GAErB,OAAO,MAAM;CAEjB,IAAI,KAAK,SAAS,cAAc,OAAO,UAAU,UAAU;EACvD,MAAM,QAAQ,+EAA+E,KACzF,KACJ;EACA,IAAI,OACA,OAAO;GACH,KAAK,OAAO,MAAM,EAAE;GACpB,KAAK,OAAO,MAAM,EAAE;EACxB;CAER;CACA,IACI,KAAK,SAAS,gBACd,yBAAyB,KAAK,MAAM,IAAI,MAAM,WAC9C,cAAc,KAAK,KACnB,MAAM,SAAS,gBACf,OAAO,MAAM,eAAe,UAE5B,OAAO,EAAE,KAAK,MAAM,WAAW;CAEnC,IACI,KAAK,SAAS,gBACd,yBAAyB,KAAK,MAAM,IAAI,MAAM,WAC9C,cAAc,KAAK,KACnB,MAAM,SAAS,oBACf,cAAc,MAAM,cAAc,GAElC,OAAO,MAAM;CAEjB,OAAO;AACX;AAEA,SAAS,iBACL,OACA,MACA,UACO;CACP,MAAM,OAAO,yBAAyB,IAAI;CAC1C,MAAM,UAAU,SAAS,UAAU,qBAAqB,KAAK,IAAI,wBAAwB,KAAK;CAC9F,IAAI,YAAY,KAAA,KAAa,UACzB,OAAO;CAEX,MAAM,IAAI,MAAM,4BAA4B,KAAK,QAAQ;AAC7D;AAEA,SAAS,wBAAwB,OAAyB;CACtD,MAAM,aAAa;CACnB,IAAI,OAAO,YAAY,QAAQ,UAC3B;CAEJ,OAAO,EAAE,IAAI,WAAW,IAAI;AAChC;AAEA,SAAS,qBAAqB,OAAyB;CACnD,IACI,CAAC,cAAc,KAAK,KACpB,OAAO,MAAM,aAAa,YAC1B,CAAC,cAAc,MAAM,SAAS,KAC9B,MAAM,UAAU,SAAS,sBACzB,CAAC,cAAc,MAAM,UAAU,gBAAgB,GAE/C;CAEJ,MAAM,iBAAiB;CACvB,MAAM,KAAK,+BAA+B,cAAc;CACxD,IAAI,CAAC,qBAAqB,EAAE,GACxB;CAEJ,OAAO;EACH;EACA,MAAM,eAAe;CACzB;AACJ;AAEA,SAAS,iBACL,OACA,MACA,uBACO;CACP,IAAI,CAAC,cAAc,KAAK,GACpB,OAAO;CAEX,IAAI,OAAO,MAAM,OAAO,UACpB,MAAM,IAAI,MAAM,4EAA4E;CAEhG,IAAI,yBAAyB,IAAI,MAAM,SACnC,OAAO,MAAM;CAEjB,MAAM,WAAW,wBAAwB,MAAM,EAAE;CACjD,IAAI,UAAU,OAAO;CACrB,MAAM,KAAK,qBAAqB,MAAM,EAAE;CACxC,IAAI,CAAC,IACD,MAAM,IAAI,MAAM,wCAAwC,MAAM,GAAG,GAAG;CAExE,IAAI,OAAO,MAAM,SAAS,UACtB,MAAM,IAAI,MAAM,6BAA6B,MAAM,GAAG,4BAA4B;CAEtF,OAAO,0BAA0B,IAAI,MAAM,IAAI;AACnD;AAEA,SAAS,cAAc,OAA8C;CACjE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E"}
1
+ {"version":3,"file":"foundryCodec.js","names":[],"sources":["../../src/adapter/foundryCodec.ts"],"sourcesContent":["import { Schema } from \"effect\";\nimport { Temporal } from \"temporal-polyfill\";\nimport { getFoundryAttachmentKind } from \"../meta/foundryAttachmentMetadata.js\";\nimport { decodeFoundryCiphertext, encodeFoundryCiphertext } from \"./encrypted.js\";\nimport {\n decodeFoundryMediaId,\n foundryMediaIdToReference,\n mediaReferenceToFoundryMediaId,\n} from \"./foundryMediaId.js\";\nimport type { MediaReference } from \"@osdk/foundry.core\";\nimport type { AttachmentProperty, OntologyObjectV2 } from \"@osdk/foundry.ontologies\";\nimport type { ObjectTypeDef, OntologyIR, TypeDef } from \"@party-stack/ontology-spec\";\nimport type { Encrypted } from \"@party-stack/ontology-spec/values\";\n\ntype FoundryObjectRecord = Record<string, unknown>;\nexport interface FoundryCodec {\n decodeObject: (objectType: string, object: OntologyObjectV2 | FoundryObjectRecord) => FoundryObjectRecord;\n decodeEditObject: (objectType: string, object: FoundryObjectRecord) => FoundryObjectRecord;\n decodeValue: (type: TypeDef, value: unknown) => unknown;\n encodeValue: (type: TypeDef, value: unknown) => unknown;\n}\n\nexport function createFoundryCodec(\n ir: OntologyIR,\n options?: {\n resolveMediaReference?: (id: string) => MediaReference | undefined;\n resolveAttachmentId?: (id: string) => string | undefined;\n }\n): FoundryCodec {\n const objectTypes = new Map(ir.objectTypes.map((objectType) => [objectType.name, objectType]));\n const namedTypes = new Map(ir.types.map((type) => [type.name, type.type]));\n\n const resolveType = (type: TypeDef, seen = new Set<string>()): TypeDef => {\n if (type.kind !== \"ref\") {\n return type;\n }\n\n const name = type.value.name;\n if (seen.has(name)) {\n throw new Error(`Circular ontology type reference \"${name}\".`);\n }\n\n const resolved = namedTypes.get(name);\n if (!resolved) {\n throw new Error(`Unknown ontology type reference \"${name}\".`);\n }\n\n return resolveType(resolved, new Set([...seen, name]));\n };\n\n const decodeValue = (\n type: TypeDef,\n value: unknown,\n context: { editHistory: boolean; optional: boolean; source?: Encrypted[\"source\"] } = {\n editHistory: false,\n optional: false,\n }\n ): unknown => {\n const resolvedType = resolveType(type);\n\n if (resolvedType.kind === \"optional\") {\n if (\n value === undefined ||\n value === null ||\n (context.editHistory && isNullEditHistoryValue(value))\n ) {\n return undefined;\n }\n return decodeValue(resolvedType.value.type, value, {\n ...context,\n optional: true,\n });\n }\n\n if (value === undefined || value === null) {\n return value;\n }\n if (context.editHistory) {\n value = unwrapEditHistoryValue(resolvedType, value);\n }\n\n switch (resolvedType.kind) {\n case \"encrypted\":\n return decodeFoundryCiphertext(value, context.source);\n case \"string\":\n return value;\n case \"boolean\":\n return typeof value === \"string\" ? value === \"true\" : value;\n case \"integer\":\n case \"float\":\n case \"double\":\n return typeof value === \"string\" ? Number(value) : value;\n case \"date\":\n return typeof value === \"string\" ? Temporal.PlainDate.from(value) : value;\n case \"timestamp\":\n if (typeof value === \"string\") return Temporal.Instant.from(value);\n if (typeof value === \"number\") return Temporal.Instant.fromEpochMilliseconds(value);\n return value;\n case \"geopoint\":\n return decodeGeoPoint(value);\n case \"attachment\":\n return decodeAttachment(value, resolvedType.value.meta, context.optional);\n case \"objectReference\":\n return value;\n case \"list\":\n return Array.isArray(value)\n ? value.map((item) => decodeValue(resolvedType.value.elementType, item, context))\n : value;\n case \"map\":\n if (!isPlainObject(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => [\n decodeValue(resolvedType.value.keyType, key, context),\n decodeValue(resolvedType.value.valueType, entryValue, context),\n ])\n );\n case \"struct\":\n if (!isPlainObject(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => {\n const field = resolvedType.value.fields.find((candidate) => candidate.name === key);\n return [key, field ? decodeValue(field.type, entryValue, context) : entryValue];\n })\n );\n case \"union\":\n case \"result\":\n return value;\n case \"ref\":\n return decodeValue(resolveType(resolvedType), value);\n }\n };\n\n const decodeObjectType = (\n objectType: ObjectTypeDef,\n object: FoundryObjectRecord,\n editHistory = false\n ): FoundryObjectRecord => {\n const keyProperty = objectType.properties.find((property) => property.name === objectType.primaryKey);\n const primaryKey = keyProperty\n ? decodeValue(keyProperty.type, object[objectType.primaryKey], { editHistory, optional: false })\n : undefined;\n return Object.fromEntries(\n Object.entries(object).map(([key, value]) => {\n const property = objectType.properties.find((candidate) => candidate.name === key);\n return [\n key,\n property\n ? decodeValue(property.type, value, {\n editHistory,\n optional: false,\n source: Schema.is(Schema.Union([Schema.String, Schema.Finite]))(primaryKey)\n ? {\n objectType: objectType.name,\n primaryKey,\n property: key,\n }\n : undefined,\n })\n : value,\n ];\n })\n );\n };\n\n const encodeValue = (type: TypeDef, value: unknown): unknown => {\n if (value === undefined) return undefined;\n if (value === null) return null;\n\n const resolvedType = resolveType(type);\n\n switch (resolvedType.kind) {\n case \"encrypted\":\n return encodeFoundryCiphertext(value);\n case \"string\":\n case \"boolean\":\n case \"integer\":\n case \"float\":\n case \"double\":\n return value;\n case \"date\":\n return value instanceof Temporal.PlainDate ? value.toString() : value;\n case \"timestamp\":\n if (value instanceof Temporal.Instant) return value.toString();\n if (value instanceof Temporal.PlainDateTime) return value.toString();\n return value;\n case \"geopoint\":\n return encodeGeoPoint(value);\n case \"attachment\":\n return encodeAttachment(\n value,\n resolvedType.value.meta,\n options?.resolveMediaReference,\n options?.resolveAttachmentId\n );\n case \"objectReference\":\n case \"unknown\":\n return value;\n case \"list\":\n return Array.isArray(value)\n ? value.map((item) => encodeValue(resolvedType.value.elementType, item))\n : value;\n case \"map\":\n if (!isPlainObject(value)) return value;\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => [\n key,\n encodeValue(resolvedType.value.valueType, entryValue),\n ])\n );\n case \"struct\":\n if (!isPlainObject(value)) return value;\n return Object.fromEntries(\n Object.entries(value).map(([key, entryValue]) => {\n const field = resolvedType.value.fields.find((f) => f.name === key);\n return [key, field ? encodeValue(field.type, entryValue) : entryValue];\n })\n );\n case \"optional\":\n return encodeValue(resolvedType.value.type, value);\n case \"union\":\n case \"result\":\n return value;\n case \"ref\":\n return encodeValue(resolveType(resolvedType), value);\n }\n };\n\n return {\n decodeObject: (objectTypeName, object) => {\n const objectType = objectTypes.get(objectTypeName);\n if (!objectType) {\n return object;\n }\n\n return decodeObjectType(objectType, object);\n },\n decodeEditObject: (objectTypeName, object) => {\n const objectType = objectTypes.get(objectTypeName);\n if (!objectType) {\n return object;\n }\n\n return decodeObjectType(objectType, object, true);\n },\n decodeValue,\n encodeValue,\n };\n}\n\nfunction encodeGeoPoint(value: unknown): unknown {\n if (isPlainObject(value) && typeof value.lat === \"number\" && typeof value.lon === \"number\") {\n return { type: \"Point\", coordinates: [value.lon, value.lat] };\n }\n return value;\n}\n\nfunction decodeGeoPoint(value: unknown): unknown {\n if (isPlainObject(value) && value.type === \"Point\" && Array.isArray(value.coordinates)) {\n const coordinates = value.coordinates as unknown[];\n const lon = coordinates[0];\n const lat = coordinates[1];\n if (typeof lat === \"number\" && typeof lon === \"number\") {\n return { lat, lon };\n }\n }\n\n if (isPlainObject(value) && typeof value.lat === \"number\" && typeof value.lon === \"number\") {\n return value;\n }\n\n return value;\n}\n\nfunction isNullEditHistoryValue(value: unknown): boolean {\n return value === \"NullPropertyValue{}\";\n}\n\nfunction unwrapEditHistoryValue(type: TypeDef, value: unknown): unknown {\n if (\n isPlainObject(value) &&\n typeof value.type === \"string\" &&\n \"value\" in value &&\n [\n \"stringValue\",\n \"integerValue\",\n \"doubleValue\",\n \"longValue\",\n \"booleanValue\",\n \"dateValue\",\n \"timestampValue\",\n ].includes(value.type)\n ) {\n return value.value;\n }\n if (type.kind === \"geopoint\" && typeof value === \"string\") {\n const match = /^GeoPointPropertyValue\\{latitude:\\s*(-?[\\d.]+),\\s*longitude:\\s*(-?[\\d.]+)\\}$/.exec(\n value\n );\n if (match) {\n return {\n lat: Number(match[1]),\n lon: Number(match[2]),\n };\n }\n }\n if (\n type.kind === \"attachment\" &&\n getFoundryAttachmentKind(type.value.meta) !== \"media\" &&\n isPlainObject(value) &&\n value.type === \"attachment\" &&\n typeof value.attachment === \"string\"\n ) {\n return { rid: value.attachment };\n }\n if (\n type.kind === \"attachment\" &&\n getFoundryAttachmentKind(type.value.meta) === \"media\" &&\n isPlainObject(value) &&\n value.type === \"mediaReference\" &&\n isPlainObject(value.mediaReference)\n ) {\n return value.mediaReference;\n }\n return value;\n}\n\nfunction decodeAttachment(\n value: unknown,\n meta: Record<string, unknown> | undefined,\n optional: boolean\n): unknown {\n const kind = getFoundryAttachmentKind(meta);\n const decoded = kind === \"media\" ? decodeMediaReference(value) : decodeFoundryAttachment(value);\n if (decoded !== undefined || optional) {\n return decoded;\n }\n throw new Error(`Invalid required Foundry ${kind} value.`);\n}\n\nfunction decodeFoundryAttachment(value: unknown): unknown {\n const attachment = value as Partial<AttachmentProperty>;\n if (typeof attachment?.rid !== \"string\") {\n return undefined;\n }\n return { id: attachment.rid };\n}\n\nfunction decodeMediaReference(value: unknown): unknown {\n if (\n !isPlainObject(value) ||\n typeof value.mimeType !== \"string\" ||\n !isPlainObject(value.reference) ||\n value.reference.type !== \"mediaSetViewItem\" ||\n !isPlainObject(value.reference.mediaSetViewItem)\n ) {\n return undefined;\n }\n const mediaReference = value as unknown as MediaReference;\n const id = mediaReferenceToFoundryMediaId(mediaReference);\n if (!decodeFoundryMediaId(id)) {\n return undefined;\n }\n return {\n id,\n type: mediaReference.mimeType,\n };\n}\n\nfunction encodeAttachment(\n value: unknown,\n meta?: Record<string, unknown>,\n resolveMediaReference?: (id: string) => MediaReference | undefined,\n resolveAttachmentId?: (id: string) => string | undefined\n): unknown {\n if (!isPlainObject(value)) {\n return value;\n }\n if (typeof value.id !== \"string\") {\n throw new Error(\"Invalid Foundry attachment value: expected an attachment with a string id.\");\n }\n if (getFoundryAttachmentKind(meta) !== \"media\") {\n return resolveAttachmentId?.(value.id) ?? value.id;\n }\n const resolved = resolveMediaReference?.(value.id);\n if (resolved) return resolved;\n const id = decodeFoundryMediaId(value.id);\n if (!id) {\n throw new Error(`Invalid Foundry media attachment id \"${value.id}\".`);\n }\n if (typeof value.type !== \"string\") {\n throw new Error(`Foundry media attachment \"${value.id}\" is missing its MIME type.`);\n }\n return foundryMediaIdToReference(id, value.type);\n}\n\nfunction isPlainObject(value: unknown): value is FoundryObjectRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { OntologyClient } from "@party-stack/foundry-client";
2
+ import { SearchJsonQueryV2, SearchOrderByV2 } from "@osdk/foundry.ontologies";
3
+ //#region src/adapter/foundryObjectSearch.d.ts
4
+ /** Shared HTTP/pagination path. Callers translate their query syntax before searching. */
5
+ export declare function searchFoundryObjects(client: OntologyClient, objectType: string, selectedProperties: string[], options: {
6
+ readonly where?: SearchJsonQueryV2;
7
+ readonly orderBy?: SearchOrderByV2;
8
+ readonly offset?: number;
9
+ readonly limit?: number;
10
+ readonly signal?: AbortSignal;
11
+ }, decodeObject?: (object: Record<string, unknown>) => Record<string, unknown>): Promise<Record<string, unknown>[]>;
12
+ //#endregion
13
+ //# sourceMappingURL=foundryObjectSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundryObjectSearch.d.ts","names":[],"sources":["../../src/adapter/foundryObjectSearch.ts"],"mappings":";;;;wBAqBsB,qBAClB,QAAQ,gBACR,oBACA,8BACA;WACa,QAAQ;WACR,UAAU;WACV;WACA;WACA,SAAS;GAEtB,gBAAe,QAAQ,4BAA4B,0BACpD,QAAQ"}
@@ -0,0 +1,57 @@
1
+ import { fromPagination, toArray } from "../utils/AsyncIterable.js";
2
+ import { Redacted, Schema } from "effect";
3
+ import { OntologyObjectsV2 } from "@osdk/foundry.ontologies";
4
+ import { BackendError } from "@party-stack/ontology-backend";
5
+ //#region src/adapter/foundryObjectSearch.ts
6
+ const Page = Schema.Struct({
7
+ data: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),
8
+ nextPageToken: Schema.optional(Schema.String)
9
+ });
10
+ const invalidResponse = (cause) => new BackendError({
11
+ operation: "foundry.loadSubset",
12
+ kind: "InvalidResponse",
13
+ message: "Foundry returned an invalid object page.",
14
+ retryable: false,
15
+ cause: Redacted.make(cause)
16
+ });
17
+ /** Shared HTTP/pagination path. Callers translate their query syntax before searching. */
18
+ async function searchFoundryObjects(client, objectType, selectedProperties, options, decodeObject = (object) => object) {
19
+ options.signal?.throwIfAborted();
20
+ const offset = Math.max(0, Math.trunc(options.offset ?? 0));
21
+ const limit = options.limit === void 0 ? void 0 : Math.max(0, Math.trunc(options.limit));
22
+ if (limit === 0 || options.where?.type === "in" && options.where.value.length === 0) return [];
23
+ const requestClient = options.signal ? {
24
+ ...client,
25
+ fetch: (input, init) => client.fetch(input, {
26
+ ...init,
27
+ signal: init?.signal ? AbortSignal.any([options.signal, init.signal]) : options.signal
28
+ })
29
+ } : client;
30
+ const results = await toArray(fromPagination(async (pageSize, pageToken) => {
31
+ const result = await OntologyObjectsV2.search(requestClient, client.ontologyRid, objectType, {
32
+ snapshot: true,
33
+ where: options.where,
34
+ excludeRid: true,
35
+ select: selectedProperties,
36
+ selectV2: [],
37
+ pageSize,
38
+ pageToken,
39
+ orderBy: options.orderBy
40
+ });
41
+ try {
42
+ return Schema.decodeUnknownSync(Page)(result);
43
+ } catch (cause) {
44
+ throw invalidResponse(cause);
45
+ }
46
+ }, (page) => page.nextPageToken, (page) => page.data, 1e4, limit === void 0 ? void 0 : offset + limit));
47
+ options.signal?.throwIfAborted();
48
+ try {
49
+ return results.slice(offset, limit === void 0 ? void 0 : offset + limit).map(decodeObject);
50
+ } catch (cause) {
51
+ throw invalidResponse(cause);
52
+ }
53
+ }
54
+ //#endregion
55
+ export { searchFoundryObjects };
56
+
57
+ //# sourceMappingURL=foundryObjectSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundryObjectSearch.js","names":["AsyncIterable.toArray","AsyncIterable.fromPagination"],"sources":["../../src/adapter/foundryObjectSearch.ts"],"sourcesContent":["import { OntologyObjectsV2 } from \"@osdk/foundry.ontologies\";\nimport { BackendError } from \"@party-stack/ontology-backend\";\nimport { Schema, Redacted } from \"effect\";\nimport * as AsyncIterable from \"../utils/AsyncIterable.js\";\nimport type { SearchJsonQueryV2, SearchOrderByV2 } from \"@osdk/foundry.ontologies\";\nimport type { OntologyClient } from \"@party-stack/foundry-client\";\n\nconst Page = Schema.Struct({\n data: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),\n nextPageToken: Schema.optional(Schema.String),\n});\nconst invalidResponse = (cause: unknown) =>\n new BackendError({\n operation: \"foundry.loadSubset\",\n kind: \"InvalidResponse\",\n message: \"Foundry returned an invalid object page.\",\n retryable: false,\n cause: Redacted.make(cause),\n });\n\n/** Shared HTTP/pagination path. Callers translate their query syntax before searching. */\nexport async function searchFoundryObjects(\n client: OntologyClient,\n objectType: string,\n selectedProperties: string[],\n options: {\n readonly where?: SearchJsonQueryV2;\n readonly orderBy?: SearchOrderByV2;\n readonly offset?: number;\n readonly limit?: number;\n readonly signal?: AbortSignal;\n },\n decodeObject: (object: Record<string, unknown>) => Record<string, unknown> = (object) => object\n): Promise<Record<string, unknown>[]> {\n options.signal?.throwIfAborted();\n const offset = Math.max(0, Math.trunc(options.offset ?? 0));\n const limit = options.limit === undefined ? undefined : Math.max(0, Math.trunc(options.limit));\n if (limit === 0 || (options.where?.type === \"in\" && options.where.value.length === 0)) return [];\n const requestClient = options.signal\n ? {\n ...client,\n fetch: (input: RequestInfo | URL, init?: RequestInit) =>\n client.fetch(input, {\n ...init,\n signal: init?.signal ? AbortSignal.any([options.signal!, init.signal]) : options.signal,\n }),\n }\n : client;\n const results = await AsyncIterable.toArray(\n AsyncIterable.fromPagination(\n async (pageSize, pageToken: string | undefined) => {\n const result = await OntologyObjectsV2.search(requestClient, client.ontologyRid, objectType, {\n snapshot: true,\n where: options.where,\n excludeRid: true,\n select: selectedProperties,\n selectV2: [],\n pageSize,\n pageToken,\n orderBy: options.orderBy,\n });\n try {\n return Schema.decodeUnknownSync(Page)(result);\n } catch (cause) {\n throw invalidResponse(cause);\n }\n },\n (page) => page.nextPageToken,\n (page) => page.data,\n 10_000,\n limit === undefined ? undefined : offset + limit\n )\n );\n options.signal?.throwIfAborted();\n try {\n return results.slice(offset, limit === undefined ? undefined : offset + limit).map(decodeObject);\n } catch (cause) {\n throw invalidResponse(cause);\n }\n}\n"],"mappings":";;;;;AAOA,MAAM,OAAO,OAAO,OAAO;CACvB,MAAM,OAAO,MAAM,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC;CAC/D,eAAe,OAAO,SAAS,OAAO,MAAM;AAChD,CAAC;AACD,MAAM,mBAAmB,UACrB,IAAI,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACT,WAAW;CACX,OAAO,SAAS,KAAK,KAAK;AAC9B,CAAC;;AAGL,eAAsB,qBAClB,QACA,YACA,oBACA,SAOA,gBAA8E,WAAW,QACvD;CAClC,QAAQ,QAAQ,eAAe;CAC/B,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,UAAU,CAAC,CAAC;CAC1D,MAAM,QAAQ,QAAQ,UAAU,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,CAAC;CAC7F,IAAI,UAAU,KAAM,QAAQ,OAAO,SAAS,QAAQ,QAAQ,MAAM,MAAM,WAAW,GAAI,OAAO,CAAC;CAC/F,MAAM,gBAAgB,QAAQ,SACxB;EACI,GAAG;EACH,QAAQ,OAA0B,SAC9B,OAAO,MAAM,OAAO;GAChB,GAAG;GACH,QAAQ,MAAM,SAAS,YAAY,IAAI,CAAC,QAAQ,QAAS,KAAK,MAAM,CAAC,IAAI,QAAQ;EACrF,CAAC;CACT,IACA;CACN,MAAM,UAAU,MAAMA,QAClBC,eACI,OAAO,UAAU,cAAkC;EAC/C,MAAM,SAAS,MAAM,kBAAkB,OAAO,eAAe,OAAO,aAAa,YAAY;GACzF,UAAU;GACV,OAAO,QAAQ;GACf,YAAY;GACZ,QAAQ;GACR,UAAU,CAAC;GACX;GACA;GACA,SAAS,QAAQ;EACrB,CAAC;EACD,IAAI;GACA,OAAO,OAAO,kBAAkB,IAAI,CAAC,CAAC,MAAM;EAChD,SAAS,OAAO;GACZ,MAAM,gBAAgB,KAAK;EAC/B;CACJ,IACC,SAAS,KAAK,gBACd,SAAS,KAAK,MACf,KACA,UAAU,KAAA,IAAY,KAAA,IAAY,SAAS,KAC/C,CACJ;CACA,QAAQ,QAAQ,eAAe;CAC/B,IAAI;EACA,OAAO,QAAQ,MAAM,QAAQ,UAAU,KAAA,IAAY,KAAA,IAAY,SAAS,KAAK,CAAC,CAAC,IAAI,YAAY;CACnG,SAAS,OAAO;EACZ,MAAM,gBAAgB,KAAK;CAC/B;AACJ"}
@@ -1,4 +1,3 @@
1
- import { CreateFoundryOntologyBackendAdapterOptions, CreateFoundryOntologyBackendOptions, FoundryUsersIntegration, createFoundryOntologyBackend, createFoundryOntologyBackendAdapter, isFoundryNotFoundError } from "./createFoundryOntologyBackendAdapter.js";
2
- import { FoundryCodec, FoundryObjectDecoder, createFoundryCodec, createFoundryObjectDecoder } from "./foundryCodec.js";
3
- import { ObjectCollectionConfig, ObjectCollectionOpts, ObjectCollectionUtils, objectCollectionOptions } from "./objectCollectionOptions.js";
4
- export { CreateFoundryOntologyBackendAdapterOptions, CreateFoundryOntologyBackendOptions, FoundryCodec, FoundryObjectDecoder, FoundryUsersIntegration, ObjectCollectionConfig, ObjectCollectionOpts, ObjectCollectionUtils, createFoundryCodec, createFoundryObjectDecoder, createFoundryOntologyBackend, createFoundryOntologyBackendAdapter, isFoundryNotFoundError, objectCollectionOptions };
1
+ import { FoundryCodec, createFoundryCodec } from "./foundryCodec.js";
2
+ import { FoundryOntologyBackendOptions, FoundryUsersIntegration, isFoundryNotFoundError, makeFoundryOntologyBackend } from "./makeFoundryOntologyBackend.js";
3
+ export { FoundryCodec, FoundryOntologyBackendOptions, FoundryUsersIntegration, createFoundryCodec, isFoundryNotFoundError, makeFoundryOntologyBackend };
@@ -1,4 +1,3 @@
1
- import { objectCollectionOptions } from "./objectCollectionOptions.js";
2
- import { createFoundryCodec, createFoundryObjectDecoder } from "./foundryCodec.js";
3
- import { createFoundryOntologyBackend, createFoundryOntologyBackendAdapter, isFoundryNotFoundError } from "./createFoundryOntologyBackendAdapter.js";
4
- export { createFoundryCodec, createFoundryObjectDecoder, createFoundryOntologyBackend, createFoundryOntologyBackendAdapter, isFoundryNotFoundError, objectCollectionOptions };
1
+ import { createFoundryCodec } from "./foundryCodec.js";
2
+ import { isFoundryNotFoundError, makeFoundryOntologyBackend } from "./makeFoundryOntologyBackend.js";
3
+ export { createFoundryCodec, isFoundryNotFoundError, makeFoundryOntologyBackend };
@@ -0,0 +1,10 @@
1
+ import { SearchJsonQueryV2 } from "@osdk/foundry.ontologies";
2
+ //#region src/adapter/likeFilter.d.ts
3
+ interface PushdownFilter {
4
+ query: SearchJsonQueryV2;
5
+ safeToNegate: boolean;
6
+ }
7
+ export declare function convertLikeFilter(field: readonly (string | number)[], value: string, literalBackslashes?: boolean): PushdownFilter;
8
+ //#endregion
9
+ export {};
10
+ //# sourceMappingURL=likeFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"likeFilter.d.ts","names":[],"sources":["../../src/adapter/likeFilter.ts"],"mappings":";;UAWU;EACN,OAAO;EACP;;wBA+CY,kBACZ,qCACA,eACA,+BACD"}