@resistdesign/voltra 3.0.0-alpha.6 → 3.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/api/index.js CHANGED
@@ -4,11 +4,9 @@ import { QueryCommand, DynamoDBClient, PutItemCommand, GetItemCommand, UpdateIte
4
4
  import { marshall, unmarshall } from '@aws-sdk/util-dynamodb';
5
5
  import { S3, PutObjectCommand, HeadObjectCommand, CopyObjectCommand, GetObjectCommand, DeleteObjectCommand, ListObjectsV2Command } from '@aws-sdk/client-s3';
6
6
  import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
7
+ import { v4 } from 'uuid';
7
8
  import Path from 'path';
8
- import FS from 'fs';
9
9
  import { fileURLToPath } from 'url';
10
- import { SyntaxKind, isLiteralTypeNode, isStringLiteral, isNumericLiteral, createSourceFile, ScriptTarget } from 'typescript';
11
- import { v4 } from 'uuid';
12
10
 
13
11
  var __defProp = Object.defineProperty;
14
12
  var __export = (target, all) => {
@@ -92,21 +90,48 @@ __export(Indexing_exports, {
92
90
  });
93
91
 
94
92
  // src/api/Indexing/cursor.ts
93
+ var textEncoder = new TextEncoder();
94
+ var textDecoder = new TextDecoder();
95
+ function base64UrlFromBytes(bytes) {
96
+ let base64;
97
+ if (typeof globalThis.Buffer !== "undefined") {
98
+ base64 = globalThis.Buffer.from(bytes).toString("base64");
99
+ } else {
100
+ let bin = "";
101
+ for (let i = 0; i < bytes.length; i += 1) {
102
+ bin += String.fromCharCode(bytes[i]);
103
+ }
104
+ base64 = btoa(bin);
105
+ }
106
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
107
+ }
108
+ function bytesFromBase64Url(input) {
109
+ const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
110
+ const padded = base64.padEnd(
111
+ base64.length + (4 - base64.length % 4) % 4,
112
+ "="
113
+ );
114
+ if (typeof globalThis.Buffer !== "undefined") {
115
+ return new Uint8Array(globalThis.Buffer.from(padded, "base64"));
116
+ }
117
+ const bin = atob(padded);
118
+ const bytes = new Uint8Array(bin.length);
119
+ for (let i = 0; i < bin.length; i += 1) {
120
+ bytes[i] = bin.charCodeAt(i);
121
+ }
122
+ return bytes;
123
+ }
95
124
  function encodeCursor(payload) {
96
- return Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
125
+ const json = JSON.stringify(payload);
126
+ const bytes = textEncoder.encode(json);
127
+ return base64UrlFromBytes(bytes);
97
128
  }
98
129
  function decodeCursor(cursor) {
99
- const base64 = cursor.replace(/-/g, "+").replace(/_/g, "/");
100
- const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
101
- let decoded;
102
- try {
103
- decoded = Buffer.from(padded, "base64").toString("utf8");
104
- } catch (error) {
105
- throw new Error("Invalid cursor encoding.");
106
- }
107
130
  try {
131
+ const bytes = bytesFromBase64Url(cursor);
132
+ const decoded = textDecoder.decode(bytes);
108
133
  return JSON.parse(decoded);
109
- } catch (error) {
134
+ } catch {
110
135
  throw new Error("Invalid cursor payload.");
111
136
  }
112
137
  }
@@ -130,7 +155,11 @@ function decodePlanner(payload) {
130
155
  if (!payload?.p) {
131
156
  return void 0;
132
157
  }
133
- return { primaryToken: payload.p, statsVersion: payload.sv, sorting: payload.s ?? "docIdAsc" };
158
+ return {
159
+ primaryToken: payload.p,
160
+ statsVersion: payload.sv,
161
+ sorting: payload.s ?? "docIdAsc"
162
+ };
134
163
  }
135
164
  function normalizeDocId(value) {
136
165
  if (value === void 0 || value === null) {
@@ -185,7 +214,12 @@ function encodeExactCursor(state) {
185
214
  }
186
215
  const plan = encodePlanner(state.plan);
187
216
  if (!plan && verificationPending === void 0 && verificationOffset === void 0) {
188
- return encodePayload({ v: 1, t: "exact", lossyLastDocId, verificationLastDocId });
217
+ return encodePayload({
218
+ v: 1,
219
+ t: "exact",
220
+ lossyLastDocId,
221
+ verificationLastDocId
222
+ });
189
223
  }
190
224
  return encodePayload({
191
225
  v: 3,
@@ -206,7 +240,9 @@ function decodeExactCursor(cursor) {
206
240
  throw new Error("Expected exact cursor payload.");
207
241
  }
208
242
  const payloadV3 = payload;
209
- const normalizedVerificationPending = normalizeDocIdList(payloadV3.verificationPending);
243
+ const normalizedVerificationPending = normalizeDocIdList(
244
+ payloadV3.verificationPending
245
+ );
210
246
  return {
211
247
  lossy: payload.lossyLastDocId === void 0 ? void 0 : { lastDocId: normalizeDocId(payload.lossyLastDocId) },
212
248
  verification: payload.verificationLastDocId === void 0 ? normalizedVerificationPending || payloadV3.verificationOffset !== void 0 ? {
@@ -3964,1919 +4000,2351 @@ var DATA_ITEM_DB_DRIVER_ERRORS = /* @__PURE__ */ ((DATA_ITEM_DB_DRIVER_ERRORS2)
3964
4000
  DATA_ITEM_DB_DRIVER_ERRORS2["SEARCH_COMPARISON_OPERATOR_NOT_SUPPORTED"] = "SEARCH_COMPARISON_OPERATOR_NOT_SUPPORTED";
3965
4001
  return DATA_ITEM_DB_DRIVER_ERRORS2;
3966
4002
  })(DATA_ITEM_DB_DRIVER_ERRORS || {});
3967
- var convertASTToMap = (node, map = {}, parentName) => {
3968
- node.forEachChild((child) => {
3969
- const { kind: childKind } = child;
3970
- if (childKind === SyntaxKind.ModuleDeclaration) {
3971
- const moduleNode = child;
3972
- const { name: moduleName } = moduleNode;
3973
- const textModuleName = moduleName.getText();
3974
- const fullModuleName = parentName ? `${parentName}.${textModuleName}` : textModuleName;
3975
- convertASTToMap(moduleNode, map, fullModuleName);
3976
- }
3977
- if (childKind === SyntaxKind.ModuleBlock) {
3978
- convertASTToMap(child, map, parentName);
3979
- }
3980
- if (childKind === SyntaxKind.TypeAliasDeclaration) {
3981
- const typeAliasDec = child;
3982
- const {
3983
- name: { text: typeName }
3984
- } = typeAliasDec;
3985
- const fullTypeName = parentName ? `${parentName}.${typeName}` : typeName;
3986
- map[fullTypeName] = typeAliasDec;
3987
- }
3988
- });
3989
- return map;
3990
- };
3991
4003
 
3992
- // src/common/TypeParsing/ParsingUtils/extractCommentTags.ts
3993
- var TAG_NAME_PATH_DELIMITER = ".";
3994
- var getFlatTagValue = (tagValue) => {
3995
- if (typeof tagValue === "undefined") {
3996
- return "";
3997
- } else if (Array.isArray(tagValue)) {
3998
- const valueNodeArray = tagValue;
3999
- const valueList = [];
4000
- for (let i = 0; i < valueNodeArray.length; i++) {
4001
- const { text } = valueNodeArray[i];
4002
- valueList.push(getFlatTagValue(text));
4003
- }
4004
- return valueList.join(" ");
4005
- } else {
4006
- return `${tagValue}`;
4007
- }
4008
- };
4009
- var getTagNameAndValue = (tag) => {
4010
- let name = tag.tagName.text, value = getFlatTagValue(tag.comment);
4011
- if (value.startsWith(TAG_NAME_PATH_DELIMITER)) {
4012
- const extendedTagNameEndIndex = value.indexOf(" ");
4013
- const hasActualValue = extendedTagNameEndIndex !== -1;
4014
- name += hasActualValue ? value.slice(0, extendedTagNameEndIndex) : value;
4015
- value = hasActualValue ? value.slice(extendedTagNameEndIndex + 1) : "";
4016
- }
4017
- if (value === "") {
4018
- value = "true";
4019
- }
4020
- return {
4021
- name,
4022
- value
4023
- };
4024
- };
4025
- var getObjectWithValueAppliedToPath = (path = [], value, baseObject) => {
4026
- let baseParentObject = void 0, currentParent = void 0;
4027
- if (path.length === 0) {
4028
- baseParentObject = value;
4029
- } else {
4030
- for (let i = 0; i < path.length; i++) {
4031
- const pathPart = path[i];
4032
- const cleanPathPart = typeof pathPart === "number" ? pathPart : `${typeof pathPart !== "undefined" ? pathPart : ""}`;
4033
- const isNum = typeof cleanPathPart === "number";
4034
- let newCurrentParent = void 0;
4035
- if (i === 0) {
4036
- if (!baseObject) {
4037
- baseParentObject = isNum ? [] : {};
4038
- } else {
4039
- baseParentObject = isNum ? [...Array.isArray(baseObject) ? baseObject : []] : {
4040
- ...typeof baseObject === "object" ? baseObject : {}
4041
- };
4042
- }
4043
- currentParent = baseParentObject;
4044
- }
4045
- if (i < path.length - 1) {
4046
- const existingNewCurrentParent = currentParent[cleanPathPart];
4047
- newCurrentParent = isNum ? [
4048
- ...Array.isArray(existingNewCurrentParent) ? existingNewCurrentParent : []
4049
- ] : {
4050
- ...typeof existingNewCurrentParent === "object" ? existingNewCurrentParent : {}
4051
- };
4052
- currentParent[cleanPathPart] = newCurrentParent;
4053
- currentParent = newCurrentParent;
4054
- } else {
4055
- currentParent[cleanPathPart] = value;
4004
+ // src/api/ORM/drivers/S3FileItemDBDriver/ConfigTypeInfoMap.json
4005
+ var ConfigTypeInfoMap_default = {
4006
+ Logger: {
4007
+ fields: {
4008
+ trace: {
4009
+ type: "string",
4010
+ array: false,
4011
+ readonly: false,
4012
+ optional: true,
4013
+ possibleValues: [],
4014
+ tags: {}
4015
+ },
4016
+ debug: {
4017
+ type: "string",
4018
+ array: false,
4019
+ readonly: false,
4020
+ optional: false,
4021
+ typeReference: "Trace",
4022
+ tags: {}
4023
+ },
4024
+ info: {
4025
+ type: "string",
4026
+ array: false,
4027
+ readonly: false,
4028
+ optional: false,
4029
+ typeReference: "Trace",
4030
+ tags: {}
4031
+ },
4032
+ warn: {
4033
+ type: "string",
4034
+ array: false,
4035
+ readonly: false,
4036
+ optional: false,
4037
+ typeReference: "Trace",
4038
+ tags: {}
4039
+ },
4040
+ error: {
4041
+ type: "string",
4042
+ array: false,
4043
+ readonly: false,
4044
+ optional: false,
4045
+ typeReference: "Trace",
4046
+ tags: {}
4056
4047
  }
4057
- }
4058
- }
4059
- return baseParentObject;
4060
- };
4061
- var extractCommentTags = (node) => {
4062
- const jsDocComments = node["jsDoc"];
4063
- let commentTags = {};
4064
- if (jsDocComments) {
4065
- jsDocComments.forEach((jsDoc) => {
4066
- const tags = jsDoc.tags;
4067
- if (tags) {
4068
- tags.forEach((tag) => {
4069
- const { name: tagName, value: tagValue } = getTagNameAndValue(tag);
4070
- const potentialJSONValue = getPotentialJSONValue(tagValue);
4071
- commentTags = getObjectWithValueAppliedToPath(
4072
- getPathArray(tagName, TAG_NAME_PATH_DELIMITER),
4073
- potentialJSONValue,
4074
- commentTags
4075
- );
4076
- });
4048
+ },
4049
+ tags: {},
4050
+ primaryField: "trace"
4051
+ },
4052
+ Endpoint: {
4053
+ fields: {
4054
+ protocol: {
4055
+ type: "string",
4056
+ array: false,
4057
+ readonly: false,
4058
+ optional: false,
4059
+ tags: {}
4060
+ },
4061
+ hostname: {
4062
+ type: "string",
4063
+ array: false,
4064
+ readonly: false,
4065
+ optional: false,
4066
+ tags: {}
4067
+ },
4068
+ port: {
4069
+ type: "string",
4070
+ array: false,
4071
+ readonly: false,
4072
+ optional: true,
4073
+ tags: {}
4074
+ },
4075
+ path: {
4076
+ type: "string",
4077
+ array: false,
4078
+ readonly: false,
4079
+ optional: false,
4080
+ tags: {}
4081
+ },
4082
+ query: {
4083
+ type: "string",
4084
+ array: false,
4085
+ readonly: false,
4086
+ optional: true,
4087
+ tags: {}
4077
4088
  }
4078
- });
4079
- }
4080
- return commentTags;
4081
- };
4082
- var extractLiteralValues = (node) => {
4083
- const literalValues = [];
4084
- let detectedTypeKeyword;
4085
- for (const type of node.types) {
4086
- if (isLiteralTypeNode(type)) {
4087
- const literal = type.literal;
4088
- if (isStringLiteral(literal)) {
4089
- if (!detectedTypeKeyword) detectedTypeKeyword = "string";
4090
- if (detectedTypeKeyword === "string") {
4091
- literalValues.push(literal.text);
4092
- }
4093
- } else if (isNumericLiteral(literal)) {
4094
- if (!detectedTypeKeyword) detectedTypeKeyword = "number";
4095
- if (detectedTypeKeyword === "number") {
4096
- literalValues.push(Number(literal.text));
4097
- }
4098
- } else if (literal.kind === SyntaxKind.TrueKeyword || literal.kind === SyntaxKind.FalseKeyword) {
4099
- if (!detectedTypeKeyword) detectedTypeKeyword = "boolean";
4100
- if (detectedTypeKeyword === "boolean") {
4101
- literalValues.push(literal.kind === SyntaxKind.TrueKeyword);
4102
- }
4103
- } else if (literal.kind === SyntaxKind.NullKeyword) {
4104
- literalValues.push(null);
4089
+ },
4090
+ tags: {},
4091
+ primaryField: "protocol"
4092
+ },
4093
+ Properties: {
4094
+ fields: {
4095
+ authSchemes: {
4096
+ type: "string",
4097
+ array: false,
4098
+ readonly: false,
4099
+ optional: true,
4100
+ tags: {}
4105
4101
  }
4106
- } else {
4107
- return void 0;
4108
- }
4109
- }
4110
- return literalValues.length ? { values: literalValues, type: detectedTypeKeyword } : void 0;
4111
- };
4112
-
4113
- // src/common/TypeParsing/ParsingUtils/checkUnionType.ts
4114
- var checkUnionType = (unionType) => {
4115
- const extracted = extractLiteralValues(unionType);
4116
- let typeKeyword = "string";
4117
- let options;
4118
- if (extracted) {
4119
- options = extracted.values;
4120
- typeKeyword = extracted.type;
4121
- }
4122
- return { options: options || [], typeKeyword };
4123
- };
4124
- var getTypeKeyword = (node) => {
4125
- switch (node.kind) {
4126
- case SyntaxKind.StringKeyword:
4127
- return "string";
4128
- case SyntaxKind.NumberKeyword:
4129
- return "number";
4130
- case SyntaxKind.BooleanKeyword:
4131
- return "boolean";
4132
- default:
4133
- return "string";
4134
- }
4135
- };
4136
-
4137
- // src/common/TypeParsing/ParsingUtils/checkType.ts
4138
- var checkType = (node) => {
4139
- let typeReference;
4140
- let isArray = false;
4141
- let typeKeyword;
4142
- let options;
4143
- if (node.kind === SyntaxKind.TypeReference) {
4144
- typeReference = node.typeName.getText();
4145
- typeKeyword = "string";
4146
- } else if (node.kind === SyntaxKind.ArrayType) {
4147
- isArray = true;
4148
- const elementType = node.elementType;
4149
- const {
4150
- typeReference: elementReference,
4151
- isArray: elementIsArray,
4152
- typeKeyword: elementKeyword,
4153
- options: elementOptions
4154
- } = checkType(elementType);
4155
- typeReference = elementReference;
4156
- isArray = !!elementIsArray;
4157
- typeKeyword = elementKeyword || "string";
4158
- options = elementOptions;
4159
- } else if (node.kind === SyntaxKind.UnionType) {
4160
- const { types: unionTypes } = node;
4161
- const { options: unionOptions, typeKeyword: unionTypeKeyword } = checkUnionType(node);
4162
- options = unionOptions;
4163
- typeKeyword = unionTypeKeyword;
4164
- if (!options) {
4165
- typeKeyword = getTypeKeyword(unionTypes[0]);
4166
- }
4167
- } else if (node.kind === SyntaxKind.ParenthesizedType) {
4168
- const {
4169
- typeReference: parenthesizedReference,
4170
- isArray: parenthesizedIsArray,
4171
- typeKeyword: parenthesizedKeyword,
4172
- options: parenthesizedOptions
4173
- } = checkType(node.type);
4174
- typeReference = parenthesizedReference;
4175
- isArray = !!parenthesizedIsArray;
4176
- typeKeyword = parenthesizedKeyword || "string";
4177
- options = parenthesizedOptions;
4178
- } else {
4179
- typeKeyword = getTypeKeyword(node);
4180
- }
4181
- return { typeReference, isArray, typeKeyword, options };
4182
- };
4183
-
4184
- // src/common/TypeParsing/ParsingUtils/extractTypeDetails.ts
4185
- var extractTypeDetails = (type) => {
4186
- const { isArray, typeReference, options, typeKeyword } = checkType(type);
4187
- return {
4188
- type: typeKeyword || "string",
4189
- typeReference,
4190
- array: !!isArray,
4191
- options
4192
- };
4193
- };
4194
-
4195
- // src/common/TypeParsing/ParsingUtils/getTypeInfoField.ts
4196
- var getTypeInfoField = (propertySignature) => {
4197
- const { type, modifiers } = propertySignature;
4198
- const {
4199
- array,
4200
- typeReference,
4201
- type: typeKeyword,
4202
- options
4203
- } = type ? extractTypeDetails(type) : {
4204
- array: false,
4205
- typeReference: void 0,
4206
- type: "string",
4207
- options: void 0
4208
- };
4209
- const readonly = modifiers ? modifiers.some((modifier) => modifier.kind === SyntaxKind.ReadonlyKeyword) : false;
4210
- const optional = !!propertySignature.questionToken;
4211
- let tags = extractCommentTags(propertySignature);
4212
- if (readonly) {
4213
- const {
4214
- deniedOperations,
4215
- deniedOperations: { CREATE, UPDATE, DELETE } = {}
4216
- } = tags || {};
4217
- tags = {
4218
- ...tags,
4219
- deniedOperations: {
4220
- ...deniedOperations,
4221
- create: CREATE ?? true,
4222
- update: UPDATE ?? true,
4223
- delete: DELETE ?? true
4102
+ },
4103
+ tags: {},
4104
+ primaryField: "authSchemes"
4105
+ },
4106
+ RetryStrategy: {
4107
+ fields: {
4108
+ mode: {
4109
+ type: "string",
4110
+ array: false,
4111
+ readonly: false,
4112
+ optional: true,
4113
+ tags: {}
4114
+ },
4115
+ retry: {
4116
+ type: "string",
4117
+ array: false,
4118
+ readonly: false,
4119
+ optional: false,
4120
+ tags: {}
4224
4121
  }
4225
- };
4226
- }
4227
- return {
4228
- type: typeKeyword,
4229
- array,
4230
- readonly,
4231
- optional,
4232
- typeReference,
4233
- possibleValues: options,
4234
- tags
4235
- };
4236
- };
4237
-
4238
- // src/common/TypeParsing/ParsingUtils/getTypeInfo.ts
4239
- var getTypeInfo = (typeLiteral) => {
4240
- const { members } = typeLiteral;
4241
- const tags = extractCommentTags(typeLiteral);
4242
- let fields = {};
4243
- for (const m of members) {
4244
- const { name, kind } = m;
4245
- if (name && kind === SyntaxKind.PropertySignature) {
4246
- const fieldName = name.getText();
4247
- const field = getTypeInfoField(m);
4248
- fields = {
4249
- ...fields,
4250
- [fieldName]: field
4251
- };
4252
- }
4253
- }
4254
- return {
4255
- fields,
4256
- tags
4257
- };
4258
- };
4259
- var getUnionOrIntersectionTypeInfo = (unionType, typeMap) => {
4260
- const { kind, types } = unionType;
4261
- const isUnion = kind === SyntaxKind.UnionType;
4262
- let typeInfo;
4263
- for (const t of types) {
4264
- const { kind: kind2 } = t;
4265
- let nextTypeInfo;
4266
- if (kind2 === SyntaxKind.TypeReference) {
4267
- const { typeName } = t;
4268
- const refNode = typeMap[typeName.getText()];
4269
- if (refNode) {
4270
- nextTypeInfo = getTypeInfoFromTypeAlias(refNode, typeMap);
4122
+ },
4123
+ tags: {},
4124
+ primaryField: "mode"
4125
+ },
4126
+ Credentials: {
4127
+ fields: {
4128
+ accessKeyId: {
4129
+ type: "string",
4130
+ array: false,
4131
+ readonly: false,
4132
+ optional: false,
4133
+ tags: {}
4134
+ },
4135
+ secretAccessKey: {
4136
+ type: "string",
4137
+ array: false,
4138
+ readonly: false,
4139
+ optional: false,
4140
+ tags: {}
4141
+ },
4142
+ sessionToken: {
4143
+ type: "string",
4144
+ array: false,
4145
+ readonly: false,
4146
+ optional: true,
4147
+ tags: {}
4148
+ },
4149
+ credentialScope: {
4150
+ type: "string",
4151
+ array: false,
4152
+ readonly: false,
4153
+ optional: true,
4154
+ tags: {}
4155
+ },
4156
+ expiration: {
4157
+ type: "string",
4158
+ array: false,
4159
+ readonly: false,
4160
+ optional: true,
4161
+ tags: {}
4271
4162
  }
4272
- } else if (kind2 === SyntaxKind.TypeLiteral) {
4273
- nextTypeInfo = getTypeInfo(t);
4274
- }
4275
- if (nextTypeInfo) {
4276
- const {
4277
- fields: existingFields = {},
4278
- unionFieldSets: existingFieldSets = []
4279
- } = typeInfo || {};
4280
- const { fields: nextFields, unionFieldSets: nextUnionFieldSets = [] } = nextTypeInfo;
4281
- if (isUnion && nextFields) {
4282
- const newUnionFieldSet = Object.keys(nextFields);
4283
- typeInfo = {
4284
- ...typeInfo,
4285
- unionFieldSets: [
4286
- ...existingFieldSets,
4287
- ...nextUnionFieldSets,
4288
- newUnionFieldSet
4289
- ]
4290
- };
4163
+ },
4164
+ tags: {},
4165
+ primaryField: "accessKeyId"
4166
+ },
4167
+ Signer: {
4168
+ fields: {
4169
+ sign: {
4170
+ type: "string",
4171
+ array: false,
4172
+ readonly: false,
4173
+ optional: false,
4174
+ tags: {}
4291
4175
  }
4292
- typeInfo = {
4293
- ...typeInfo,
4294
- fields: {
4295
- ...existingFields,
4296
- ...nextFields
4176
+ },
4177
+ tags: {},
4178
+ primaryField: "sign"
4179
+ },
4180
+ AbridgedS3ClientConfig: {
4181
+ fields: {
4182
+ requestHandler: {
4183
+ type: "string",
4184
+ array: false,
4185
+ readonly: false,
4186
+ optional: true,
4187
+ tags: {}
4188
+ },
4189
+ apiVersion: {
4190
+ type: "string",
4191
+ array: false,
4192
+ readonly: false,
4193
+ optional: true,
4194
+ tags: {}
4195
+ },
4196
+ sha256: {
4197
+ type: "string",
4198
+ array: false,
4199
+ readonly: false,
4200
+ optional: true,
4201
+ tags: {}
4202
+ },
4203
+ urlParser: {
4204
+ type: "string",
4205
+ array: false,
4206
+ readonly: false,
4207
+ optional: true,
4208
+ tags: {}
4209
+ },
4210
+ bodyLengthChecker: {
4211
+ type: "string",
4212
+ array: false,
4213
+ readonly: false,
4214
+ optional: true,
4215
+ tags: {}
4216
+ },
4217
+ streamCollector: {
4218
+ type: "string",
4219
+ array: false,
4220
+ readonly: false,
4221
+ optional: true,
4222
+ tags: {}
4223
+ },
4224
+ base64Decoder: {
4225
+ type: "string",
4226
+ array: false,
4227
+ readonly: false,
4228
+ optional: true,
4229
+ tags: {}
4230
+ },
4231
+ base64Encoder: {
4232
+ type: "string",
4233
+ array: false,
4234
+ readonly: false,
4235
+ optional: true,
4236
+ tags: {}
4237
+ },
4238
+ utf8Decoder: {
4239
+ type: "string",
4240
+ array: false,
4241
+ readonly: false,
4242
+ optional: true,
4243
+ tags: {}
4244
+ },
4245
+ utf8Encoder: {
4246
+ type: "string",
4247
+ array: false,
4248
+ readonly: false,
4249
+ optional: true,
4250
+ tags: {}
4251
+ },
4252
+ runtime: {
4253
+ type: "string",
4254
+ array: false,
4255
+ readonly: false,
4256
+ optional: true,
4257
+ tags: {}
4258
+ },
4259
+ disableHostPrefix: {
4260
+ type: "string",
4261
+ array: false,
4262
+ readonly: false,
4263
+ optional: true,
4264
+ possibleValues: [],
4265
+ tags: {}
4266
+ },
4267
+ serviceId: {
4268
+ type: "string",
4269
+ array: false,
4270
+ readonly: false,
4271
+ optional: true,
4272
+ tags: {}
4273
+ },
4274
+ useDualstackEndpoint: {
4275
+ type: "string",
4276
+ array: false,
4277
+ readonly: false,
4278
+ optional: true,
4279
+ possibleValues: [],
4280
+ tags: {}
4281
+ },
4282
+ useFipsEndpoint: {
4283
+ type: "string",
4284
+ array: false,
4285
+ readonly: false,
4286
+ optional: true,
4287
+ possibleValues: [],
4288
+ tags: {}
4289
+ },
4290
+ region: {
4291
+ type: "string",
4292
+ array: false,
4293
+ readonly: false,
4294
+ optional: true,
4295
+ tags: {}
4296
+ },
4297
+ credentialDefaultProvider: {
4298
+ type: "string",
4299
+ array: false,
4300
+ readonly: false,
4301
+ optional: true,
4302
+ tags: {}
4303
+ },
4304
+ signingEscapePath: {
4305
+ type: "string",
4306
+ array: false,
4307
+ readonly: false,
4308
+ optional: true,
4309
+ possibleValues: [],
4310
+ tags: {}
4311
+ },
4312
+ useArnRegion: {
4313
+ type: "string",
4314
+ array: false,
4315
+ readonly: false,
4316
+ optional: true,
4317
+ possibleValues: [],
4318
+ tags: {}
4319
+ },
4320
+ defaultUserAgentProvider: {
4321
+ type: "string",
4322
+ array: false,
4323
+ readonly: false,
4324
+ optional: true,
4325
+ tags: {}
4326
+ },
4327
+ streamHasher: {
4328
+ type: "string",
4329
+ array: false,
4330
+ readonly: false,
4331
+ optional: true,
4332
+ tags: {}
4333
+ },
4334
+ md5: {
4335
+ type: "string",
4336
+ array: false,
4337
+ readonly: false,
4338
+ optional: true,
4339
+ tags: {}
4340
+ },
4341
+ sha1: {
4342
+ type: "string",
4343
+ array: false,
4344
+ readonly: false,
4345
+ optional: true,
4346
+ tags: {}
4347
+ },
4348
+ getAwsChunkedEncodingStream: {
4349
+ type: "string",
4350
+ array: false,
4351
+ readonly: false,
4352
+ optional: true,
4353
+ tags: {}
4354
+ },
4355
+ maxAttempts: {
4356
+ type: "string",
4357
+ array: false,
4358
+ readonly: false,
4359
+ optional: true,
4360
+ tags: {}
4361
+ },
4362
+ retryMode: {
4363
+ type: "string",
4364
+ array: false,
4365
+ readonly: false,
4366
+ optional: true,
4367
+ tags: {}
4368
+ },
4369
+ logger: {
4370
+ type: "string",
4371
+ array: false,
4372
+ readonly: false,
4373
+ optional: true,
4374
+ possibleValues: [],
4375
+ tags: {}
4376
+ },
4377
+ extensions: {
4378
+ type: "string",
4379
+ array: false,
4380
+ readonly: false,
4381
+ optional: true,
4382
+ tags: {}
4383
+ },
4384
+ eventStreamSerdeProvider: {
4385
+ type: "string",
4386
+ array: false,
4387
+ readonly: false,
4388
+ optional: true,
4389
+ tags: {}
4390
+ },
4391
+ defaultsMode: {
4392
+ type: "string",
4393
+ array: false,
4394
+ readonly: false,
4395
+ optional: true,
4396
+ possibleValues: [
4397
+ "standard",
4398
+ "in-region",
4399
+ "cross-region",
4400
+ "mobile",
4401
+ "auto",
4402
+ "legacy"
4403
+ ],
4404
+ tags: {
4405
+ allowCustomSelection: true
4297
4406
  }
4298
- };
4299
- }
4300
- }
4301
- return typeInfo;
4302
- };
4303
-
4304
- // src/common/TypeParsing/ParsingUtils/Constants.ts
4305
- var FIELD_FILTERS = {
4306
- OMIT: "Omit",
4307
- PICK: "Pick",
4308
- EXCLUDE: "Exclude"
4309
- };
4310
- var getUnionOrLiteralStringValues = (node) => {
4311
- let values = [];
4312
- if (node) {
4313
- if (node.kind === SyntaxKind.LiteralType) {
4314
- const { literal } = node;
4315
- if (literal.kind === SyntaxKind.StringLiteral || literal.kind === SyntaxKind.NumericLiteral) {
4316
- const { text } = literal;
4317
- values = [text];
4407
+ },
4408
+ sdkStreamMixin: {
4409
+ type: "string",
4410
+ array: false,
4411
+ readonly: false,
4412
+ optional: true,
4413
+ tags: {}
4414
+ },
4415
+ endpoint: {
4416
+ type: "string",
4417
+ array: false,
4418
+ readonly: false,
4419
+ optional: true,
4420
+ possibleValues: [],
4421
+ tags: {}
4422
+ },
4423
+ endpointProvider: {
4424
+ type: "string",
4425
+ array: false,
4426
+ readonly: false,
4427
+ optional: true,
4428
+ tags: {}
4429
+ },
4430
+ tls: {
4431
+ type: "string",
4432
+ array: false,
4433
+ readonly: false,
4434
+ optional: true,
4435
+ possibleValues: [],
4436
+ tags: {}
4437
+ },
4438
+ retryStrategy: {
4439
+ type: "string",
4440
+ array: false,
4441
+ readonly: false,
4442
+ optional: true,
4443
+ possibleValues: [],
4444
+ tags: {}
4445
+ },
4446
+ credentials: {
4447
+ type: "string",
4448
+ array: false,
4449
+ readonly: false,
4450
+ optional: true,
4451
+ possibleValues: [],
4452
+ tags: {}
4453
+ },
4454
+ signer: {
4455
+ type: "string",
4456
+ array: false,
4457
+ readonly: false,
4458
+ optional: true,
4459
+ possibleValues: [],
4460
+ tags: {}
4461
+ },
4462
+ systemClockOffset: {
4463
+ type: "string",
4464
+ array: false,
4465
+ readonly: false,
4466
+ optional: true,
4467
+ tags: {}
4468
+ },
4469
+ signingRegion: {
4470
+ type: "string",
4471
+ array: false,
4472
+ readonly: false,
4473
+ optional: true,
4474
+ tags: {}
4475
+ },
4476
+ signerConstructor: {
4477
+ type: "string",
4478
+ array: false,
4479
+ readonly: false,
4480
+ optional: true,
4481
+ tags: {}
4482
+ },
4483
+ forcePathStyle: {
4484
+ type: "string",
4485
+ array: false,
4486
+ readonly: false,
4487
+ optional: true,
4488
+ possibleValues: [],
4489
+ tags: {}
4490
+ },
4491
+ useAccelerateEndpoint: {
4492
+ type: "string",
4493
+ array: false,
4494
+ readonly: false,
4495
+ optional: true,
4496
+ possibleValues: [],
4497
+ tags: {}
4498
+ },
4499
+ disableMultiregionAccessPoints: {
4500
+ type: "string",
4501
+ array: false,
4502
+ readonly: false,
4503
+ optional: true,
4504
+ possibleValues: [],
4505
+ tags: {}
4506
+ },
4507
+ followRegionRedirects: {
4508
+ type: "string",
4509
+ array: false,
4510
+ readonly: false,
4511
+ optional: true,
4512
+ possibleValues: [],
4513
+ tags: {}
4514
+ },
4515
+ s3ExpressIdentityProvider: {
4516
+ type: "string",
4517
+ array: false,
4518
+ readonly: false,
4519
+ optional: true,
4520
+ tags: {}
4521
+ },
4522
+ customUserAgent: {
4523
+ type: "string",
4524
+ array: false,
4525
+ readonly: false,
4526
+ optional: true,
4527
+ tags: {}
4528
+ },
4529
+ useGlobalEndpoint: {
4530
+ type: "string",
4531
+ array: false,
4532
+ readonly: false,
4533
+ optional: true,
4534
+ possibleValues: [],
4535
+ tags: {}
4536
+ },
4537
+ disableS3ExpressSessionAuth: {
4538
+ type: "string",
4539
+ array: false,
4540
+ readonly: false,
4541
+ optional: true,
4542
+ possibleValues: [],
4543
+ tags: {}
4318
4544
  }
4319
- } else if (node.kind === SyntaxKind.UnionType) {
4320
- const { types } = node;
4321
- for (const type of types) {
4322
- values = [...values, ...getUnionOrLiteralStringValues(type)];
4545
+ },
4546
+ tags: {},
4547
+ primaryField: "requestHandler"
4548
+ },
4549
+ S3SpecificConfig: {
4550
+ fields: {
4551
+ s3Config: {
4552
+ type: "string",
4553
+ array: false,
4554
+ readonly: false,
4555
+ optional: true,
4556
+ typeReference: "AbridgedS3ClientConfig",
4557
+ tags: {}
4558
+ },
4559
+ bucketName: {
4560
+ type: "string",
4561
+ array: false,
4562
+ readonly: false,
4563
+ optional: false,
4564
+ tags: {}
4565
+ },
4566
+ urlExpirationInSeconds: {
4567
+ type: "number",
4568
+ array: false,
4569
+ readonly: false,
4570
+ optional: true,
4571
+ tags: {}
4323
4572
  }
4324
- }
4573
+ },
4574
+ tags: {},
4575
+ primaryField: "s3Config"
4325
4576
  }
4326
- return values;
4327
4577
  };
4328
4578
 
4329
- // src/common/TypeParsing/ParsingUtils/getTypeInfoFromFieldFilter.ts
4330
- var getTypeInfoFromPickOmitFieldFilters = (typeNameStr, typeRef, typeMap) => {
4331
- const picking = typeNameStr === FIELD_FILTERS.PICK;
4332
- const omitTypeKind = typeRef.typeArguments?.[0].kind;
4333
- let typeInfo;
4334
- if (omitTypeKind === SyntaxKind.TypeReference && typeRef.typeArguments && typeRef.typeArguments[0].kind === SyntaxKind.TypeReference) {
4335
- const omitType = typeRef.typeArguments[0];
4336
- const omitTypeFields = typeRef.typeArguments[1];
4337
- const omitTypeName = omitType.typeName.getText();
4338
- const refNode = typeMap[omitTypeName];
4339
- if (refNode) {
4579
+ // src/api/ORM/drivers/S3FileItemDBDriver.ts
4580
+ var S3FileItemDBDriver = class {
4581
+ /**
4582
+ * @param config Driver configuration including S3 settings.
4583
+ */
4584
+ constructor(config) {
4585
+ this.config = config;
4586
+ const { dbSpecificConfig } = config;
4587
+ const { s3Config, bucketName, urlExpirationInSeconds } = dbSpecificConfig;
4588
+ this.specificConfig = dbSpecificConfig;
4589
+ this.s3 = new S3(s3Config);
4590
+ this.s3FileDriver = new S3FileDriver({
4591
+ s3Config,
4592
+ bucketName,
4593
+ urlExpirationInSeconds
4594
+ });
4595
+ }
4596
+ specificConfig;
4597
+ s3;
4598
+ s3FileDriver;
4599
+ /**
4600
+ * Create a new @{@link BaseFileItem}.
4601
+ * @param item New file item payload without the id field.
4602
+ * @returns Generated file id.
4603
+ * */
4604
+ createItem = async (item) => {
4605
+ const { tableName } = this.config;
4606
+ const { bucketName } = this.specificConfig;
4607
+ await this.s3.send(
4608
+ new PutObjectCommand({
4609
+ Bucket: bucketName,
4610
+ Key: getFullFileKey({
4611
+ file: item,
4612
+ // SECURITY: `baseDirectory` is only used internally here, and not as part of the `id`.
4613
+ baseDirectory: tableName
4614
+ }),
4615
+ Body: ""
4616
+ })
4617
+ );
4618
+ return getFullFileKey({
4619
+ file: item
4620
+ });
4621
+ };
4622
+ /**
4623
+ * Read a @{@link BaseFileItem} by its id.
4624
+ * @param id Unique identifier value for the file.
4625
+ * @param selectFields Optional fields to select from the file item.
4626
+ * @returns File item payload (partial when selected fields are used).
4627
+ * */
4628
+ readItem = async (id, selectFields) => {
4629
+ const { tableName } = this.config;
4630
+ const { bucketName } = this.specificConfig;
4631
+ if (typeof id === "undefined") {
4632
+ throw new Error("MISSING_ID" /* MISSING_ID */);
4633
+ } else {
4634
+ const itemLoc = getBaseFileLocationInfo(id);
4340
4635
  const {
4341
- fields: existingFields = {},
4342
- unionFieldSets: existingUnionFieldSets,
4343
- ...typeInfoOther
4344
- } = getTypeInfoFromTypeAlias(refNode, typeMap) || {};
4345
- const omitFieldNames = getUnionOrLiteralStringValues(omitTypeFields);
4346
- const cleanTypeInfoFields = Object.keys(
4347
- existingFields
4348
- ).reduce(
4349
- (acc, key) => {
4350
- if (acc && (picking && omitFieldNames.includes(key) || !picking && !omitFieldNames.includes(key)) && existingFields[key]) {
4351
- acc[key] = existingFields[key];
4352
- }
4353
- return acc;
4354
- },
4355
- {}
4636
+ ContentType = "",
4637
+ ContentLength = 0,
4638
+ LastModified} = await this.s3.send(
4639
+ new HeadObjectCommand({
4640
+ Bucket: bucketName,
4641
+ Key: getFullFileKey({
4642
+ file: itemLoc,
4643
+ baseDirectory: tableName
4644
+ })
4645
+ })
4356
4646
  );
4357
- const cleanUnionFieldSets = existingUnionFieldSets ? existingUnionFieldSets.map(
4358
- (fieldSet) => fieldSet.filter(
4359
- (field) => picking ? omitFieldNames.includes(field) : !omitFieldNames.includes(field)
4360
- )
4361
- ) : void 0;
4362
- typeInfo = {
4363
- ...typeInfoOther,
4364
- fields: cleanTypeInfoFields,
4365
- unionFieldSets: cleanUnionFieldSets
4366
- };
4367
- }
4368
- }
4369
- return typeInfo;
4370
- };
4371
- var getTypeInfoFromExcludeFieldFilter = (typeNameStr, typeRef, typeMap) => {
4372
- const baseTypeKind = typeRef.typeArguments?.[0].kind;
4373
- const excludeTypeKind = typeRef.typeArguments?.[1].kind;
4374
- let typeInfo;
4375
- if (baseTypeKind === SyntaxKind.TypeReference && excludeTypeKind === SyntaxKind.TypeReference && typeRef.typeArguments) {
4376
- const baseType = typeRef.typeArguments[0];
4377
- const excludeType = typeRef.typeArguments[1];
4378
- const baseTypeName = baseType.typeName.getText();
4379
- const excludeTypeName = excludeType.typeName.getText();
4380
- const refNode = typeMap[baseTypeName];
4381
- const excludeNode = typeMap[excludeTypeName];
4382
- if (refNode && excludeNode) {
4383
- const baseTypeInfo = getTypeInfoFromTypeAlias(refNode, typeMap);
4384
- const excludeTypeInfo = getTypeInfoFromTypeAlias(excludeNode, typeMap);
4385
- if (baseTypeInfo && excludeTypeInfo) {
4386
- const {
4387
- fields: baseFields = {},
4388
- unionFieldSets: existingUnionFieldSets
4389
- } = baseTypeInfo;
4390
- const { fields: excludeFields = {} } = excludeTypeInfo;
4391
- const excludeFieldNames = Object.keys(excludeFields);
4392
- const cleanTypeInfoFields = Object.keys(
4393
- baseFields
4394
- ).reduce(
4395
- (acc, key) => {
4396
- if (acc && !excludeFieldNames.includes(key) && baseFields[key]) {
4397
- acc[key] = baseFields[key];
4398
- }
4399
- return acc;
4400
- },
4401
- {}
4402
- );
4403
- const cleanUnionFieldSets = existingUnionFieldSets ? existingUnionFieldSets.map(
4404
- (fieldSet) => fieldSet.filter((field) => !excludeFieldNames.includes(field))
4405
- ) : void 0;
4406
- typeInfo = {
4407
- ...baseTypeInfo,
4408
- fields: cleanTypeInfoFields,
4409
- unionFieldSets: cleanUnionFieldSets
4410
- };
4411
- }
4647
+ const item = {
4648
+ ...itemLoc,
4649
+ id,
4650
+ updatedOn: LastModified?.getTime() || 0,
4651
+ mimeType: ContentType,
4652
+ sizeInBytes: ContentLength,
4653
+ isDirectory: ContentType === "application/x-directory",
4654
+ uploadUrl: selectFields && selectFields.includes("uploadUrl") ? await this.s3FileDriver.getFileUploadUrl(itemLoc, tableName) : void 0,
4655
+ downloadUrl: selectFields && selectFields.includes("downloadUrl") ? await this.s3FileDriver.getFileDownloadUrl(itemLoc, tableName) : void 0
4656
+ };
4657
+ return item;
4412
4658
  }
4413
- }
4414
- return typeInfo;
4415
- };
4416
- var defaultFieldFilterProcessor = (typeNameStr, typeRef, typeMap) => {
4417
- const refNode = typeNameStr ? typeMap[typeNameStr] : void 0;
4418
- let typeInfo;
4419
- if (refNode) {
4420
- typeInfo = getTypeInfoFromTypeAlias(refNode, typeMap);
4421
- }
4422
- return typeInfo;
4423
- };
4424
- var FIELD_FILTER_PROCESSORS = {
4425
- [FIELD_FILTERS.PICK]: getTypeInfoFromPickOmitFieldFilters,
4426
- [FIELD_FILTERS.OMIT]: getTypeInfoFromPickOmitFieldFilters,
4427
- [FIELD_FILTERS.EXCLUDE]: getTypeInfoFromExcludeFieldFilter
4428
- };
4429
- var getTypeInfoFromFieldFilter = (typeNameStr, typeRef, typeMap) => {
4430
- const processor = typeNameStr ? FIELD_FILTER_PROCESSORS[typeNameStr] : void 0;
4431
- return processor ? processor(typeNameStr, typeRef, typeMap) : defaultFieldFilterProcessor(typeNameStr, typeRef, typeMap);
4432
- };
4433
-
4434
- // src/common/TypeParsing/ParsingUtils/getTypeInfoFromAliasType.ts
4435
- var getTypeInfoFromTypeLiteral = (type) => getTypeInfo(type);
4436
- var getTypeInfoFromUnionOrIntersectionType = (type, typeMap) => getUnionOrIntersectionTypeInfo(type, typeMap);
4437
- var getTypeInfoFromTypeReference = (type, typeMap) => {
4438
- const typeRef = type;
4439
- const { typeName } = typeRef;
4440
- const typeNameStr = typeName.getText();
4441
- return getTypeInfoFromFieldFilter(typeNameStr, typeRef, typeMap);
4442
- };
4443
- var ALIAS_TYPE_PROCESSORS = {
4444
- [SyntaxKind.TypeLiteral]: getTypeInfoFromTypeLiteral,
4445
- [SyntaxKind.UnionType]: getTypeInfoFromUnionOrIntersectionType,
4446
- [SyntaxKind.IntersectionType]: getTypeInfoFromUnionOrIntersectionType,
4447
- [SyntaxKind.TypeReference]: getTypeInfoFromTypeReference
4448
- };
4449
- var getTypeInfoFromAliasType = (type, typeMap) => {
4450
- const { kind } = type;
4451
- const processor = ALIAS_TYPE_PROCESSORS[kind];
4452
- const typeInfo = processor ? processor(type, typeMap) : void 0;
4453
- return typeInfo;
4454
- };
4455
-
4456
- // src/common/TypeParsing/ParsingUtils/getTypeInfoFromTypeAlias.ts
4457
- var getTypeInfoFromTypeAlias = (typeAliasDec, typeMap) => {
4458
- const { type } = typeAliasDec;
4459
- const tags = extractCommentTags(typeAliasDec);
4460
- const typeInfo = getTypeInfoFromAliasType(type, typeMap);
4461
- return typeInfo ? {
4462
- ...typeInfo,
4463
- tags: {
4464
- ...tags,
4465
- ...typeInfo.tags
4466
- }
4467
- } : void 0;
4468
- };
4469
-
4470
- // src/common/TypeParsing/ParsingUtils/getPrimaryFieldForTypeInfo.ts
4471
- var getPrimaryFieldForTypeInfo = (typeInfo) => {
4472
- const { fields } = typeInfo;
4473
- let primaryField = void 0, primaryFieldReadDenied = false;
4474
- for (const fieldName in fields) {
4475
- const field = fields[fieldName];
4476
- const {
4477
- tags: {
4478
- primaryField: isPrimaryField = false,
4479
- deniedOperations: { READ: readDenied = false } = {}
4480
- } = {}
4481
- } = field;
4482
- if (isPrimaryField || !primaryField) {
4483
- primaryField = fieldName;
4484
- primaryFieldReadDenied = readDenied;
4659
+ };
4660
+ /**
4661
+ * Update a @{@link BaseFileItem}.
4662
+ * @param uniqueIdentifier Unique identifier value for the file.
4663
+ * @param item Partial update payload for the file.
4664
+ * @returns True when the item was updated.
4665
+ * */
4666
+ updateItem = async (uniqueIdentifier, item) => {
4667
+ const { directory, name } = item;
4668
+ const { tableName } = this.config;
4669
+ const { bucketName } = this.specificConfig;
4670
+ const oldItemLoc = getBaseFileLocationInfo(uniqueIdentifier);
4671
+ const { name: oldName, directory: oldDirectory } = oldItemLoc;
4672
+ if (name && (name !== oldName || directory !== oldDirectory)) {
4673
+ await this.s3.send(
4674
+ new CopyObjectCommand({
4675
+ Bucket: bucketName,
4676
+ Key: getFullFileKey({
4677
+ file: {
4678
+ directory,
4679
+ name
4680
+ },
4681
+ baseDirectory: tableName
4682
+ }),
4683
+ CopySource: getFullFileKey({
4684
+ file: oldItemLoc,
4685
+ baseDirectory: tableName
4686
+ })
4687
+ })
4688
+ );
4689
+ await this.s3FileDriver.deleteFile(oldItemLoc, tableName);
4485
4690
  }
4486
- if (isPrimaryField) {
4487
- break;
4691
+ await this.readItem(uniqueIdentifier);
4692
+ return true;
4693
+ };
4694
+ /**
4695
+ * Delete a @{@link BaseFileItem} by its id.
4696
+ * @param id Unique identifier value for the file.
4697
+ * @returns True when the item was deleted.
4698
+ */
4699
+ deleteItem = async (id) => {
4700
+ const { tableName } = this.config;
4701
+ if (typeof id === "undefined") {
4702
+ throw new Error("MISSING_ID" /* MISSING_ID */);
4703
+ } else {
4704
+ await this.readItem(id);
4705
+ await this.s3FileDriver.deleteFile(
4706
+ getBaseFileLocationInfo(id),
4707
+ tableName
4708
+ );
4488
4709
  }
4489
- }
4490
- if (primaryFieldReadDenied) {
4491
- throw new Error(
4492
- "READ_DENIED_PRIMARY_FIELD_NOT_SUPPORTED" /* READ_DENIED_PRIMARY_FIELD_NOT_SUPPORTED */
4710
+ return true;
4711
+ };
4712
+ /**
4713
+ * List @{@link BaseFileItem}s by a given criteria.
4714
+ * @param config List configuration and criteria.
4715
+ * @param selectFields Optional fields to select from each file item.
4716
+ * @returns List results with items and cursor.
4717
+ */
4718
+ listItems = async (config, selectFields) => {
4719
+ const { tableName } = this.config;
4720
+ const {
4721
+ itemsPerPage = Infinity,
4722
+ cursor,
4723
+ sortFields = [],
4724
+ criteria
4725
+ } = config;
4726
+ const { files: baseFileList = [], cursor: newCursor } = await this.s3FileDriver.listFiles(
4727
+ void 0,
4728
+ tableName,
4729
+ itemsPerPage,
4730
+ cursor
4493
4731
  );
4732
+ const currentFileItems = baseFileList.map((bF) => ({
4733
+ id: getFullFileKey({
4734
+ file: bF
4735
+ }),
4736
+ ...bF
4737
+ }));
4738
+ const filteredFiles = criteria ? getFilterTypeInfoDataItemsBySearchCriteria(
4739
+ criteria,
4740
+ currentFileItems
4741
+ ) : currentFileItems;
4742
+ const expandedFiles = [];
4743
+ for (const fF of filteredFiles) {
4744
+ expandedFiles.push({
4745
+ ...fF,
4746
+ uploadUrl: selectFields?.includes("uploadUrl") ? await this.s3FileDriver.getFileUploadUrl(fF, tableName) : void 0,
4747
+ downloadUrl: selectFields?.includes("downloadUrl") ? await this.s3FileDriver.getFileDownloadUrl(fF, tableName) : void 0
4748
+ });
4749
+ }
4750
+ return {
4751
+ items: getSortedItems(
4752
+ sortFields,
4753
+ expandedFiles
4754
+ ),
4755
+ cursor: newCursor
4756
+ };
4757
+ };
4758
+ };
4759
+ var S3SupportedFileItemDBDriverEntry = {
4760
+ /**
4761
+ * @param config Driver configuration.
4762
+ * @returns S3 file driver instance.
4763
+ */
4764
+ factory: (config) => {
4765
+ return new S3FileItemDBDriver(config);
4766
+ },
4767
+ /**
4768
+ * @returns Type info pack for the S3 config.
4769
+ */
4770
+ getDBSpecificConfigTypeInfo: () => {
4771
+ return {
4772
+ entryTypeName: "S3SpecificConfig",
4773
+ typeInfoMap: ConfigTypeInfoMap_default
4774
+ };
4494
4775
  }
4495
- return primaryField;
4496
4776
  };
4497
4777
 
4498
- // src/common/TypeParsing/TypeParsing.ts
4499
- var getTypeInfoMapFromTypeScript = (source) => {
4500
- const typeScriptNode = createSourceFile(
4501
- "x.ts",
4502
- source,
4503
- ScriptTarget.Latest,
4504
- true
4505
- );
4506
- const typeMap = convertASTToMap(typeScriptNode, {});
4507
- const typeInfoMap = {};
4508
- for (const key in typeMap) {
4509
- const typeAliasDec = typeMap[key];
4510
- const { modifiers } = typeAliasDec;
4511
- let outputTypeInfo = false;
4512
- if (modifiers) {
4513
- modifiers.forEach((modifier) => {
4514
- const { kind } = modifier;
4515
- if (kind === SyntaxKind.ExportKeyword) {
4516
- outputTypeInfo = true;
4778
+ // src/api/ORM/drivers/DynamoDBDataItemDBDriver/ConfigTypeInfoMap.json
4779
+ var ConfigTypeInfoMap_default2 = {
4780
+ Logger: {
4781
+ fields: {
4782
+ trace: {
4783
+ type: "string",
4784
+ array: false,
4785
+ readonly: false,
4786
+ optional: true,
4787
+ possibleValues: [],
4788
+ tags: {}
4789
+ },
4790
+ debug: {
4791
+ type: "string",
4792
+ array: false,
4793
+ readonly: false,
4794
+ optional: false,
4795
+ typeReference: "Trace",
4796
+ tags: {}
4797
+ },
4798
+ info: {
4799
+ type: "string",
4800
+ array: false,
4801
+ readonly: false,
4802
+ optional: false,
4803
+ typeReference: "Trace",
4804
+ tags: {}
4805
+ },
4806
+ warn: {
4807
+ type: "string",
4808
+ array: false,
4809
+ readonly: false,
4810
+ optional: false,
4811
+ typeReference: "Trace",
4812
+ tags: {}
4813
+ },
4814
+ error: {
4815
+ type: "string",
4816
+ array: false,
4817
+ readonly: false,
4818
+ optional: false,
4819
+ typeReference: "Trace",
4820
+ tags: {}
4821
+ }
4822
+ },
4823
+ tags: {},
4824
+ primaryField: "trace"
4825
+ },
4826
+ Endpoint: {
4827
+ fields: {
4828
+ protocol: {
4829
+ type: "string",
4830
+ array: false,
4831
+ readonly: false,
4832
+ optional: false,
4833
+ tags: {}
4834
+ },
4835
+ hostname: {
4836
+ type: "string",
4837
+ array: false,
4838
+ readonly: false,
4839
+ optional: false,
4840
+ tags: {}
4841
+ },
4842
+ port: {
4843
+ type: "string",
4844
+ array: false,
4845
+ readonly: false,
4846
+ optional: true,
4847
+ tags: {}
4848
+ },
4849
+ path: {
4850
+ type: "string",
4851
+ array: false,
4852
+ readonly: false,
4853
+ optional: false,
4854
+ tags: {}
4855
+ },
4856
+ query: {
4857
+ type: "string",
4858
+ array: false,
4859
+ readonly: false,
4860
+ optional: true,
4861
+ tags: {}
4862
+ }
4863
+ },
4864
+ tags: {},
4865
+ primaryField: "protocol"
4866
+ },
4867
+ RetryStrategy: {
4868
+ fields: {
4869
+ mode: {
4870
+ type: "string",
4871
+ array: false,
4872
+ readonly: false,
4873
+ optional: true,
4874
+ tags: {}
4875
+ },
4876
+ retry: {
4877
+ type: "string",
4878
+ array: false,
4879
+ readonly: false,
4880
+ optional: false,
4881
+ tags: {}
4882
+ }
4883
+ },
4884
+ tags: {},
4885
+ primaryField: "mode"
4886
+ },
4887
+ DynamoDBSpecificConfig: {
4888
+ fields: {
4889
+ requestHandler: {
4890
+ type: "string",
4891
+ array: false,
4892
+ readonly: false,
4893
+ optional: true,
4894
+ tags: {}
4895
+ },
4896
+ apiVersion: {
4897
+ type: "string",
4898
+ array: false,
4899
+ readonly: false,
4900
+ optional: true,
4901
+ tags: {}
4902
+ },
4903
+ sha256: {
4904
+ type: "string",
4905
+ array: false,
4906
+ readonly: false,
4907
+ optional: true,
4908
+ tags: {}
4909
+ },
4910
+ urlParser: {
4911
+ type: "string",
4912
+ array: false,
4913
+ readonly: false,
4914
+ optional: true,
4915
+ tags: {}
4916
+ },
4917
+ bodyLengthChecker: {
4918
+ type: "string",
4919
+ array: false,
4920
+ readonly: false,
4921
+ optional: true,
4922
+ tags: {}
4923
+ },
4924
+ streamCollector: {
4925
+ type: "string",
4926
+ array: false,
4927
+ readonly: false,
4928
+ optional: true,
4929
+ tags: {}
4930
+ },
4931
+ base64Decoder: {
4932
+ type: "string",
4933
+ array: false,
4934
+ readonly: false,
4935
+ optional: true,
4936
+ tags: {}
4937
+ },
4938
+ base64Encoder: {
4939
+ type: "string",
4940
+ array: false,
4941
+ readonly: false,
4942
+ optional: true,
4943
+ tags: {}
4944
+ },
4945
+ utf8Decoder: {
4946
+ type: "string",
4947
+ array: false,
4948
+ readonly: false,
4949
+ optional: true,
4950
+ tags: {}
4951
+ },
4952
+ utf8Encoder: {
4953
+ type: "string",
4954
+ array: false,
4955
+ readonly: false,
4956
+ optional: true,
4957
+ tags: {}
4958
+ },
4959
+ runtime: {
4960
+ type: "string",
4961
+ array: false,
4962
+ readonly: false,
4963
+ optional: true,
4964
+ tags: {}
4965
+ },
4966
+ disableHostPrefix: {
4967
+ type: "string",
4968
+ array: false,
4969
+ readonly: false,
4970
+ optional: true,
4971
+ possibleValues: [],
4972
+ tags: {}
4973
+ },
4974
+ serviceId: {
4975
+ type: "string",
4976
+ array: false,
4977
+ readonly: false,
4978
+ optional: true,
4979
+ tags: {}
4980
+ },
4981
+ useDualstackEndpoint: {
4982
+ type: "string",
4983
+ array: false,
4984
+ readonly: false,
4985
+ optional: true,
4986
+ possibleValues: [],
4987
+ tags: {}
4988
+ },
4989
+ useFipsEndpoint: {
4990
+ type: "string",
4991
+ array: false,
4992
+ readonly: false,
4993
+ optional: true,
4994
+ possibleValues: [],
4995
+ tags: {}
4996
+ },
4997
+ defaultUserAgentProvider: {
4998
+ type: "string",
4999
+ array: false,
5000
+ readonly: false,
5001
+ optional: true,
5002
+ tags: {}
5003
+ },
5004
+ region: {
5005
+ type: "string",
5006
+ array: false,
5007
+ readonly: false,
5008
+ optional: true,
5009
+ tags: {}
5010
+ },
5011
+ credentialDefaultProvider: {
5012
+ type: "string",
5013
+ array: false,
5014
+ readonly: false,
5015
+ optional: true,
5016
+ tags: {}
5017
+ },
5018
+ maxAttempts: {
5019
+ type: "string",
5020
+ array: false,
5021
+ readonly: false,
5022
+ optional: true,
5023
+ tags: {}
5024
+ },
5025
+ retryMode: {
5026
+ type: "string",
5027
+ array: false,
5028
+ readonly: false,
5029
+ optional: true,
5030
+ tags: {}
5031
+ },
5032
+ logger: {
5033
+ type: "string",
5034
+ array: false,
5035
+ readonly: false,
5036
+ optional: true,
5037
+ possibleValues: [],
5038
+ tags: {}
5039
+ },
5040
+ extensions: {
5041
+ type: "string",
5042
+ array: false,
5043
+ readonly: false,
5044
+ optional: true,
5045
+ tags: {}
5046
+ },
5047
+ defaultsMode: {
5048
+ type: "string",
5049
+ array: false,
5050
+ readonly: false,
5051
+ optional: true,
5052
+ possibleValues: [
5053
+ "standard",
5054
+ "in-region",
5055
+ "cross-region",
5056
+ "mobile",
5057
+ "auto",
5058
+ "legacy"
5059
+ ],
5060
+ tags: {
5061
+ allowCustomSelection: true
4517
5062
  }
4518
- });
4519
- }
4520
- if (outputTypeInfo) {
4521
- const typeInfo = getTypeInfoFromTypeAlias(typeAliasDec, typeMap);
4522
- if (typeInfo) {
4523
- typeInfoMap[key] = {
4524
- ...typeInfo,
4525
- primaryField: getPrimaryFieldForTypeInfo(typeInfo)
4526
- };
5063
+ },
5064
+ endpointDiscoveryEnabledProvider: {
5065
+ type: "string",
5066
+ array: false,
5067
+ readonly: false,
5068
+ optional: true,
5069
+ tags: {}
5070
+ },
5071
+ endpoint: {
5072
+ type: "string",
5073
+ array: false,
5074
+ readonly: false,
5075
+ optional: true,
5076
+ possibleValues: [],
5077
+ tags: {}
5078
+ },
5079
+ endpointProvider: {
5080
+ type: "string",
5081
+ array: false,
5082
+ readonly: false,
5083
+ optional: true,
5084
+ tags: {}
5085
+ },
5086
+ tls: {
5087
+ type: "string",
5088
+ array: false,
5089
+ readonly: false,
5090
+ optional: true,
5091
+ possibleValues: [],
5092
+ tags: {}
5093
+ },
5094
+ retryStrategy: {
5095
+ type: "string",
5096
+ array: false,
5097
+ readonly: false,
5098
+ optional: true,
5099
+ possibleValues: [],
5100
+ tags: {}
5101
+ },
5102
+ customUserAgent: {
5103
+ type: "string",
5104
+ array: false,
5105
+ readonly: false,
5106
+ optional: true,
5107
+ tags: {}
5108
+ },
5109
+ httpAuthSchemes: {
5110
+ type: "string",
5111
+ array: false,
5112
+ readonly: false,
5113
+ optional: true,
5114
+ tags: {}
5115
+ },
5116
+ httpAuthSchemeProvider: {
5117
+ type: "string",
5118
+ array: false,
5119
+ readonly: false,
5120
+ optional: true,
5121
+ tags: {}
5122
+ },
5123
+ credentials: {
5124
+ type: "string",
5125
+ array: false,
5126
+ readonly: false,
5127
+ optional: true,
5128
+ tags: {}
5129
+ },
5130
+ signer: {
5131
+ type: "string",
5132
+ array: false,
5133
+ readonly: false,
5134
+ optional: true,
5135
+ tags: {}
5136
+ },
5137
+ signingEscapePath: {
5138
+ type: "string",
5139
+ array: false,
5140
+ readonly: false,
5141
+ optional: true,
5142
+ possibleValues: [],
5143
+ tags: {}
5144
+ },
5145
+ systemClockOffset: {
5146
+ type: "string",
5147
+ array: false,
5148
+ readonly: false,
5149
+ optional: true,
5150
+ tags: {}
5151
+ },
5152
+ signingRegion: {
5153
+ type: "string",
5154
+ array: false,
5155
+ readonly: false,
5156
+ optional: true,
5157
+ tags: {}
5158
+ },
5159
+ signerConstructor: {
5160
+ type: "string",
5161
+ array: false,
5162
+ readonly: false,
5163
+ optional: true,
5164
+ tags: {}
5165
+ },
5166
+ endpointCacheSize: {
5167
+ type: "string",
5168
+ array: false,
5169
+ readonly: false,
5170
+ optional: true,
5171
+ tags: {}
5172
+ },
5173
+ endpointDiscoveryEnabled: {
5174
+ type: "string",
5175
+ array: false,
5176
+ readonly: false,
5177
+ optional: true,
5178
+ possibleValues: [],
5179
+ tags: {}
4527
5180
  }
4528
- }
5181
+ },
5182
+ tags: {},
5183
+ primaryField: "requestHandler"
4529
5184
  }
4530
- return typeInfoMap;
4531
5185
  };
4532
5186
 
4533
- // src/common/TypeParsing/Validation.ts
4534
- var INVALID_CUSTOM_TYPE = "INVALID_CUSTOM_TYPE";
4535
- var PRIMITIVE_ERROR_MESSAGE_CONSTANTS = {
4536
- string: "NOT_A_STRING",
4537
- number: "NOT_A_NUMBER",
4538
- boolean: "NOT_A_BOOLEAN"
4539
- };
4540
- var ERROR_MESSAGE_CONSTANTS = {
4541
- MISSING: "MISSING",
4542
- INVALID_OPTION: "INVALID_OPTION",
4543
- INVALID_FIELD: "INVALID_FIELD",
4544
- RELATIONSHIP_VALUES_ARE_STRICTLY_EXCLUDED: "RELATIONSHIP_VALUES_ARE_STRICTLY_EXCLUDED",
4545
- INVALID_TYPE: "INVALID_TYPE",
4546
- NO_UNION_TYPE_MATCHED: "NO_UNION_TYPE_MATCHED",
4547
- TYPE_DOES_NOT_EXIST: "TYPE_DOES_NOT_EXIST",
4548
- INVALID_PATTERN: "INVALID_PATTERN",
4549
- VALUE_DOES_NOT_MATCH_PATTERN: "VALUE_DOES_NOT_MATCH_PATTERN"
5187
+ // src/api/ORM/drivers/DynamoDBDataItemDBDriver.ts
5188
+ typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
5189
+ var DynamoDBOperatorMappings = {
5190
+ ["EQUALS" /* EQUALS */]: (fieldName) => `#${fieldName} = :${fieldName}`,
5191
+ ["NOT_EQUALS" /* NOT_EQUALS */]: (fieldName) => `#${fieldName} <> :${fieldName}`,
5192
+ ["GREATER_THAN" /* GREATER_THAN */]: (fieldName) => `#${fieldName} > :${fieldName}`,
5193
+ ["GREATER_THAN_OR_EQUAL" /* GREATER_THAN_OR_EQUAL */]: (fieldName) => `#${fieldName} >= :${fieldName}`,
5194
+ ["LESS_THAN" /* LESS_THAN */]: (fieldName) => `#${fieldName} < :${fieldName}`,
5195
+ ["LESS_THAN_OR_EQUAL" /* LESS_THAN_OR_EQUAL */]: (fieldName) => `#${fieldName} <= :${fieldName}`,
5196
+ ["IN" /* IN */]: (fieldName) => `#${fieldName} IN (:${fieldName})`,
5197
+ ["LIKE" /* LIKE */]: (fieldName) => `contains(#${fieldName}, :${fieldName})`,
5198
+ ["EXISTS" /* EXISTS */]: (fieldName) => `attribute_exists(#${fieldName})`,
5199
+ ["NOT_EXISTS" /* NOT_EXISTS */]: (fieldName) => `attribute_not_exists(#${fieldName})`,
5200
+ ["IS_EMPTY" /* IS_EMPTY */]: (fieldName) => `size(#${fieldName}) = 0`,
5201
+ ["IS_NOT_EMPTY" /* IS_NOT_EMPTY */]: (fieldName) => `size(#${fieldName}) > 0`,
5202
+ ["BETWEEN" /* BETWEEN */]: (fieldName) => `#${fieldName} BETWEEN :${fieldName}_start AND :${fieldName}_end`,
5203
+ ["CONTAINS" /* CONTAINS */]: (fieldName) => `contains(#${fieldName}, :${fieldName})`,
5204
+ ["STARTS_WITH" /* STARTS_WITH */]: (fieldName) => `begins_with(#${fieldName}, :${fieldName})`
4550
5205
  };
4551
- var DENIED_TYPE_OPERATIONS = {
4552
- CREATE: "DENIED_TYPE_OPERATION_CREATE",
4553
- READ: "DENIED_TYPE_OPERATION_READ",
4554
- UPDATE: "DENIED_TYPE_OPERATION_UPDATE",
4555
- DELETE: "DENIED_TYPE_OPERATION_DELETE"
5206
+ var DynamoDBLogicalOperatorMappings = {
5207
+ ["AND" /* AND */]: "AND",
5208
+ ["OR" /* OR */]: "OR"
4556
5209
  };
4557
- var validateValueMatchesPattern = (typeName, value, pattern) => {
4558
- const results = {
4559
- typeName,
4560
- valid: true,
4561
- error: "",
4562
- errorMap: {}
4563
- };
4564
- {
4565
- try {
4566
- const regex = new RegExp(pattern);
4567
- const testResult = typeof value === "string" && regex.test(value);
4568
- if (!testResult) {
4569
- results.valid = false;
4570
- results.error = ERROR_MESSAGE_CONSTANTS.VALUE_DOES_NOT_MATCH_PATTERN;
5210
+ var createFilterExpression = (fieldCriteria, logicalOperator) => {
5211
+ let output = {};
5212
+ if (fieldCriteria && fieldCriteria.length > 0) {
5213
+ const expressions = [];
5214
+ const attributeNames = {};
5215
+ const attributeValues = {};
5216
+ for (const criterion of fieldCriteria) {
5217
+ const { fieldName, operator, value } = criterion;
5218
+ const createExpression = DynamoDBOperatorMappings[operator];
5219
+ if (!createExpression) {
5220
+ throw {
5221
+ message: "SEARCH_COMPARISON_OPERATOR_NOT_SUPPORTED" /* SEARCH_COMPARISON_OPERATOR_NOT_SUPPORTED */,
5222
+ operator,
5223
+ fieldName
5224
+ };
4571
5225
  }
4572
- } catch (e) {
4573
- results.valid = false;
4574
- results.error = ERROR_MESSAGE_CONSTANTS.INVALID_PATTERN;
5226
+ expressions.push(createExpression(fieldName));
5227
+ attributeNames[`#${fieldName}`] = fieldName;
5228
+ attributeValues[`:${fieldName}`] = value;
4575
5229
  }
5230
+ output = {
5231
+ FilterExpression: expressions.join(
5232
+ ` ${DynamoDBLogicalOperatorMappings[logicalOperator]} `
5233
+ ),
5234
+ ExpressionAttributeNames: attributeNames,
5235
+ ExpressionAttributeValues: marshall(attributeValues)
5236
+ };
4576
5237
  }
4577
- return results;
4578
- };
4579
- var getValidityValue = (existing, pending) => !existing ? false : pending;
4580
- var TYPE_KEYWORD_VALIDATORS = {
4581
- string: (value) => typeof value === "string",
4582
- number: (value) => typeof value === "number",
4583
- boolean: (value) => typeof value === "boolean"
4584
- };
4585
- var hasValue = (value) => value ?? false;
4586
- var validateKeywordType = (value, type) => {
4587
- const validator = TYPE_KEYWORD_VALIDATORS[type];
4588
- let valid = true;
4589
- if (validator) {
4590
- valid = validator(value);
4591
- }
4592
- return valid;
5238
+ return output;
4593
5239
  };
4594
- var validateCustomType = (value, customType, customValidators) => {
4595
- let valid = true;
4596
- if (customValidators && customType) {
4597
- const validator = customValidators[customType];
4598
- if (validator) {
4599
- try {
4600
- valid = validator(value);
4601
- } catch (e) {
4602
- valid = false;
4603
- }
5240
+ var buildUpdateExpression = (updatedItem, uniquelyIdentifyingFieldName) => {
5241
+ const updateExpressionParts = [];
5242
+ const attributeNames = {};
5243
+ const attributeValues = {};
5244
+ for (const f in updatedItem) {
5245
+ const value = updatedItem[f];
5246
+ if (f !== uniquelyIdentifyingFieldName && typeof value !== "undefined") {
5247
+ const placeholderName = `#${f}`;
5248
+ const placeholderValue = `:${f}`;
5249
+ updateExpressionParts.push(`${placeholderName} = ${placeholderValue}`);
5250
+ attributeNames[placeholderName] = f;
5251
+ attributeValues[placeholderValue] = marshall(value);
4604
5252
  }
4605
5253
  }
4606
- return valid;
4607
- };
4608
- var validateTypeInfoFieldValue = (value, typeInfoField, typeInfoMap, ignoreArray = false, strict = false, customValidators, typeOperation, relationshipValidationType = "STRICT_EXCLUDE" /* STRICT_EXCLUDE */, itemIsPartial) => {
4609
- const {
4610
- type,
4611
- typeReference,
4612
- array,
4613
- optional,
4614
- possibleValues,
4615
- tags: { customType, constraints: { pattern = void 0 } = {} } = {}
4616
- } = typeInfoField;
4617
- const results = {
4618
- typeName: typeReference ?? type,
4619
- valid: true,
4620
- error: "",
4621
- errorMap: {}
5254
+ return {
5255
+ UpdateExpression: `SET ${updateExpressionParts.join(", ")}`,
5256
+ ExpressionAttributeNames: attributeNames,
5257
+ ExpressionAttributeValues: attributeValues
4622
5258
  };
4623
- const requiredValueAllowed = !typeReference || relationshipValidationType === "INCLUDE" /* INCLUDE */;
4624
- if (requiredValueAllowed && !itemIsPartial && !optional && !hasValue(value)) {
4625
- results.valid = false;
4626
- results.error = ERROR_MESSAGE_CONSTANTS.MISSING;
4627
- } else if (array && !ignoreArray) {
4628
- const {
4629
- valid: validArray,
4630
- error: arrayError,
4631
- errorMap: arrayErrorMap
4632
- } = validateArrayOfTypeInfoFieldValues(
4633
- value,
4634
- typeInfoField,
4635
- typeInfoMap,
4636
- strict,
4637
- customValidators,
4638
- typeOperation,
4639
- relationshipValidationType,
4640
- itemIsPartial
5259
+ };
5260
+ var buildSelectedFieldParams = (selectedFields) => {
5261
+ const selectedFieldParams = typeof (selectedFields ?? false) && Array.isArray(selectedFields) ? {
5262
+ ExpressionAttributeNames: selectedFields.reduce(
5263
+ (acc, field) => {
5264
+ const fieldAsString = String(field);
5265
+ acc[`#${fieldAsString}`] = fieldAsString;
5266
+ return acc;
5267
+ },
5268
+ {}
5269
+ ),
5270
+ ProjectionExpression: selectedFields.map((field) => `#${String(field)}`).join(", ")
5271
+ } : {};
5272
+ return selectedFieldParams;
5273
+ };
5274
+ var DynamoDBDataItemDBDriver = class {
5275
+ /**
5276
+ * @param config Driver configuration including DynamoDB client settings.
5277
+ */
5278
+ constructor(config) {
5279
+ this.config = config;
5280
+ const { dbSpecificConfig } = config;
5281
+ this.dynamoDBClient = new DynamoDBClient(
5282
+ dbSpecificConfig
4641
5283
  );
4642
- results.valid = getValidityValue(results.valid, validArray);
4643
- results.error = arrayError;
4644
- results.errorMap = arrayErrorMap;
4645
- } else {
4646
- if (typeReference) {
4647
- if (relationshipValidationType === "INCLUDE" /* INCLUDE */) {
4648
- const {
4649
- valid: validTypeInfo,
4650
- error: typeInfoError,
4651
- errorMap: typeInfoErrorMap
4652
- } = validateTypeInfoValue(
4653
- value,
4654
- typeReference,
4655
- typeInfoMap,
4656
- strict,
4657
- customValidators,
4658
- typeOperation,
4659
- relationshipValidationType,
4660
- itemIsPartial
4661
- );
4662
- results.valid = getValidityValue(results.valid, validTypeInfo);
4663
- results.error = typeInfoError;
4664
- results.errorMap = typeInfoErrorMap;
4665
- } else if (relationshipValidationType === "STRICT_EXCLUDE" /* STRICT_EXCLUDE */) {
4666
- const valueSupplied = typeof value !== "undefined";
4667
- if (valueSupplied) {
4668
- results.valid = false;
4669
- results.error = ERROR_MESSAGE_CONSTANTS.RELATIONSHIP_VALUES_ARE_STRICTLY_EXCLUDED;
4670
- }
4671
- } else if (relationshipValidationType === "EXCLUDE" /* EXCLUDE */) {
4672
- results.valid = getValidityValue(results.valid, true);
4673
- }
4674
- } else if (possibleValues && !possibleValues.includes(value)) {
4675
- results.valid = false;
4676
- results.error = ERROR_MESSAGE_CONSTANTS.INVALID_OPTION;
5284
+ }
5285
+ dynamoDBClient;
5286
+ /**
5287
+ * Create an item in the database.
5288
+ * @returns Generated identifier for the created item.
5289
+ */
5290
+ createItem = async (newItem) => {
5291
+ const {
5292
+ tableName,
5293
+ uniquelyIdentifyingFieldName,
5294
+ generateUniqueIdentifier = () => v4()
5295
+ } = this.config;
5296
+ const newItemId = generateUniqueIdentifier(newItem);
5297
+ const cleanNewItemWithId = {
5298
+ ...newItem,
5299
+ [uniquelyIdentifyingFieldName]: newItemId
5300
+ };
5301
+ const command = new PutItemCommand({
5302
+ TableName: tableName,
5303
+ Item: marshall(cleanNewItemWithId)
5304
+ });
5305
+ await this.dynamoDBClient.send(command);
5306
+ return newItemId;
5307
+ };
5308
+ /**
5309
+ * Read an item from the database.
5310
+ * @returns Item payload (partial when selected fields are used).
5311
+ */
5312
+ readItem = async (uniqueIdentifier, selectedFields) => {
5313
+ const { tableName, uniquelyIdentifyingFieldName } = this.config;
5314
+ const selectedFieldParams = buildSelectedFieldParams(selectedFields);
5315
+ const command = new GetItemCommand({
5316
+ TableName: tableName,
5317
+ Key: marshall({
5318
+ [uniquelyIdentifyingFieldName]: uniqueIdentifier
5319
+ }),
5320
+ ...selectedFieldParams
5321
+ });
5322
+ const { Item } = await this.dynamoDBClient.send(command);
5323
+ if (typeof Item === "undefined") {
5324
+ throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
4677
5325
  } else {
4678
- const pendingValid = validateKeywordType(value, type);
4679
- const customValid = validateCustomType(
4680
- value,
4681
- customType,
4682
- customValidators
4683
- );
4684
- results.valid = getValidityValue(results.valid, pendingValid);
4685
- results.valid = getValidityValue(results.valid, customValid);
4686
- if (type === "string" && typeof pattern === "string") {
4687
- const { valid: patternValid, error: patternError } = validateValueMatchesPattern(value, pattern);
4688
- results.valid = getValidityValue(results.valid, patternValid);
4689
- results.error = patternError;
4690
- }
4691
- if (!customValid) {
4692
- results.error = INVALID_CUSTOM_TYPE;
4693
- } else if (!results.valid) {
4694
- results.error = results.error ? results.error : PRIMITIVE_ERROR_MESSAGE_CONSTANTS[type];
4695
- }
5326
+ const cleanItem = unmarshall(Item);
5327
+ return cleanItem;
4696
5328
  }
4697
- }
4698
- return results;
4699
- };
4700
- var validateArrayOfTypeInfoFieldValues = (values = [], typeInfoField, typeInfoMap, strict = false, customValidators, typeOperation, relationshipValidationType, itemIsPartial) => {
4701
- const { type, typeReference } = typeInfoField;
4702
- const results = {
4703
- typeName: typeReference ?? type,
4704
- valid: true,
4705
- error: "",
4706
- errorMap: {}
4707
5329
  };
4708
- for (let i = 0; i < values.length; i++) {
4709
- const v = values[i];
5330
+ /**
5331
+ * Update an item in the database.
5332
+ * @returns True when an item was updated.
5333
+ */
5334
+ updateItem = async (uniqueIdentifier, updatedItem) => {
5335
+ const { tableName, uniquelyIdentifyingFieldName } = this.config;
4710
5336
  const {
4711
- valid: indexValid,
4712
- error: indexError = "",
4713
- errorMap: indexErrorMap
4714
- } = validateTypeInfoFieldValue(
4715
- v,
4716
- typeInfoField,
4717
- typeInfoMap,
4718
- true,
4719
- strict,
4720
- customValidators,
4721
- typeOperation,
4722
- relationshipValidationType,
4723
- itemIsPartial
4724
- );
4725
- results.valid = getValidityValue(results.valid, indexValid);
4726
- results.errorMap[getPathString([i])] = [indexError];
4727
- for (const er in indexErrorMap) {
4728
- results.errorMap[getPathString([i, er])] = indexErrorMap[er];
5337
+ [uniquelyIdentifyingFieldName]: _unusedUniqueIdentifier,
5338
+ ...cleanUpdatedItem
5339
+ } = updatedItem;
5340
+ if (typeof uniqueIdentifier !== "undefined") {
5341
+ const command = new UpdateItemCommand({
5342
+ TableName: tableName,
5343
+ Key: marshall({
5344
+ [uniquelyIdentifyingFieldName]: uniqueIdentifier
5345
+ }),
5346
+ ReturnValues: "ALL_NEW",
5347
+ ...buildUpdateExpression(
5348
+ cleanUpdatedItem,
5349
+ uniquelyIdentifyingFieldName
5350
+ )
5351
+ });
5352
+ const { Attributes } = await this.dynamoDBClient.send(command);
5353
+ return !!Attributes;
5354
+ } else {
5355
+ throw {
5356
+ message: "MISSING_UNIQUE_IDENTIFIER" /* MISSING_UNIQUE_IDENTIFIER */,
5357
+ uniquelyIdentifyingFieldName
5358
+ };
4729
5359
  }
4730
- }
4731
- return results;
4732
- };
4733
- var validateTypeInfoFieldOperationAllowed = (fieldName, fieldOperation, typeInfoField) => {
4734
- const results = {
4735
- typeName: null,
4736
- valid: true,
4737
- error: "",
4738
- errorMap: {}
4739
5360
  };
4740
- if (fieldOperation && typeInfoField) {
5361
+ /**
5362
+ * Delete an item from the database.
5363
+ * @returns True when an item was deleted.
5364
+ */
5365
+ deleteItem = async (uniqueIdentifier) => {
5366
+ const { tableName, uniquelyIdentifyingFieldName } = this.config;
5367
+ const command = new DeleteItemCommand({
5368
+ TableName: tableName,
5369
+ Key: marshall({
5370
+ [uniquelyIdentifyingFieldName]: uniqueIdentifier
5371
+ }),
5372
+ ReturnValues: "ALL_OLD"
5373
+ });
5374
+ const { Attributes } = await this.dynamoDBClient.send(command);
5375
+ return !!Attributes;
5376
+ };
5377
+ /**
5378
+ * List items from the database.
5379
+ * @returns List results with items and cursor.
5380
+ */
5381
+ listItems = async (config, selectedFields) => {
5382
+ const { tableName } = this.config;
4741
5383
  const {
4742
- type,
4743
- typeReference,
4744
- tags = {}
4745
- } = typeInfoField || {};
4746
- const { deniedOperations: { [fieldOperation]: denied = false } = {} } = tags;
4747
- results.typeName = typeReference ?? type;
4748
- results.valid = !denied;
4749
- if (!results.valid) {
4750
- results.error = DENIED_TYPE_OPERATIONS[fieldOperation];
4751
- results.errorMap[fieldName] = [results.error];
5384
+ itemsPerPage = 10,
5385
+ cursor,
5386
+ sortFields,
5387
+ criteria: {
5388
+ logicalOperator = "AND" /* AND */,
5389
+ fieldCriteria = []
5390
+ } = {}
5391
+ } = config;
5392
+ const {
5393
+ ProjectionExpression,
5394
+ ExpressionAttributeNames: selectFieldParamsAttributeNames
5395
+ } = buildSelectedFieldParams(selectedFields);
5396
+ const {
5397
+ FilterExpression,
5398
+ ExpressionAttributeNames,
5399
+ ExpressionAttributeValues
5400
+ } = createFilterExpression(fieldCriteria, logicalOperator);
5401
+ const params = {
5402
+ TableName: tableName,
5403
+ Select: selectedFields && selectedFields.length > 0 ? "SPECIFIC_ATTRIBUTES" : "ALL_ATTRIBUTES",
5404
+ ...ProjectionExpression ? {
5405
+ ProjectionExpression
5406
+ } : {},
5407
+ ...FilterExpression ? {
5408
+ FilterExpression
5409
+ } : {},
5410
+ ...FilterExpression ? {
5411
+ ExpressionAttributeNames: {
5412
+ ...selectFieldParamsAttributeNames,
5413
+ ...ExpressionAttributeNames
5414
+ }
5415
+ } : ProjectionExpression ? {
5416
+ ExpressionAttributeNames: {
5417
+ ...selectFieldParamsAttributeNames
5418
+ }
5419
+ } : {},
5420
+ ...FilterExpression ? {
5421
+ ExpressionAttributeValues
5422
+ } : {}
5423
+ };
5424
+ let structuredCursor = void 0;
5425
+ if (typeof cursor === "string") {
5426
+ try {
5427
+ structuredCursor = marshall(JSON.parse(cursor));
5428
+ } catch (error) {
5429
+ throw {
5430
+ message: "INVALID_CURSOR" /* INVALID_CURSOR */,
5431
+ cursor
5432
+ };
5433
+ }
4752
5434
  }
5435
+ const command = new ScanCommand({
5436
+ ...params,
5437
+ ExclusiveStartKey: structuredCursor,
5438
+ Limit: itemsPerPage
5439
+ });
5440
+ const { Items = [], LastEvaluatedKey } = await this.dynamoDBClient.send(command);
5441
+ const unmarshalledItems = Items.map((item) => unmarshall(item));
5442
+ const sortedItems = getSortedItems(sortFields, unmarshalledItems);
5443
+ return {
5444
+ items: sortedItems,
5445
+ cursor: LastEvaluatedKey ? JSON.stringify(unmarshall(LastEvaluatedKey)) : void 0
5446
+ };
5447
+ };
5448
+ };
5449
+ var DynamoDBSupportedDataItemDBDriverEntry = {
5450
+ /**
5451
+ * @param config Driver configuration.
5452
+ * @returns DynamoDB-backed driver instance.
5453
+ */
5454
+ factory: (config) => {
5455
+ return new DynamoDBDataItemDBDriver(config);
5456
+ },
5457
+ /**
5458
+ * @returns Type info pack for the DynamoDB-specific config.
5459
+ */
5460
+ getDBSpecificConfigTypeInfo: () => {
5461
+ return {
5462
+ entryTypeName: "DynamoDBSpecificConfig",
5463
+ typeInfoMap: ConfigTypeInfoMap_default2
5464
+ };
4753
5465
  }
4754
- return results;
4755
5466
  };
4756
- var validateTypeOperationAllowed = (typeName, valueFields, typeOperation, typeInfo) => {
4757
- const results = {
4758
- typeName,
4759
- valid: true,
4760
- error: "",
4761
- errorMap: {}
4762
- };
4763
- const { fields = {}, tags = {} } = typeInfo;
4764
- const { deniedOperations: { [typeOperation]: denied = false } = {} } = tags;
4765
- if (denied) {
4766
- results.valid = false;
4767
- results.error = DENIED_TYPE_OPERATIONS[typeOperation];
4768
- } else {
4769
- for (const vF of valueFields) {
4770
- const vFieldInfo = fields[vF];
4771
- const { valid: vFValid, error: vFError } = validateTypeInfoFieldOperationAllowed(vF, typeOperation, vFieldInfo);
4772
- results.valid = getValidityValue(results.valid, vFValid);
4773
- if (!vFValid) {
4774
- results.errorMap[vF] = [vFError];
4775
- }
5467
+
5468
+ // src/api/ORM/drivers/InMemoryDataItemDBDriver/ConfigTypeInfoMap.json
5469
+ var ConfigTypeInfoMap_default3 = {
5470
+ InMemorySpecificConfig: {
5471
+ fields: {},
5472
+ tags: {}
5473
+ }
5474
+ };
5475
+
5476
+ // src/api/ORM/drivers/InMemoryDataItemDBDriver.ts
5477
+ typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
5478
+ var decodeCursor2 = (cursor) => {
5479
+ if (!cursor) {
5480
+ return 0;
5481
+ }
5482
+ try {
5483
+ const parsed = JSON.parse(cursor);
5484
+ const offset = parsed.offset ?? 0;
5485
+ if (!Number.isFinite(offset) || offset < 0) {
5486
+ throw new Error("Invalid cursor offset.");
4776
5487
  }
5488
+ return offset;
5489
+ } catch (_error) {
5490
+ throw {
5491
+ message: "INVALID_CURSOR" /* INVALID_CURSOR */,
5492
+ cursor
5493
+ };
4777
5494
  }
4778
- return results;
4779
5495
  };
4780
- var validateTypeInfoValue = (value, typeInfoFullName, typeInfoMap, strict = false, customValidators, typeOperation, relationshipValidationType, itemIsPartial) => {
4781
- const typeInfo = typeInfoMap[typeInfoFullName];
4782
- const results = {
4783
- typeName: typeInfoFullName,
4784
- valid: !!typeInfo,
4785
- error: !!typeInfo ? "" : ERROR_MESSAGE_CONSTANTS.TYPE_DOES_NOT_EXIST,
4786
- errorMap: {}
4787
- };
4788
- if (typeInfo) {
4789
- const { primaryField, fields, unionFieldSets } = typeInfo;
4790
- if (typeOperation) {
4791
- const valueFields = typeof value === "object" ? Object.keys(value ?? {}) : [];
4792
- const {
4793
- valid: operationValid,
4794
- error: operationError,
4795
- errorMap: operationErrorMap
4796
- } = validateTypeOperationAllowed(
4797
- typeInfoFullName,
4798
- valueFields,
4799
- typeOperation,
4800
- typeInfo
4801
- );
4802
- results.valid = getValidityValue(results.valid, operationValid);
4803
- results.error = operationError;
4804
- for (const oE in operationErrorMap) {
4805
- const existingError = results.errorMap[oE] ?? [];
4806
- results.errorMap[oE] = existingError ? [...existingError, ...operationErrorMap[oE]] : operationErrorMap[oE];
4807
- }
4808
- if (!operationValid && operationError) {
4809
- results.error = operationError;
4810
- }
5496
+ var encodeCursor2 = (offset) => JSON.stringify({ offset });
5497
+ var selectFieldsFromItem = (item, selectedFields) => {
5498
+ if (!selectedFields || selectedFields.length === 0) {
5499
+ return { ...item };
5500
+ }
5501
+ return selectedFields.reduce((accumulator, field) => {
5502
+ if (field in item) {
5503
+ accumulator[field] = item[field];
4811
5504
  }
4812
- if (unionFieldSets) {
4813
- const valueFields = Object.keys(value || {});
4814
- let valid = false;
4815
- for (const uFS of unionFieldSets) {
4816
- valid = valueFields.every((vF) => uFS.includes(vF));
4817
- if (valid) {
4818
- break;
4819
- }
4820
- }
4821
- if (!valid) {
4822
- results.valid = false;
4823
- results.error = ERROR_MESSAGE_CONSTANTS.NO_UNION_TYPE_MATCHED;
4824
- }
4825
- } else if (strict) {
4826
- const knownFields = Object.keys(fields || {});
4827
- const valueFields = Object.keys(value || {});
4828
- for (const vF of valueFields) {
4829
- if (!knownFields.includes(vF)) {
4830
- results.valid = false;
4831
- results.errorMap[vF] = [ERROR_MESSAGE_CONSTANTS.INVALID_FIELD];
4832
- }
4833
- }
4834
- }
4835
- if (fields) {
4836
- for (const key in fields) {
4837
- if (typeOperation !== "CREATE" /* CREATE */ || typeof primaryField !== "string" || key !== primaryField) {
4838
- const typeInfoField = fields[key];
4839
- const fieldValue = value[key];
4840
- const {
4841
- valid: fieldValid,
4842
- error: fieldError,
4843
- errorMap: fieldErrorMap
4844
- } = validateTypeInfoFieldValue(
4845
- fieldValue,
4846
- typeInfoField,
4847
- typeInfoMap,
4848
- false,
4849
- strict,
4850
- customValidators,
4851
- typeOperation,
4852
- relationshipValidationType,
4853
- itemIsPartial
4854
- );
4855
- results.valid = getValidityValue(results.valid, fieldValid);
4856
- results.errorMap[key] = [fieldError];
4857
- for (const fE in fieldErrorMap) {
4858
- results.errorMap[getPathString([key, fE])] = fieldErrorMap[fE];
4859
- }
4860
- }
4861
- }
4862
- }
4863
- if (!results.valid && !results.error) {
4864
- results.error = ERROR_MESSAGE_CONSTANTS.INVALID_TYPE;
4865
- }
4866
- }
4867
- return results;
5505
+ return accumulator;
5506
+ }, {});
4868
5507
  };
4869
-
4870
- // src/api/ORM/drivers/S3FileItemDBDriver.ts
4871
- var moduleDirname = typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
4872
- var S3FileItemDBDriver = class {
4873
- /**
4874
- * @param config Driver configuration including S3 settings.
4875
- */
5508
+ var InMemoryDataItemDBDriver = class {
4876
5509
  constructor(config) {
4877
5510
  this.config = config;
4878
- const { dbSpecificConfig } = config;
4879
- const { s3Config, bucketName, urlExpirationInSeconds } = dbSpecificConfig;
4880
- this.specificConfig = dbSpecificConfig;
4881
- this.s3 = new S3(s3Config);
4882
- this.s3FileDriver = new S3FileDriver({
4883
- s3Config,
4884
- bucketName,
4885
- urlExpirationInSeconds
4886
- });
4887
5511
  }
4888
- specificConfig;
4889
- s3;
4890
- s3FileDriver;
5512
+ items = /* @__PURE__ */ new Map();
4891
5513
  /**
4892
- * Create a new @{@link BaseFileItem}.
4893
- * @param item New file item payload without the id field.
4894
- * @returns Generated file id.
4895
- * */
4896
- createItem = async (item) => {
4897
- const { tableName } = this.config;
4898
- const { bucketName } = this.specificConfig;
4899
- await this.s3.send(
4900
- new PutObjectCommand({
4901
- Bucket: bucketName,
4902
- Key: getFullFileKey({
4903
- file: item,
4904
- // SECURITY: `baseDirectory` is only used internally here, and not as part of the `id`.
4905
- baseDirectory: tableName
4906
- }),
4907
- Body: ""
4908
- })
5514
+ * Create a new item in memory.
5515
+ * @param newItem New item payload without the identifying field.
5516
+ * @returns Generated identifier for the created item.
5517
+ */
5518
+ createItem = async (newItem) => {
5519
+ const {
5520
+ uniquelyIdentifyingFieldName,
5521
+ generateUniqueIdentifier = () => v4()
5522
+ } = this.config;
5523
+ const newItemId = generateUniqueIdentifier(
5524
+ newItem
4909
5525
  );
4910
- return getFullFileKey({
4911
- file: item
4912
- });
5526
+ const cleanNewItemWithId = {
5527
+ ...newItem,
5528
+ [uniquelyIdentifyingFieldName]: newItemId
5529
+ };
5530
+ this.items.set(newItemId, { ...cleanNewItemWithId });
5531
+ return newItemId;
4913
5532
  };
4914
5533
  /**
4915
- * Read a @{@link BaseFileItem} by its id.
4916
- * @param id Unique identifier value for the file.
4917
- * @param selectFields Optional fields to select from the file item.
4918
- * @returns File item payload (partial when selected fields are used).
4919
- * */
4920
- readItem = async (id, selectFields) => {
4921
- const { tableName } = this.config;
4922
- const { bucketName } = this.specificConfig;
4923
- if (typeof id === "undefined") {
5534
+ * Read an item from memory.
5535
+ * @param uniqueIdentifier Unique identifier value for the item.
5536
+ * @param selectedFields Optional fields to select from the item.
5537
+ * @returns Item payload (partial when selected fields are used).
5538
+ */
5539
+ readItem = async (uniqueIdentifier, selectedFields) => {
5540
+ if (typeof uniqueIdentifier === "undefined") {
4924
5541
  throw new Error("MISSING_ID" /* MISSING_ID */);
4925
- } else {
4926
- const itemLoc = getBaseFileLocationInfo(id);
4927
- const {
4928
- ContentType = "",
4929
- ContentLength = 0,
4930
- LastModified} = await this.s3.send(
4931
- new HeadObjectCommand({
4932
- Bucket: bucketName,
4933
- Key: getFullFileKey({
4934
- file: itemLoc,
4935
- baseDirectory: tableName
4936
- })
4937
- })
4938
- );
4939
- const item = {
4940
- ...itemLoc,
4941
- id,
4942
- updatedOn: LastModified?.getTime() || 0,
4943
- mimeType: ContentType,
4944
- sizeInBytes: ContentLength,
4945
- isDirectory: ContentType === "application/x-directory",
4946
- uploadUrl: selectFields && selectFields.includes("uploadUrl") ? await this.s3FileDriver.getFileUploadUrl(itemLoc, tableName) : void 0,
4947
- downloadUrl: selectFields && selectFields.includes("downloadUrl") ? await this.s3FileDriver.getFileDownloadUrl(itemLoc, tableName) : void 0
4948
- };
4949
- return item;
4950
5542
  }
5543
+ const item = this.items.get(uniqueIdentifier);
5544
+ if (!item) {
5545
+ throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
5546
+ }
5547
+ return selectFieldsFromItem(item, selectedFields);
4951
5548
  };
4952
5549
  /**
4953
- * Update a @{@link BaseFileItem}.
4954
- * @param uniqueIdentifier Unique identifier value for the file.
4955
- * @param item Partial update payload for the file.
5550
+ * Update an item in memory.
5551
+ * @param uniqueIdentifier Unique identifier value for the item.
5552
+ * @param updatedItem Partial update payload for the item.
4956
5553
  * @returns True when the item was updated.
4957
- * */
4958
- updateItem = async (uniqueIdentifier, item) => {
4959
- const { directory, name } = item;
4960
- const { tableName } = this.config;
4961
- const { bucketName } = this.specificConfig;
4962
- const oldItemLoc = getBaseFileLocationInfo(uniqueIdentifier);
4963
- const { name: oldName, directory: oldDirectory } = oldItemLoc;
4964
- if (name && (name !== oldName || directory !== oldDirectory)) {
4965
- await this.s3.send(
4966
- new CopyObjectCommand({
4967
- Bucket: bucketName,
4968
- Key: getFullFileKey({
4969
- file: {
4970
- directory,
4971
- name
4972
- },
4973
- baseDirectory: tableName
4974
- }),
4975
- CopySource: getFullFileKey({
4976
- file: oldItemLoc,
4977
- baseDirectory: tableName
4978
- })
4979
- })
4980
- );
4981
- await this.s3FileDriver.deleteFile(oldItemLoc, tableName);
5554
+ */
5555
+ updateItem = async (uniqueIdentifier, updatedItem) => {
5556
+ const { uniquelyIdentifyingFieldName } = this.config;
5557
+ if (typeof uniqueIdentifier === "undefined") {
5558
+ throw {
5559
+ message: "MISSING_UNIQUE_IDENTIFIER" /* MISSING_UNIQUE_IDENTIFIER */,
5560
+ uniquelyIdentifyingFieldName
5561
+ };
4982
5562
  }
4983
- await this.readItem(uniqueIdentifier);
5563
+ const existing = this.items.get(uniqueIdentifier);
5564
+ const cleanUpdatedItem = { ...updatedItem };
5565
+ delete cleanUpdatedItem[uniquelyIdentifyingFieldName];
5566
+ const nextItem = {
5567
+ ...existing ?? {
5568
+ [uniquelyIdentifyingFieldName]: uniqueIdentifier
5569
+ }
5570
+ };
5571
+ for (const [key, value] of Object.entries(cleanUpdatedItem)) {
5572
+ if (typeof value !== "undefined") {
5573
+ nextItem[key] = value;
5574
+ }
5575
+ }
5576
+ this.items.set(uniqueIdentifier, nextItem);
4984
5577
  return true;
4985
5578
  };
4986
5579
  /**
4987
- * Delete a @{@link BaseFileItem} by its id.
4988
- * @param id Unique identifier value for the file.
5580
+ * Delete an item from memory.
5581
+ * @param uniqueIdentifier Unique identifier value for the item.
4989
5582
  * @returns True when the item was deleted.
4990
5583
  */
4991
- deleteItem = async (id) => {
4992
- const { tableName } = this.config;
4993
- if (typeof id === "undefined") {
5584
+ deleteItem = async (uniqueIdentifier) => {
5585
+ if (typeof uniqueIdentifier === "undefined") {
4994
5586
  throw new Error("MISSING_ID" /* MISSING_ID */);
4995
- } else {
4996
- await this.readItem(id);
4997
- await this.s3FileDriver.deleteFile(
4998
- getBaseFileLocationInfo(id),
4999
- tableName
5000
- );
5001
5587
  }
5002
- return true;
5588
+ return this.items.delete(uniqueIdentifier);
5003
5589
  };
5004
5590
  /**
5005
- * List @{@link BaseFileItem}s by a given criteria.
5591
+ * List items from memory.
5006
5592
  * @param config List configuration and criteria.
5007
- * @param selectFields Optional fields to select from each file item.
5593
+ * @param selectedFields Optional fields to select from each item.
5008
5594
  * @returns List results with items and cursor.
5009
5595
  */
5010
- listItems = async (config, selectFields) => {
5011
- const { tableName } = this.config;
5012
- const {
5013
- itemsPerPage = Infinity,
5014
- cursor,
5015
- sortFields = [],
5016
- criteria
5017
- } = config;
5018
- const { files: baseFileList = [], cursor: newCursor } = await this.s3FileDriver.listFiles(
5019
- void 0,
5020
- tableName,
5021
- itemsPerPage,
5022
- cursor
5023
- );
5024
- const currentFileItems = baseFileList.map((bF) => ({
5025
- id: getFullFileKey({
5026
- file: bF
5027
- }),
5028
- ...bF
5029
- }));
5030
- const filteredFiles = criteria ? getFilterTypeInfoDataItemsBySearchCriteria(
5596
+ listItems = async (config, selectedFields) => {
5597
+ const { itemsPerPage = 10, cursor, sortFields, criteria } = config;
5598
+ const allItems = Array.from(this.items.values());
5599
+ const filteredItems = criteria ? getFilterTypeInfoDataItemsBySearchCriteria(
5031
5600
  criteria,
5032
- currentFileItems
5033
- ) : currentFileItems;
5034
- const expandedFiles = [];
5035
- for (const fF of filteredFiles) {
5036
- expandedFiles.push({
5037
- ...fF,
5038
- uploadUrl: selectFields?.includes("uploadUrl") ? await this.s3FileDriver.getFileUploadUrl(fF, tableName) : void 0,
5039
- downloadUrl: selectFields?.includes("downloadUrl") ? await this.s3FileDriver.getFileDownloadUrl(fF, tableName) : void 0
5040
- });
5041
- }
5042
- return {
5043
- items: getSortedItems(
5044
- sortFields,
5045
- expandedFiles
5046
- ),
5047
- cursor: newCursor
5601
+ allItems
5602
+ ) : allItems;
5603
+ const sortedItems = getSortedItems(
5604
+ sortFields,
5605
+ filteredItems
5606
+ );
5607
+ const offset = decodeCursor2(cursor);
5608
+ const items = sortedItems.slice(offset, offset + itemsPerPage).map((item) => selectFieldsFromItem(item, selectedFields));
5609
+ const nextOffset = offset + itemsPerPage;
5610
+ return {
5611
+ items,
5612
+ cursor: nextOffset < sortedItems.length ? encodeCursor2(nextOffset) : void 0
5048
5613
  };
5049
5614
  };
5050
5615
  };
5051
- var S3SupportedFileItemDBDriverEntry = {
5616
+ var InMemorySupportedDataItemDBDriverEntry = {
5052
5617
  /**
5053
5618
  * @param config Driver configuration.
5054
- * @returns S3 file driver instance.
5619
+ * @returns In-memory driver instance.
5055
5620
  */
5056
5621
  factory: (config) => {
5057
- return new S3FileItemDBDriver(config);
5622
+ return new InMemoryDataItemDBDriver(config);
5058
5623
  },
5059
5624
  /**
5060
- * @returns Type info pack for the S3 config.
5625
+ * @returns Type info pack for the in-memory config.
5061
5626
  */
5062
5627
  getDBSpecificConfigTypeInfo: () => {
5063
- const configTypesPath = Path.join(
5064
- moduleDirname,
5065
- "S3FileItemDBDriver",
5066
- "ConfigTypes.ts"
5067
- );
5068
- const configTypesTS = FS.readFileSync(configTypesPath, "utf8");
5069
- const typeInfoMap = getTypeInfoMapFromTypeScript(configTypesTS);
5070
5628
  return {
5071
- entryTypeName: "S3SpecificConfig",
5072
- typeInfoMap
5629
+ entryTypeName: "InMemorySpecificConfig",
5630
+ typeInfoMap: ConfigTypeInfoMap_default3
5073
5631
  };
5074
5632
  }
5075
5633
  };
5076
- var moduleDirname2 = typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
5077
- var DynamoDBOperatorMappings = {
5078
- ["EQUALS" /* EQUALS */]: (fieldName) => `#${fieldName} = :${fieldName}`,
5079
- ["NOT_EQUALS" /* NOT_EQUALS */]: (fieldName) => `#${fieldName} <> :${fieldName}`,
5080
- ["GREATER_THAN" /* GREATER_THAN */]: (fieldName) => `#${fieldName} > :${fieldName}`,
5081
- ["GREATER_THAN_OR_EQUAL" /* GREATER_THAN_OR_EQUAL */]: (fieldName) => `#${fieldName} >= :${fieldName}`,
5082
- ["LESS_THAN" /* LESS_THAN */]: (fieldName) => `#${fieldName} < :${fieldName}`,
5083
- ["LESS_THAN_OR_EQUAL" /* LESS_THAN_OR_EQUAL */]: (fieldName) => `#${fieldName} <= :${fieldName}`,
5084
- ["IN" /* IN */]: (fieldName) => `#${fieldName} IN (:${fieldName})`,
5085
- ["LIKE" /* LIKE */]: (fieldName) => `contains(#${fieldName}, :${fieldName})`,
5086
- ["EXISTS" /* EXISTS */]: (fieldName) => `attribute_exists(#${fieldName})`,
5087
- ["NOT_EXISTS" /* NOT_EXISTS */]: (fieldName) => `attribute_not_exists(#${fieldName})`,
5088
- ["IS_EMPTY" /* IS_EMPTY */]: (fieldName) => `size(#${fieldName}) = 0`,
5089
- ["IS_NOT_EMPTY" /* IS_NOT_EMPTY */]: (fieldName) => `size(#${fieldName}) > 0`,
5090
- ["BETWEEN" /* BETWEEN */]: (fieldName) => `#${fieldName} BETWEEN :${fieldName}_start AND :${fieldName}_end`,
5091
- ["CONTAINS" /* CONTAINS */]: (fieldName) => `contains(#${fieldName}, :${fieldName})`,
5092
- ["STARTS_WITH" /* STARTS_WITH */]: (fieldName) => `begins_with(#${fieldName}, :${fieldName})`
5634
+
5635
+ // src/api/ORM/drivers/InMemoryItemRelationshipDBDriver.ts
5636
+ var buildDefaultRelationshipId = (item) => {
5637
+ const {
5638
+ fromTypeName,
5639
+ fromTypeFieldName,
5640
+ fromTypePrimaryFieldValue,
5641
+ toTypePrimaryFieldValue
5642
+ } = item;
5643
+ return [
5644
+ fromTypeName,
5645
+ fromTypeFieldName,
5646
+ fromTypePrimaryFieldValue,
5647
+ toTypePrimaryFieldValue
5648
+ ].map((value) => String(value)).join("|");
5093
5649
  };
5094
- var DynamoDBLogicalOperatorMappings = {
5095
- ["AND" /* AND */]: "AND",
5096
- ["OR" /* OR */]: "OR"
5650
+ var InMemoryItemRelationshipDBDriver = class extends InMemoryDataItemDBDriver {
5651
+ /**
5652
+ * @param config Driver configuration for relationship items.
5653
+ */
5654
+ constructor(config) {
5655
+ const generateUniqueIdentifier = config.generateUniqueIdentifier ?? buildDefaultRelationshipId;
5656
+ super({
5657
+ ...config,
5658
+ generateUniqueIdentifier
5659
+ });
5660
+ }
5097
5661
  };
5098
- var createFilterExpression = (fieldCriteria, logicalOperator) => {
5099
- let output = {};
5100
- if (fieldCriteria && fieldCriteria.length > 0) {
5101
- const expressions = [];
5102
- const attributeNames = {};
5103
- const attributeValues = {};
5104
- for (const criterion of fieldCriteria) {
5105
- const { fieldName, operator, value } = criterion;
5106
- const createExpression = DynamoDBOperatorMappings[operator];
5107
- if (!createExpression) {
5108
- throw {
5109
- message: "SEARCH_COMPARISON_OPERATOR_NOT_SUPPORTED" /* SEARCH_COMPARISON_OPERATOR_NOT_SUPPORTED */,
5110
- operator,
5111
- fieldName
5112
- };
5662
+
5663
+ // src/api/ORM/drivers/InMemoryFileItemDBDriver/ConfigTypeInfoMap.json
5664
+ var ConfigTypeInfoMap_default4 = {
5665
+ InMemoryFileSpecificConfig: {
5666
+ fields: {
5667
+ uploadUrlPrefix: {
5668
+ type: "string",
5669
+ array: false,
5670
+ readonly: false,
5671
+ optional: true,
5672
+ tags: {}
5673
+ },
5674
+ downloadUrlPrefix: {
5675
+ type: "string",
5676
+ array: false,
5677
+ readonly: false,
5678
+ optional: true,
5679
+ tags: {}
5113
5680
  }
5114
- expressions.push(createExpression(fieldName));
5115
- attributeNames[`#${fieldName}`] = fieldName;
5116
- attributeValues[`:${fieldName}`] = value;
5117
- }
5118
- output = {
5119
- FilterExpression: expressions.join(
5120
- ` ${DynamoDBLogicalOperatorMappings[logicalOperator]} `
5121
- ),
5122
- ExpressionAttributeNames: attributeNames,
5123
- ExpressionAttributeValues: marshall(attributeValues)
5124
- };
5681
+ },
5682
+ tags: {},
5683
+ primaryField: "uploadUrlPrefix"
5125
5684
  }
5126
- return output;
5127
5685
  };
5128
- var buildUpdateExpression = (updatedItem, uniquelyIdentifyingFieldName) => {
5129
- const updateExpressionParts = [];
5130
- const attributeNames = {};
5131
- const attributeValues = {};
5132
- for (const f in updatedItem) {
5133
- const value = updatedItem[f];
5134
- if (f !== uniquelyIdentifyingFieldName && typeof value !== "undefined") {
5135
- const placeholderName = `#${f}`;
5136
- const placeholderValue = `:${f}`;
5137
- updateExpressionParts.push(`${placeholderName} = ${placeholderValue}`);
5138
- attributeNames[placeholderName] = f;
5139
- attributeValues[placeholderValue] = marshall(value);
5686
+
5687
+ // src/api/ORM/drivers/InMemoryFileItemDBDriver.ts
5688
+ typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
5689
+ var decodeCursor3 = (cursor) => {
5690
+ if (!cursor) {
5691
+ return 0;
5692
+ }
5693
+ try {
5694
+ const parsed = JSON.parse(cursor);
5695
+ const offset = parsed.offset ?? 0;
5696
+ if (!Number.isFinite(offset) || offset < 0) {
5697
+ throw new Error("Invalid cursor offset.");
5140
5698
  }
5699
+ return offset;
5700
+ } catch (_error) {
5701
+ throw {
5702
+ message: "INVALID_CURSOR" /* INVALID_CURSOR */,
5703
+ cursor
5704
+ };
5141
5705
  }
5142
- return {
5143
- UpdateExpression: `SET ${updateExpressionParts.join(", ")}`,
5144
- ExpressionAttributeNames: attributeNames,
5145
- ExpressionAttributeValues: attributeValues
5146
- };
5147
5706
  };
5148
- var buildSelectedFieldParams = (selectedFields) => {
5149
- const selectedFieldParams = typeof (selectedFields ?? false) && Array.isArray(selectedFields) ? {
5150
- ExpressionAttributeNames: selectedFields.reduce(
5151
- (acc, field) => {
5152
- const fieldAsString = String(field);
5153
- acc[`#${fieldAsString}`] = fieldAsString;
5154
- return acc;
5155
- },
5156
- {}
5157
- ),
5158
- ProjectionExpression: selectedFields.map((field) => `#${String(field)}`).join(", ")
5159
- } : {};
5160
- return selectedFieldParams;
5707
+ var encodeCursor3 = (offset) => JSON.stringify({ offset });
5708
+ var selectFieldsFromItem2 = (item, selectedFields) => {
5709
+ if (!selectedFields || selectedFields.length === 0) {
5710
+ return { ...item };
5711
+ }
5712
+ return selectedFields.reduce((accumulator, field) => {
5713
+ if (field in item) {
5714
+ accumulator[String(field)] = item[field];
5715
+ }
5716
+ return accumulator;
5717
+ }, {});
5161
5718
  };
5162
- var DynamoDBDataItemDBDriver = class {
5163
- /**
5164
- * @param config Driver configuration including DynamoDB client settings.
5165
- */
5719
+ var InMemoryFileItemDBDriver = class {
5166
5720
  constructor(config) {
5167
5721
  this.config = config;
5168
- const { dbSpecificConfig } = config;
5169
- this.dynamoDBClient = new DynamoDBClient(
5170
- dbSpecificConfig
5171
- );
5722
+ const specific = config.dbSpecificConfig ?? {};
5723
+ this.now = specific.now ?? (() => Date.now());
5724
+ this.uploadUrlPrefix = specific.uploadUrlPrefix ?? "memory://upload/";
5725
+ this.downloadUrlPrefix = specific.downloadUrlPrefix ?? "memory://download/";
5726
+ }
5727
+ items = /* @__PURE__ */ new Map();
5728
+ aliases = /* @__PURE__ */ new Map();
5729
+ now;
5730
+ uploadUrlPrefix;
5731
+ downloadUrlPrefix;
5732
+ resolveId(id) {
5733
+ return this.aliases.get(id) ?? id;
5734
+ }
5735
+ buildUrl(prefix, id) {
5736
+ const { tableName } = this.config;
5737
+ return `${prefix}${tableName}/${id}`;
5172
5738
  }
5173
- dynamoDBClient;
5174
5739
  /**
5175
- * Create an item in the database.
5176
- * @returns Generated identifier for the created item.
5740
+ * Create a new file item in memory.
5741
+ * @returns Generated file id.
5177
5742
  */
5178
- createItem = async (newItem) => {
5179
- const {
5180
- tableName,
5181
- uniquelyIdentifyingFieldName,
5182
- generateUniqueIdentifier = () => v4()
5183
- } = this.config;
5184
- const newItemId = generateUniqueIdentifier(newItem);
5185
- const cleanNewItemWithId = {
5186
- ...newItem,
5187
- [uniquelyIdentifyingFieldName]: newItemId
5743
+ createItem = async (item) => {
5744
+ const { generateUniqueIdentifier } = this.config;
5745
+ if (!item?.name) {
5746
+ throw new Error("MISSING_ID" /* MISSING_ID */);
5747
+ }
5748
+ const fileLocation = {
5749
+ name: item.name,
5750
+ directory: item.directory
5188
5751
  };
5189
- const command = new PutItemCommand({
5190
- TableName: tableName,
5191
- Item: marshall(cleanNewItemWithId)
5192
- });
5193
- await this.dynamoDBClient.send(command);
5194
- return newItemId;
5752
+ const id = typeof generateUniqueIdentifier === "function" ? String(generateUniqueIdentifier(item)) : getFullFileKey({ file: fileLocation });
5753
+ const mimeType = item.mimeType ?? "application/octet-stream";
5754
+ const newItem = {
5755
+ id,
5756
+ name: item.name,
5757
+ directory: item.directory,
5758
+ updatedOn: this.now(),
5759
+ mimeType,
5760
+ sizeInBytes: item.sizeInBytes ?? 0,
5761
+ isDirectory: item.isDirectory ?? mimeType === "application/x-directory"
5762
+ };
5763
+ this.items.set(id, { ...newItem });
5764
+ return id;
5195
5765
  };
5196
5766
  /**
5197
- * Read an item from the database.
5198
- * @returns Item payload (partial when selected fields are used).
5767
+ * Read a file item from memory.
5768
+ * @returns File item payload (partial when selected fields are used).
5199
5769
  */
5200
- readItem = async (uniqueIdentifier, selectedFields) => {
5201
- const { tableName, uniquelyIdentifyingFieldName } = this.config;
5202
- const selectedFieldParams = buildSelectedFieldParams(selectedFields);
5203
- const command = new GetItemCommand({
5204
- TableName: tableName,
5205
- Key: marshall({
5206
- [uniquelyIdentifyingFieldName]: uniqueIdentifier
5207
- }),
5208
- ...selectedFieldParams
5209
- });
5210
- const { Item } = await this.dynamoDBClient.send(command);
5211
- if (typeof Item === "undefined") {
5770
+ readItem = async (uniqueIdentifier, selectFields) => {
5771
+ if (typeof uniqueIdentifier === "undefined") {
5772
+ throw new Error("MISSING_ID" /* MISSING_ID */);
5773
+ }
5774
+ const resolvedId = this.resolveId(uniqueIdentifier);
5775
+ const item = this.items.get(resolvedId);
5776
+ if (!item) {
5212
5777
  throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
5213
- } else {
5214
- const cleanItem = unmarshall(Item);
5215
- return cleanItem;
5216
5778
  }
5779
+ const selected = selectFieldsFromItem2(item, selectFields);
5780
+ if (selectFields?.includes("uploadUrl")) {
5781
+ selected.uploadUrl = this.buildUrl(this.uploadUrlPrefix, resolvedId);
5782
+ }
5783
+ if (selectFields?.includes("downloadUrl")) {
5784
+ selected.downloadUrl = this.buildUrl(this.downloadUrlPrefix, resolvedId);
5785
+ }
5786
+ return selected;
5217
5787
  };
5218
5788
  /**
5219
- * Update an item in the database.
5220
- * @returns True when an item was updated.
5789
+ * Update a file item in memory.
5790
+ * @returns True when the item was updated.
5221
5791
  */
5222
- updateItem = async (uniqueIdentifier, updatedItem) => {
5223
- const { tableName, uniquelyIdentifyingFieldName } = this.config;
5224
- const {
5225
- [uniquelyIdentifyingFieldName]: _unusedUniqueIdentifier,
5226
- ...cleanUpdatedItem
5227
- } = updatedItem;
5228
- if (typeof uniqueIdentifier !== "undefined") {
5229
- const command = new UpdateItemCommand({
5230
- TableName: tableName,
5231
- Key: marshall({
5232
- [uniquelyIdentifyingFieldName]: uniqueIdentifier
5233
- }),
5234
- ReturnValues: "ALL_NEW",
5235
- ...buildUpdateExpression(
5236
- cleanUpdatedItem,
5237
- uniquelyIdentifyingFieldName
5238
- )
5239
- });
5240
- const { Attributes } = await this.dynamoDBClient.send(command);
5241
- return !!Attributes;
5242
- } else {
5792
+ updateItem = async (uniqueIdentifier, item) => {
5793
+ if (typeof uniqueIdentifier === "undefined") {
5243
5794
  throw {
5244
5795
  message: "MISSING_UNIQUE_IDENTIFIER" /* MISSING_UNIQUE_IDENTIFIER */,
5245
- uniquelyIdentifyingFieldName
5796
+ uniquelyIdentifyingFieldName: this.config.uniquelyIdentifyingFieldName
5246
5797
  };
5247
5798
  }
5799
+ const resolvedId = this.resolveId(uniqueIdentifier);
5800
+ const existing = this.items.get(resolvedId);
5801
+ if (!existing) {
5802
+ throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
5803
+ }
5804
+ const directory = typeof item.directory === "undefined" ? existing.directory : item.directory;
5805
+ const name = typeof item.name === "undefined" ? existing.name : item.name;
5806
+ const nextLocationId = name && (name !== existing.name || directory !== existing.directory) ? getFullFileKey({ file: { name, directory } }) : resolvedId;
5807
+ const updated = {
5808
+ ...existing,
5809
+ ...item,
5810
+ id: nextLocationId,
5811
+ name,
5812
+ directory,
5813
+ updatedOn: this.now()
5814
+ };
5815
+ if (nextLocationId !== resolvedId) {
5816
+ this.items.delete(resolvedId);
5817
+ this.items.set(nextLocationId, updated);
5818
+ this.aliases.set(uniqueIdentifier, nextLocationId);
5819
+ this.aliases.set(resolvedId, nextLocationId);
5820
+ } else {
5821
+ this.items.set(resolvedId, updated);
5822
+ }
5823
+ await this.readItem(uniqueIdentifier);
5824
+ return true;
5248
5825
  };
5249
5826
  /**
5250
- * Delete an item from the database.
5251
- * @returns True when an item was deleted.
5827
+ * Delete a file item from memory.
5828
+ * @returns True when the item was deleted.
5252
5829
  */
5253
- deleteItem = async (uniqueIdentifier) => {
5254
- const { tableName, uniquelyIdentifyingFieldName } = this.config;
5255
- const command = new DeleteItemCommand({
5256
- TableName: tableName,
5257
- Key: marshall({
5258
- [uniquelyIdentifyingFieldName]: uniqueIdentifier
5259
- }),
5260
- ReturnValues: "ALL_OLD"
5261
- });
5262
- const { Attributes } = await this.dynamoDBClient.send(command);
5263
- return !!Attributes;
5830
+ deleteItem = async (id) => {
5831
+ if (typeof id === "undefined") {
5832
+ throw new Error("MISSING_ID" /* MISSING_ID */);
5833
+ }
5834
+ await this.readItem(id);
5835
+ const resolvedId = this.resolveId(id);
5836
+ this.items.delete(resolvedId);
5837
+ this.aliases.delete(id);
5838
+ this.aliases.delete(resolvedId);
5839
+ return true;
5264
5840
  };
5265
5841
  /**
5266
- * List items from the database.
5842
+ * List file items from memory.
5267
5843
  * @returns List results with items and cursor.
5268
5844
  */
5269
- listItems = async (config, selectedFields) => {
5270
- const { tableName } = this.config;
5845
+ listItems = async (config, selectFields) => {
5271
5846
  const {
5272
- itemsPerPage = 10,
5847
+ itemsPerPage = Infinity,
5273
5848
  cursor,
5274
- sortFields,
5275
- criteria: {
5276
- logicalOperator = "AND" /* AND */,
5277
- fieldCriteria = []
5278
- } = {}
5849
+ sortFields = [],
5850
+ criteria
5279
5851
  } = config;
5280
- const {
5281
- ProjectionExpression,
5282
- ExpressionAttributeNames: selectFieldParamsAttributeNames
5283
- } = buildSelectedFieldParams(selectedFields);
5284
- const {
5285
- FilterExpression,
5286
- ExpressionAttributeNames,
5287
- ExpressionAttributeValues
5288
- } = createFilterExpression(fieldCriteria, logicalOperator);
5289
- const params = {
5290
- TableName: tableName,
5291
- Select: selectedFields && selectedFields.length > 0 ? "SPECIFIC_ATTRIBUTES" : "ALL_ATTRIBUTES",
5292
- ...ProjectionExpression ? {
5293
- ProjectionExpression
5294
- } : {},
5295
- ...FilterExpression ? {
5296
- FilterExpression
5297
- } : {},
5298
- ...FilterExpression ? {
5299
- ExpressionAttributeNames: {
5300
- ...selectFieldParamsAttributeNames,
5301
- ...ExpressionAttributeNames
5302
- }
5303
- } : ProjectionExpression ? {
5304
- ExpressionAttributeNames: {
5305
- ...selectFieldParamsAttributeNames
5306
- }
5307
- } : {},
5308
- ...FilterExpression ? {
5309
- ExpressionAttributeValues
5310
- } : {}
5311
- };
5312
- let structuredCursor = void 0;
5313
- if (typeof cursor === "string") {
5314
- try {
5315
- structuredCursor = marshall(JSON.parse(cursor));
5316
- } catch (error) {
5317
- throw {
5318
- message: "INVALID_CURSOR" /* INVALID_CURSOR */,
5319
- cursor
5320
- };
5852
+ const allItems = Array.from(this.items.values());
5853
+ const filteredItems = criteria ? getFilterTypeInfoDataItemsBySearchCriteria(
5854
+ criteria,
5855
+ allItems
5856
+ ) : allItems;
5857
+ const sortedItems = getSortedItems(
5858
+ sortFields,
5859
+ filteredItems
5860
+ );
5861
+ const offset = decodeCursor3(cursor);
5862
+ const slice = sortedItems.slice(offset, offset + itemsPerPage);
5863
+ const expandedItems = slice.map((item) => {
5864
+ const entry = { ...item };
5865
+ if (selectFields?.includes("uploadUrl")) {
5866
+ entry.uploadUrl = this.buildUrl(this.uploadUrlPrefix, item.id);
5321
5867
  }
5322
- }
5323
- const command = new ScanCommand({
5324
- ...params,
5325
- ExclusiveStartKey: structuredCursor,
5326
- Limit: itemsPerPage
5868
+ if (selectFields?.includes("downloadUrl")) {
5869
+ entry.downloadUrl = this.buildUrl(this.downloadUrlPrefix, item.id);
5870
+ }
5871
+ return selectFields ? selectFieldsFromItem2(entry, selectFields) : entry;
5327
5872
  });
5328
- const { Items = [], LastEvaluatedKey } = await this.dynamoDBClient.send(command);
5329
- const unmarshalledItems = Items.map((item) => unmarshall(item));
5330
- const sortedItems = getSortedItems(sortFields, unmarshalledItems);
5873
+ const nextOffset = offset + itemsPerPage;
5331
5874
  return {
5332
- items: sortedItems,
5333
- cursor: LastEvaluatedKey ? JSON.stringify(unmarshall(LastEvaluatedKey)) : void 0
5875
+ items: expandedItems,
5876
+ cursor: nextOffset < sortedItems.length ? encodeCursor3(nextOffset) : void 0
5334
5877
  };
5335
5878
  };
5336
5879
  };
5337
- var DynamoDBSupportedDataItemDBDriverEntry = {
5880
+ var InMemoryFileSupportedDataItemDBDriverEntry = {
5338
5881
  /**
5339
5882
  * @param config Driver configuration.
5340
- * @returns DynamoDB-backed driver instance.
5883
+ * @returns In-memory file driver instance.
5341
5884
  */
5342
5885
  factory: (config) => {
5343
- return new DynamoDBDataItemDBDriver(config);
5886
+ return new InMemoryFileItemDBDriver(config);
5344
5887
  },
5345
5888
  /**
5346
- * @returns Type info pack for the DynamoDB-specific config.
5889
+ * @returns Type info pack for the in-memory file config.
5347
5890
  */
5348
5891
  getDBSpecificConfigTypeInfo: () => {
5349
- const configTypesPath = Path.join(
5350
- moduleDirname2,
5351
- "DynamoDBDataItemDBDriver",
5352
- "ConfigTypes.ts"
5353
- );
5354
- const configTypesTS = FS.readFileSync(configTypesPath, "utf8");
5355
- const typeInfoMap = getTypeInfoMapFromTypeScript(configTypesTS);
5356
5892
  return {
5357
- entryTypeName: "DynamoDBSpecificConfig",
5358
- typeInfoMap
5893
+ entryTypeName: "InMemoryFileSpecificConfig",
5894
+ typeInfoMap: ConfigTypeInfoMap_default4
5359
5895
  };
5360
5896
  }
5361
5897
  };
5362
- var moduleDirname3 = typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
5363
- var decodeCursor2 = (cursor) => {
5364
- if (!cursor) {
5365
- return 0;
5898
+
5899
+ // src/common/ItemRelationshipInfoTypes.ts
5900
+ var ItemRelationshipInfoKeys = /* @__PURE__ */ ((ItemRelationshipInfoKeys2) => {
5901
+ ItemRelationshipInfoKeys2["fromTypeName"] = "fromTypeName";
5902
+ ItemRelationshipInfoKeys2["fromTypeFieldName"] = "fromTypeFieldName";
5903
+ ItemRelationshipInfoKeys2["fromTypePrimaryFieldValue"] = "fromTypePrimaryFieldValue";
5904
+ ItemRelationshipInfoKeys2["toTypePrimaryFieldValue"] = "toTypePrimaryFieldValue";
5905
+ return ItemRelationshipInfoKeys2;
5906
+ })(ItemRelationshipInfoKeys || {});
5907
+
5908
+ // src/api/ORM/drivers/IndexingRelationshipDriver.ts
5909
+ var defaultEncodeEntityId = (typeName, primaryFieldValue) => `${typeName}#${primaryFieldValue}`;
5910
+ var defaultDecodeEntityId = (typeName, entityId) => {
5911
+ const prefix = `${typeName}#`;
5912
+ return entityId.startsWith(prefix) ? entityId.slice(prefix.length) : entityId;
5913
+ };
5914
+ var buildRelationshipId = (edgeKey2) => `${edgeKey2.from}|${edgeKey2.relation}|${edgeKey2.to}`;
5915
+ var IndexingRelationshipDriver = class {
5916
+ /**
5917
+ * @param config Driver configuration for relation indexing.
5918
+ */
5919
+ constructor(config) {
5920
+ this.config = config;
5921
+ this.encodeEntityId = config.encodeEntityId ?? defaultEncodeEntityId;
5922
+ this.decodeEntityId = config.decodeEntityId ?? defaultDecodeEntityId;
5366
5923
  }
5367
- try {
5368
- const parsed = JSON.parse(cursor);
5369
- const offset = parsed.offset ?? 0;
5370
- if (!Number.isFinite(offset) || offset < 0) {
5371
- throw new Error("Invalid cursor offset.");
5372
- }
5373
- return offset;
5374
- } catch (_error) {
5375
- throw {
5376
- message: "INVALID_CURSOR" /* INVALID_CURSOR */,
5377
- cursor
5924
+ encodeEntityId;
5925
+ decodeEntityId;
5926
+ buildEdgeKey(relationship, toTypeName) {
5927
+ const { fromTypeName, fromTypeFieldName, fromTypePrimaryFieldValue, toTypePrimaryFieldValue } = relationship;
5928
+ const relation = this.config.relationNameFor(fromTypeName, fromTypeFieldName);
5929
+ return {
5930
+ from: this.encodeEntityId(fromTypeName, String(fromTypePrimaryFieldValue)),
5931
+ to: this.encodeEntityId(toTypeName, String(toTypePrimaryFieldValue)),
5932
+ relation
5378
5933
  };
5379
5934
  }
5380
- };
5381
- var encodeCursor2 = (offset) => JSON.stringify({ offset });
5382
- var selectFieldsFromItem = (item, selectedFields) => {
5383
- if (!selectedFields || selectedFields.length === 0) {
5384
- return { ...item };
5935
+ buildRelationshipInfo(edge, origin, toTypeName) {
5936
+ const { fromTypeName, fromTypeFieldName } = origin;
5937
+ const fromTypePrimaryFieldValue = this.decodeEntityId(fromTypeName, edge.key.from);
5938
+ const toTypePrimaryFieldValue = this.decodeEntityId(toTypeName, edge.key.to);
5939
+ return {
5940
+ ["id" /* id */]: buildRelationshipId(edge.key),
5941
+ ["fromTypeName" /* fromTypeName */]: fromTypeName,
5942
+ ["fromTypeFieldName" /* fromTypeFieldName */]: fromTypeFieldName,
5943
+ ["fromTypePrimaryFieldValue" /* fromTypePrimaryFieldValue */]: fromTypePrimaryFieldValue,
5944
+ ["toTypePrimaryFieldValue" /* toTypePrimaryFieldValue */]: toTypePrimaryFieldValue
5945
+ };
5385
5946
  }
5386
- return selectedFields.reduce((accumulator, field) => {
5387
- if (field in item) {
5388
- accumulator[field] = item[field];
5389
- }
5390
- return accumulator;
5391
- }, {});
5392
- };
5393
- var InMemoryDataItemDBDriver = class {
5394
- constructor(config) {
5395
- this.config = config;
5947
+ async removeAllOutgoing(fromId, relation) {
5948
+ let cursor = void 0;
5949
+ do {
5950
+ const page = await this.config.backend.getOutgoing(fromId, relation, { limit: 100, cursor });
5951
+ await Promise.all(page.edges.map((edge) => this.config.backend.removeEdge(edge.key)));
5952
+ cursor = page.nextCursor;
5953
+ } while (cursor);
5396
5954
  }
5397
- items = /* @__PURE__ */ new Map();
5398
5955
  /**
5399
- * Create a new item in memory.
5400
- * @param newItem New item payload without the identifying field.
5401
- * @returns Generated identifier for the created item.
5402
- */
5403
- createItem = async (newItem) => {
5404
- const {
5405
- uniquelyIdentifyingFieldName,
5406
- generateUniqueIdentifier = () => v4()
5407
- } = this.config;
5408
- const newItemId = generateUniqueIdentifier(newItem);
5409
- const cleanNewItemWithId = {
5410
- ...newItem,
5411
- [uniquelyIdentifyingFieldName]: newItemId
5412
- };
5413
- this.items.set(newItemId, { ...cleanNewItemWithId });
5414
- return newItemId;
5415
- };
5416
- /**
5417
- * Read an item from memory.
5418
- * @param uniqueIdentifier Unique identifier value for the item.
5419
- * @param selectedFields Optional fields to select from the item.
5420
- * @returns Item payload (partial when selected fields are used).
5421
- */
5422
- readItem = async (uniqueIdentifier, selectedFields) => {
5423
- if (typeof uniqueIdentifier === "undefined") {
5424
- throw new Error("MISSING_ID" /* MISSING_ID */);
5425
- }
5426
- const item = this.items.get(uniqueIdentifier);
5427
- if (!item) {
5428
- throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
5429
- }
5430
- return selectFieldsFromItem(item, selectedFields);
5431
- };
5432
- /**
5433
- * Update an item in memory.
5434
- * @param uniqueIdentifier Unique identifier value for the item.
5435
- * @param updatedItem Partial update payload for the item.
5436
- * @returns True when the item was updated.
5956
+ * Create a relationship via the relational backend.
5957
+ * @returns Promise resolved once the relationship is stored.
5437
5958
  */
5438
- updateItem = async (uniqueIdentifier, updatedItem) => {
5439
- const { uniquelyIdentifyingFieldName } = this.config;
5440
- if (typeof uniqueIdentifier === "undefined") {
5441
- throw {
5442
- message: "MISSING_UNIQUE_IDENTIFIER" /* MISSING_UNIQUE_IDENTIFIER */,
5443
- uniquelyIdentifyingFieldName
5444
- };
5445
- }
5446
- const existing = this.items.get(uniqueIdentifier);
5447
- const cleanUpdatedItem = { ...updatedItem };
5448
- delete cleanUpdatedItem[uniquelyIdentifyingFieldName];
5449
- const nextItem = {
5450
- ...existing ?? {
5451
- [uniquelyIdentifyingFieldName]: uniqueIdentifier
5452
- }
5453
- };
5454
- for (const [key, value] of Object.entries(cleanUpdatedItem)) {
5455
- if (typeof value !== "undefined") {
5456
- nextItem[key] = value;
5457
- }
5959
+ async createRelationship(relationship, toTypeName, ensureSingle) {
5960
+ const edgeKey2 = this.buildEdgeKey(relationship, toTypeName);
5961
+ if (ensureSingle) {
5962
+ await this.removeAllOutgoing(edgeKey2.from, edgeKey2.relation);
5458
5963
  }
5459
- this.items.set(uniqueIdentifier, nextItem);
5460
- return true;
5461
- };
5964
+ await this.config.backend.putEdge({ key: edgeKey2 });
5965
+ }
5462
5966
  /**
5463
- * Delete an item from memory.
5464
- * @param uniqueIdentifier Unique identifier value for the item.
5465
- * @returns True when the item was deleted.
5967
+ * Delete a relationship via the relational backend.
5968
+ * @returns Promise resolved once the relationship is removed.
5466
5969
  */
5467
- deleteItem = async (uniqueIdentifier) => {
5468
- if (typeof uniqueIdentifier === "undefined") {
5469
- throw new Error("MISSING_ID" /* MISSING_ID */);
5470
- }
5471
- return this.items.delete(uniqueIdentifier);
5472
- };
5970
+ async deleteRelationship(relationship, toTypeName) {
5971
+ const edgeKey2 = this.buildEdgeKey(relationship, toTypeName);
5972
+ await this.config.backend.removeEdge(edgeKey2);
5973
+ }
5473
5974
  /**
5474
- * List items from memory.
5475
- * @param config List configuration and criteria.
5476
- * @param selectedFields Optional fields to select from each item.
5975
+ * List relationships via the relational backend.
5477
5976
  * @returns List results with items and cursor.
5478
5977
  */
5479
- listItems = async (config, selectedFields) => {
5480
- const {
5481
- itemsPerPage = 10,
5482
- cursor,
5483
- sortFields,
5484
- criteria
5485
- } = config;
5486
- const allItems = Array.from(this.items.values());
5487
- const filteredItems = criteria ? getFilterTypeInfoDataItemsBySearchCriteria(
5488
- criteria,
5489
- allItems
5490
- ) : allItems;
5491
- const sortedItems = getSortedItems(sortFields, filteredItems);
5492
- const offset = decodeCursor2(cursor);
5493
- const items = sortedItems.slice(offset, offset + itemsPerPage).map((item) => selectFieldsFromItem(item, selectedFields));
5494
- const nextOffset = offset + itemsPerPage;
5495
- return {
5496
- items,
5497
- cursor: nextOffset < sortedItems.length ? encodeCursor2(nextOffset) : void 0
5978
+ async listRelationships(config, toTypeName) {
5979
+ const { relationshipItemOrigin, itemsPerPage, cursor } = config;
5980
+ const { fromTypeName, fromTypeFieldName, fromTypePrimaryFieldValue } = relationshipItemOrigin;
5981
+ const relation = this.config.relationNameFor(fromTypeName, fromTypeFieldName);
5982
+ const fromId = this.encodeEntityId(fromTypeName, String(fromTypePrimaryFieldValue));
5983
+ const options = {
5984
+ limit: itemsPerPage,
5985
+ cursor
5498
5986
  };
5499
- };
5500
- };
5501
- var InMemorySupportedDataItemDBDriverEntry = {
5502
- /**
5503
- * @param config Driver configuration.
5504
- * @returns In-memory driver instance.
5505
- */
5506
- factory: (config) => {
5507
- return new InMemoryDataItemDBDriver(config);
5508
- },
5509
- /**
5510
- * @returns Type info pack for the in-memory config.
5511
- */
5512
- getDBSpecificConfigTypeInfo: () => {
5513
- const configTypesPath = Path.join(
5514
- moduleDirname3,
5515
- "InMemoryDataItemDBDriver",
5516
- "ConfigTypes.ts"
5987
+ const page = await this.config.backend.getOutgoing(fromId, relation, options);
5988
+ const items = page.edges.map(
5989
+ (edge) => this.buildRelationshipInfo(edge, relationshipItemOrigin, toTypeName)
5517
5990
  );
5518
- const configTypesTS = FS.readFileSync(configTypesPath, "utf8");
5519
- const typeInfoMap = getTypeInfoMapFromTypeScript(configTypesTS);
5520
5991
  return {
5521
- entryTypeName: "InMemorySpecificConfig",
5522
- typeInfoMap
5992
+ items,
5993
+ cursor: page.nextCursor
5523
5994
  };
5524
5995
  }
5525
5996
  };
5526
5997
 
5527
- // src/api/ORM/drivers/InMemoryItemRelationshipDBDriver.ts
5528
- var buildDefaultRelationshipId = (item) => {
5529
- const {
5530
- fromTypeName,
5531
- fromTypeFieldName,
5532
- fromTypePrimaryFieldValue,
5533
- toTypePrimaryFieldValue
5534
- } = item;
5535
- return [
5536
- fromTypeName,
5537
- fromTypeFieldName,
5538
- fromTypePrimaryFieldValue,
5539
- toTypePrimaryFieldValue
5540
- ].map((value) => String(value)).join("|");
5998
+ // src/api/ORM/drivers/common/SupportedTypeInfoORMDBDrivers.ts
5999
+ var SupportedTypeInfoORMDBDriverNames = /* @__PURE__ */ ((SupportedTypeInfoORMDBDriverNames2) => {
6000
+ SupportedTypeInfoORMDBDriverNames2["DYNAMO_DB_DATA_ITEM"] = "DYNAMO_DB_DATA_ITEM";
6001
+ SupportedTypeInfoORMDBDriverNames2["IN_MEMORY_DATA_ITEM"] = "IN_MEMORY_DATA_ITEM";
6002
+ SupportedTypeInfoORMDBDriverNames2["IN_MEMORY_FILE_ITEM"] = "IN_MEMORY_FILE_ITEM";
6003
+ SupportedTypeInfoORMDBDriverNames2["S3_FILE_ITEM"] = "S3_FILE_ITEM";
6004
+ return SupportedTypeInfoORMDBDriverNames2;
6005
+ })(SupportedTypeInfoORMDBDriverNames || {});
6006
+ var SUPPORTED_TYPE_INFO_ORM_DB_DRIVERS = {
6007
+ ["DYNAMO_DB_DATA_ITEM" /* DYNAMO_DB_DATA_ITEM */]: DynamoDBSupportedDataItemDBDriverEntry,
6008
+ ["IN_MEMORY_DATA_ITEM" /* IN_MEMORY_DATA_ITEM */]: InMemorySupportedDataItemDBDriverEntry,
6009
+ ["IN_MEMORY_FILE_ITEM" /* IN_MEMORY_FILE_ITEM */]: InMemoryFileSupportedDataItemDBDriverEntry,
6010
+ ["S3_FILE_ITEM" /* S3_FILE_ITEM */]: S3SupportedFileItemDBDriverEntry
5541
6011
  };
5542
- var InMemoryItemRelationshipDBDriver = class extends InMemoryDataItemDBDriver {
5543
- /**
5544
- * @param config Driver configuration for relationship items.
5545
- */
5546
- constructor(config) {
5547
- const generateUniqueIdentifier = config.generateUniqueIdentifier ?? buildDefaultRelationshipId;
5548
- super({
5549
- ...config,
5550
- generateUniqueIdentifier
5551
- });
5552
- }
6012
+
6013
+ // src/common/TypeParsing/Validation.ts
6014
+ var INVALID_CUSTOM_TYPE = "INVALID_CUSTOM_TYPE";
6015
+ var PRIMITIVE_ERROR_MESSAGE_CONSTANTS = {
6016
+ string: "NOT_A_STRING",
6017
+ number: "NOT_A_NUMBER",
6018
+ boolean: "NOT_A_BOOLEAN"
5553
6019
  };
5554
- var moduleDirname4 = typeof __dirname === "string" ? __dirname : Path.dirname(fileURLToPath(import.meta.url));
5555
- var decodeCursor3 = (cursor) => {
5556
- if (!cursor) {
5557
- return 0;
5558
- }
5559
- try {
5560
- const parsed = JSON.parse(cursor);
5561
- const offset = parsed.offset ?? 0;
5562
- if (!Number.isFinite(offset) || offset < 0) {
5563
- throw new Error("Invalid cursor offset.");
6020
+ var ERROR_MESSAGE_CONSTANTS = {
6021
+ MISSING: "MISSING",
6022
+ INVALID_OPTION: "INVALID_OPTION",
6023
+ INVALID_FIELD: "INVALID_FIELD",
6024
+ RELATIONSHIP_VALUES_ARE_STRICTLY_EXCLUDED: "RELATIONSHIP_VALUES_ARE_STRICTLY_EXCLUDED",
6025
+ INVALID_TYPE: "INVALID_TYPE",
6026
+ NO_UNION_TYPE_MATCHED: "NO_UNION_TYPE_MATCHED",
6027
+ TYPE_DOES_NOT_EXIST: "TYPE_DOES_NOT_EXIST",
6028
+ INVALID_PATTERN: "INVALID_PATTERN",
6029
+ VALUE_DOES_NOT_MATCH_PATTERN: "VALUE_DOES_NOT_MATCH_PATTERN"
6030
+ };
6031
+ var DENIED_TYPE_OPERATIONS = {
6032
+ CREATE: "DENIED_TYPE_OPERATION_CREATE",
6033
+ READ: "DENIED_TYPE_OPERATION_READ",
6034
+ UPDATE: "DENIED_TYPE_OPERATION_UPDATE",
6035
+ DELETE: "DENIED_TYPE_OPERATION_DELETE"
6036
+ };
6037
+ var validateValueMatchesPattern = (typeName, value, pattern) => {
6038
+ const results = {
6039
+ typeName,
6040
+ valid: true,
6041
+ error: "",
6042
+ errorMap: {}
6043
+ };
6044
+ {
6045
+ try {
6046
+ const regex = new RegExp(pattern);
6047
+ const testResult = typeof value === "string" && regex.test(value);
6048
+ if (!testResult) {
6049
+ results.valid = false;
6050
+ results.error = ERROR_MESSAGE_CONSTANTS.VALUE_DOES_NOT_MATCH_PATTERN;
6051
+ }
6052
+ } catch (e) {
6053
+ results.valid = false;
6054
+ results.error = ERROR_MESSAGE_CONSTANTS.INVALID_PATTERN;
5564
6055
  }
5565
- return offset;
5566
- } catch (_error) {
5567
- throw {
5568
- message: "INVALID_CURSOR" /* INVALID_CURSOR */,
5569
- cursor
5570
- };
5571
6056
  }
6057
+ return results;
5572
6058
  };
5573
- var encodeCursor3 = (offset) => JSON.stringify({ offset });
5574
- var selectFieldsFromItem2 = (item, selectedFields) => {
5575
- if (!selectedFields || selectedFields.length === 0) {
5576
- return { ...item };
5577
- }
5578
- return selectedFields.reduce((accumulator, field) => {
5579
- if (field in item) {
5580
- accumulator[String(field)] = item[field];
5581
- }
5582
- return accumulator;
5583
- }, {});
6059
+ var getValidityValue = (existing, pending) => !existing ? false : pending;
6060
+ var TYPE_KEYWORD_VALIDATORS = {
6061
+ string: (value) => typeof value === "string",
6062
+ number: (value) => typeof value === "number",
6063
+ boolean: (value) => typeof value === "boolean"
5584
6064
  };
5585
- var InMemoryFileItemDBDriver = class {
5586
- constructor(config) {
5587
- this.config = config;
5588
- const specific = config.dbSpecificConfig ?? {};
5589
- this.now = specific.now ?? (() => Date.now());
5590
- this.uploadUrlPrefix = specific.uploadUrlPrefix ?? "memory://upload/";
5591
- this.downloadUrlPrefix = specific.downloadUrlPrefix ?? "memory://download/";
6065
+ var hasValue = (value) => value ?? false;
6066
+ var validateKeywordType = (value, type) => {
6067
+ const validator = TYPE_KEYWORD_VALIDATORS[type];
6068
+ let valid = true;
6069
+ if (validator) {
6070
+ valid = validator(value);
5592
6071
  }
5593
- items = /* @__PURE__ */ new Map();
5594
- aliases = /* @__PURE__ */ new Map();
5595
- now;
5596
- uploadUrlPrefix;
5597
- downloadUrlPrefix;
5598
- resolveId(id) {
5599
- return this.aliases.get(id) ?? id;
5600
- }
5601
- buildUrl(prefix, id) {
5602
- const { tableName } = this.config;
5603
- return `${prefix}${tableName}/${id}`;
5604
- }
5605
- /**
5606
- * Create a new file item in memory.
5607
- * @returns Generated file id.
5608
- */
5609
- createItem = async (item) => {
5610
- const {
5611
- generateUniqueIdentifier
5612
- } = this.config;
5613
- if (!item?.name) {
5614
- throw new Error("MISSING_ID" /* MISSING_ID */);
5615
- }
5616
- const fileLocation = { name: item.name, directory: item.directory };
5617
- const id = typeof generateUniqueIdentifier === "function" ? String(generateUniqueIdentifier(item)) : getFullFileKey({ file: fileLocation });
5618
- const mimeType = item.mimeType ?? "application/octet-stream";
5619
- const newItem = {
5620
- id,
5621
- name: item.name,
5622
- directory: item.directory,
5623
- updatedOn: this.now(),
5624
- mimeType,
5625
- sizeInBytes: item.sizeInBytes ?? 0,
5626
- isDirectory: item.isDirectory ?? mimeType === "application/x-directory"
5627
- };
5628
- this.items.set(id, { ...newItem });
5629
- return id;
5630
- };
5631
- /**
5632
- * Read a file item from memory.
5633
- * @returns File item payload (partial when selected fields are used).
5634
- */
5635
- readItem = async (uniqueIdentifier, selectFields) => {
5636
- if (typeof uniqueIdentifier === "undefined") {
5637
- throw new Error("MISSING_ID" /* MISSING_ID */);
5638
- }
5639
- const resolvedId = this.resolveId(uniqueIdentifier);
5640
- const item = this.items.get(resolvedId);
5641
- if (!item) {
5642
- throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
5643
- }
5644
- const selected = selectFieldsFromItem2(item, selectFields);
5645
- if (selectFields?.includes("uploadUrl")) {
5646
- selected.uploadUrl = this.buildUrl(this.uploadUrlPrefix, resolvedId);
5647
- }
5648
- if (selectFields?.includes("downloadUrl")) {
5649
- selected.downloadUrl = this.buildUrl(this.downloadUrlPrefix, resolvedId);
6072
+ return valid;
6073
+ };
6074
+ var validateCustomType = (value, customType, customValidators) => {
6075
+ let valid = true;
6076
+ if (customValidators && customType) {
6077
+ const validator = customValidators[customType];
6078
+ if (validator) {
6079
+ try {
6080
+ valid = validator(value);
6081
+ } catch (e) {
6082
+ valid = false;
6083
+ }
5650
6084
  }
5651
- return selected;
6085
+ }
6086
+ return valid;
6087
+ };
6088
+ var validateTypeInfoFieldValue = (value, typeInfoField, typeInfoMap, ignoreArray = false, strict = false, customValidators, typeOperation, relationshipValidationType = "STRICT_EXCLUDE" /* STRICT_EXCLUDE */, itemIsPartial) => {
6089
+ const {
6090
+ type,
6091
+ typeReference,
6092
+ array,
6093
+ optional,
6094
+ possibleValues,
6095
+ tags: { customType, constraints: { pattern = void 0 } = {} } = {}
6096
+ } = typeInfoField;
6097
+ const results = {
6098
+ typeName: typeReference ?? type,
6099
+ valid: true,
6100
+ error: "",
6101
+ errorMap: {}
5652
6102
  };
5653
- /**
5654
- * Update a file item in memory.
5655
- * @returns True when the item was updated.
5656
- */
5657
- updateItem = async (uniqueIdentifier, item) => {
5658
- if (typeof uniqueIdentifier === "undefined") {
5659
- throw {
5660
- message: "MISSING_UNIQUE_IDENTIFIER" /* MISSING_UNIQUE_IDENTIFIER */,
5661
- uniquelyIdentifyingFieldName: this.config.uniquelyIdentifyingFieldName
5662
- };
5663
- }
5664
- const resolvedId = this.resolveId(uniqueIdentifier);
5665
- const existing = this.items.get(resolvedId);
5666
- if (!existing) {
5667
- throw new Error("ITEM_NOT_FOUND" /* ITEM_NOT_FOUND */);
5668
- }
5669
- const directory = typeof item.directory === "undefined" ? existing.directory : item.directory;
5670
- const name = typeof item.name === "undefined" ? existing.name : item.name;
5671
- const nextLocationId = name && (name !== existing.name || directory !== existing.directory) ? getFullFileKey({ file: { name, directory } }) : resolvedId;
5672
- const updated = {
5673
- ...existing,
5674
- ...item,
5675
- id: nextLocationId,
5676
- name,
5677
- directory,
5678
- updatedOn: this.now()
5679
- };
5680
- if (nextLocationId !== resolvedId) {
5681
- this.items.delete(resolvedId);
5682
- this.items.set(nextLocationId, updated);
5683
- this.aliases.set(uniqueIdentifier, nextLocationId);
5684
- this.aliases.set(resolvedId, nextLocationId);
6103
+ const requiredValueAllowed = !typeReference || relationshipValidationType === "INCLUDE" /* INCLUDE */;
6104
+ if (requiredValueAllowed && !itemIsPartial && !optional && !hasValue(value)) {
6105
+ results.valid = false;
6106
+ results.error = ERROR_MESSAGE_CONSTANTS.MISSING;
6107
+ } else if (array && !ignoreArray) {
6108
+ const {
6109
+ valid: validArray,
6110
+ error: arrayError,
6111
+ errorMap: arrayErrorMap
6112
+ } = validateArrayOfTypeInfoFieldValues(
6113
+ value,
6114
+ typeInfoField,
6115
+ typeInfoMap,
6116
+ strict,
6117
+ customValidators,
6118
+ typeOperation,
6119
+ relationshipValidationType,
6120
+ itemIsPartial
6121
+ );
6122
+ results.valid = getValidityValue(results.valid, validArray);
6123
+ results.error = arrayError;
6124
+ results.errorMap = arrayErrorMap;
6125
+ } else {
6126
+ if (typeReference) {
6127
+ if (relationshipValidationType === "INCLUDE" /* INCLUDE */) {
6128
+ const {
6129
+ valid: validTypeInfo,
6130
+ error: typeInfoError,
6131
+ errorMap: typeInfoErrorMap
6132
+ } = validateTypeInfoValue(
6133
+ value,
6134
+ typeReference,
6135
+ typeInfoMap,
6136
+ strict,
6137
+ customValidators,
6138
+ typeOperation,
6139
+ relationshipValidationType,
6140
+ itemIsPartial
6141
+ );
6142
+ results.valid = getValidityValue(results.valid, validTypeInfo);
6143
+ results.error = typeInfoError;
6144
+ results.errorMap = typeInfoErrorMap;
6145
+ } else if (relationshipValidationType === "STRICT_EXCLUDE" /* STRICT_EXCLUDE */) {
6146
+ const valueSupplied = typeof value !== "undefined";
6147
+ if (valueSupplied) {
6148
+ results.valid = false;
6149
+ results.error = ERROR_MESSAGE_CONSTANTS.RELATIONSHIP_VALUES_ARE_STRICTLY_EXCLUDED;
6150
+ }
6151
+ } else if (relationshipValidationType === "EXCLUDE" /* EXCLUDE */) {
6152
+ results.valid = getValidityValue(results.valid, true);
6153
+ }
6154
+ } else if (possibleValues && !possibleValues.includes(value)) {
6155
+ results.valid = false;
6156
+ results.error = ERROR_MESSAGE_CONSTANTS.INVALID_OPTION;
5685
6157
  } else {
5686
- this.items.set(resolvedId, updated);
6158
+ const pendingValid = validateKeywordType(value, type);
6159
+ const customValid = validateCustomType(
6160
+ value,
6161
+ customType,
6162
+ customValidators
6163
+ );
6164
+ results.valid = getValidityValue(results.valid, pendingValid);
6165
+ results.valid = getValidityValue(results.valid, customValid);
6166
+ if (type === "string" && typeof pattern === "string") {
6167
+ const { valid: patternValid, error: patternError } = validateValueMatchesPattern(value, pattern);
6168
+ results.valid = getValidityValue(results.valid, patternValid);
6169
+ results.error = patternError;
6170
+ }
6171
+ if (!customValid) {
6172
+ results.error = INVALID_CUSTOM_TYPE;
6173
+ } else if (!results.valid) {
6174
+ results.error = results.error ? results.error : PRIMITIVE_ERROR_MESSAGE_CONSTANTS[type];
6175
+ }
5687
6176
  }
5688
- await this.readItem(uniqueIdentifier);
5689
- return true;
6177
+ }
6178
+ return results;
6179
+ };
6180
+ var validateArrayOfTypeInfoFieldValues = (values = [], typeInfoField, typeInfoMap, strict = false, customValidators, typeOperation, relationshipValidationType, itemIsPartial) => {
6181
+ const { type, typeReference } = typeInfoField;
6182
+ const results = {
6183
+ typeName: typeReference ?? type,
6184
+ valid: true,
6185
+ error: "",
6186
+ errorMap: {}
5690
6187
  };
5691
- /**
5692
- * Delete a file item from memory.
5693
- * @returns True when the item was deleted.
5694
- */
5695
- deleteItem = async (id) => {
5696
- if (typeof id === "undefined") {
5697
- throw new Error("MISSING_ID" /* MISSING_ID */);
6188
+ for (let i = 0; i < values.length; i++) {
6189
+ const v = values[i];
6190
+ const {
6191
+ valid: indexValid,
6192
+ error: indexError = "",
6193
+ errorMap: indexErrorMap
6194
+ } = validateTypeInfoFieldValue(
6195
+ v,
6196
+ typeInfoField,
6197
+ typeInfoMap,
6198
+ true,
6199
+ strict,
6200
+ customValidators,
6201
+ typeOperation,
6202
+ relationshipValidationType,
6203
+ itemIsPartial
6204
+ );
6205
+ results.valid = getValidityValue(results.valid, indexValid);
6206
+ results.errorMap[getPathString([i])] = [indexError];
6207
+ for (const er in indexErrorMap) {
6208
+ results.errorMap[getPathString([i, er])] = indexErrorMap[er];
5698
6209
  }
5699
- await this.readItem(id);
5700
- const resolvedId = this.resolveId(id);
5701
- this.items.delete(resolvedId);
5702
- this.aliases.delete(id);
5703
- this.aliases.delete(resolvedId);
5704
- return true;
6210
+ }
6211
+ return results;
6212
+ };
6213
+ var validateTypeInfoFieldOperationAllowed = (fieldName, fieldOperation, typeInfoField) => {
6214
+ const results = {
6215
+ typeName: null,
6216
+ valid: true,
6217
+ error: "",
6218
+ errorMap: {}
5705
6219
  };
5706
- /**
5707
- * List file items from memory.
5708
- * @returns List results with items and cursor.
5709
- */
5710
- listItems = async (config, selectFields) => {
6220
+ if (fieldOperation && typeInfoField) {
5711
6221
  const {
5712
- itemsPerPage = Infinity,
5713
- cursor,
5714
- sortFields = [],
5715
- criteria
5716
- } = config;
5717
- const allItems = Array.from(this.items.values());
5718
- const filteredItems = criteria ? getFilterTypeInfoDataItemsBySearchCriteria(
5719
- criteria,
5720
- allItems
5721
- ) : allItems;
5722
- const sortedItems = getSortedItems(sortFields, filteredItems);
5723
- const offset = decodeCursor3(cursor);
5724
- const slice = sortedItems.slice(offset, offset + itemsPerPage);
5725
- const expandedItems = slice.map((item) => {
5726
- const entry = { ...item };
5727
- if (selectFields?.includes("uploadUrl")) {
5728
- entry.uploadUrl = this.buildUrl(this.uploadUrlPrefix, item.id);
5729
- }
5730
- if (selectFields?.includes("downloadUrl")) {
5731
- entry.downloadUrl = this.buildUrl(this.downloadUrlPrefix, item.id);
5732
- }
5733
- return selectFields ? selectFieldsFromItem2(entry, selectFields) : entry;
5734
- });
5735
- const nextOffset = offset + itemsPerPage;
5736
- return {
5737
- items: expandedItems,
5738
- cursor: nextOffset < sortedItems.length ? encodeCursor3(nextOffset) : void 0
5739
- };
5740
- };
5741
- };
5742
- var InMemoryFileSupportedDataItemDBDriverEntry = {
5743
- /**
5744
- * @param config Driver configuration.
5745
- * @returns In-memory file driver instance.
5746
- */
5747
- factory: (config) => {
5748
- return new InMemoryFileItemDBDriver(config);
5749
- },
5750
- /**
5751
- * @returns Type info pack for the in-memory file config.
5752
- */
5753
- getDBSpecificConfigTypeInfo: () => {
5754
- const configTypesPath = Path.join(
5755
- moduleDirname4,
5756
- "InMemoryFileItemDBDriver",
5757
- "ConfigTypes.ts"
5758
- );
5759
- const configTypesTS = FS.readFileSync(configTypesPath, "utf8");
5760
- const typeInfoMap = getTypeInfoMapFromTypeScript(configTypesTS);
5761
- return {
5762
- entryTypeName: "InMemoryFileSpecificConfig",
5763
- typeInfoMap
5764
- };
6222
+ type,
6223
+ typeReference,
6224
+ tags = {}
6225
+ } = typeInfoField || {};
6226
+ const { deniedOperations: { [fieldOperation]: denied = false } = {} } = tags;
6227
+ results.typeName = typeReference ?? type;
6228
+ results.valid = !denied;
6229
+ if (!results.valid) {
6230
+ results.error = DENIED_TYPE_OPERATIONS[fieldOperation];
6231
+ results.errorMap[fieldName] = [results.error];
6232
+ }
5765
6233
  }
6234
+ return results;
5766
6235
  };
5767
-
5768
- // src/common/ItemRelationshipInfoTypes.ts
5769
- var ItemRelationshipInfoKeys = /* @__PURE__ */ ((ItemRelationshipInfoKeys2) => {
5770
- ItemRelationshipInfoKeys2["fromTypeName"] = "fromTypeName";
5771
- ItemRelationshipInfoKeys2["fromTypeFieldName"] = "fromTypeFieldName";
5772
- ItemRelationshipInfoKeys2["fromTypePrimaryFieldValue"] = "fromTypePrimaryFieldValue";
5773
- ItemRelationshipInfoKeys2["toTypePrimaryFieldValue"] = "toTypePrimaryFieldValue";
5774
- return ItemRelationshipInfoKeys2;
5775
- })(ItemRelationshipInfoKeys || {});
5776
-
5777
- // src/api/ORM/drivers/IndexingRelationshipDriver.ts
5778
- var defaultEncodeEntityId = (typeName, primaryFieldValue) => `${typeName}#${primaryFieldValue}`;
5779
- var defaultDecodeEntityId = (typeName, entityId) => {
5780
- const prefix = `${typeName}#`;
5781
- return entityId.startsWith(prefix) ? entityId.slice(prefix.length) : entityId;
5782
- };
5783
- var buildRelationshipId = (edgeKey2) => `${edgeKey2.from}|${edgeKey2.relation}|${edgeKey2.to}`;
5784
- var IndexingRelationshipDriver = class {
5785
- /**
5786
- * @param config Driver configuration for relation indexing.
5787
- */
5788
- constructor(config) {
5789
- this.config = config;
5790
- this.encodeEntityId = config.encodeEntityId ?? defaultEncodeEntityId;
5791
- this.decodeEntityId = config.decodeEntityId ?? defaultDecodeEntityId;
5792
- }
5793
- encodeEntityId;
5794
- decodeEntityId;
5795
- buildEdgeKey(relationship, toTypeName) {
5796
- const { fromTypeName, fromTypeFieldName, fromTypePrimaryFieldValue, toTypePrimaryFieldValue } = relationship;
5797
- const relation = this.config.relationNameFor(fromTypeName, fromTypeFieldName);
5798
- return {
5799
- from: this.encodeEntityId(fromTypeName, String(fromTypePrimaryFieldValue)),
5800
- to: this.encodeEntityId(toTypeName, String(toTypePrimaryFieldValue)),
5801
- relation
5802
- };
5803
- }
5804
- buildRelationshipInfo(edge, origin, toTypeName) {
5805
- const { fromTypeName, fromTypeFieldName } = origin;
5806
- const fromTypePrimaryFieldValue = this.decodeEntityId(fromTypeName, edge.key.from);
5807
- const toTypePrimaryFieldValue = this.decodeEntityId(toTypeName, edge.key.to);
5808
- return {
5809
- ["id" /* id */]: buildRelationshipId(edge.key),
5810
- ["fromTypeName" /* fromTypeName */]: fromTypeName,
5811
- ["fromTypeFieldName" /* fromTypeFieldName */]: fromTypeFieldName,
5812
- ["fromTypePrimaryFieldValue" /* fromTypePrimaryFieldValue */]: fromTypePrimaryFieldValue,
5813
- ["toTypePrimaryFieldValue" /* toTypePrimaryFieldValue */]: toTypePrimaryFieldValue
5814
- };
5815
- }
5816
- async removeAllOutgoing(fromId, relation) {
5817
- let cursor = void 0;
5818
- do {
5819
- const page = await this.config.backend.getOutgoing(fromId, relation, { limit: 100, cursor });
5820
- await Promise.all(page.edges.map((edge) => this.config.backend.removeEdge(edge.key)));
5821
- cursor = page.nextCursor;
5822
- } while (cursor);
5823
- }
5824
- /**
5825
- * Create a relationship via the relational backend.
5826
- * @returns Promise resolved once the relationship is stored.
5827
- */
5828
- async createRelationship(relationship, toTypeName, ensureSingle) {
5829
- const edgeKey2 = this.buildEdgeKey(relationship, toTypeName);
5830
- if (ensureSingle) {
5831
- await this.removeAllOutgoing(edgeKey2.from, edgeKey2.relation);
6236
+ var validateTypeOperationAllowed = (typeName, valueFields, typeOperation, typeInfo) => {
6237
+ const results = {
6238
+ typeName,
6239
+ valid: true,
6240
+ error: "",
6241
+ errorMap: {}
6242
+ };
6243
+ const { fields = {}, tags = {} } = typeInfo;
6244
+ const { deniedOperations: { [typeOperation]: denied = false } = {} } = tags;
6245
+ if (denied) {
6246
+ results.valid = false;
6247
+ results.error = DENIED_TYPE_OPERATIONS[typeOperation];
6248
+ } else {
6249
+ for (const vF of valueFields) {
6250
+ const vFieldInfo = fields[vF];
6251
+ const { valid: vFValid, error: vFError } = validateTypeInfoFieldOperationAllowed(vF, typeOperation, vFieldInfo);
6252
+ results.valid = getValidityValue(results.valid, vFValid);
6253
+ if (!vFValid) {
6254
+ results.errorMap[vF] = [vFError];
6255
+ }
5832
6256
  }
5833
- await this.config.backend.putEdge({ key: edgeKey2 });
5834
- }
5835
- /**
5836
- * Delete a relationship via the relational backend.
5837
- * @returns Promise resolved once the relationship is removed.
5838
- */
5839
- async deleteRelationship(relationship, toTypeName) {
5840
- const edgeKey2 = this.buildEdgeKey(relationship, toTypeName);
5841
- await this.config.backend.removeEdge(edgeKey2);
5842
- }
5843
- /**
5844
- * List relationships via the relational backend.
5845
- * @returns List results with items and cursor.
5846
- */
5847
- async listRelationships(config, toTypeName) {
5848
- const { relationshipItemOrigin, itemsPerPage, cursor } = config;
5849
- const { fromTypeName, fromTypeFieldName, fromTypePrimaryFieldValue } = relationshipItemOrigin;
5850
- const relation = this.config.relationNameFor(fromTypeName, fromTypeFieldName);
5851
- const fromId = this.encodeEntityId(fromTypeName, String(fromTypePrimaryFieldValue));
5852
- const options = {
5853
- limit: itemsPerPage,
5854
- cursor
5855
- };
5856
- const page = await this.config.backend.getOutgoing(fromId, relation, options);
5857
- const items = page.edges.map(
5858
- (edge) => this.buildRelationshipInfo(edge, relationshipItemOrigin, toTypeName)
5859
- );
5860
- return {
5861
- items,
5862
- cursor: page.nextCursor
5863
- };
5864
6257
  }
6258
+ return results;
5865
6259
  };
5866
-
5867
- // src/api/ORM/drivers/common/SupportedTypeInfoORMDBDrivers.ts
5868
- var SupportedTypeInfoORMDBDriverNames = /* @__PURE__ */ ((SupportedTypeInfoORMDBDriverNames2) => {
5869
- SupportedTypeInfoORMDBDriverNames2["DYNAMO_DB_DATA_ITEM"] = "DYNAMO_DB_DATA_ITEM";
5870
- SupportedTypeInfoORMDBDriverNames2["IN_MEMORY_DATA_ITEM"] = "IN_MEMORY_DATA_ITEM";
5871
- SupportedTypeInfoORMDBDriverNames2["IN_MEMORY_FILE_ITEM"] = "IN_MEMORY_FILE_ITEM";
5872
- SupportedTypeInfoORMDBDriverNames2["S3_FILE_ITEM"] = "S3_FILE_ITEM";
5873
- return SupportedTypeInfoORMDBDriverNames2;
5874
- })(SupportedTypeInfoORMDBDriverNames || {});
5875
- var SUPPORTED_TYPE_INFO_ORM_DB_DRIVERS = {
5876
- ["DYNAMO_DB_DATA_ITEM" /* DYNAMO_DB_DATA_ITEM */]: DynamoDBSupportedDataItemDBDriverEntry,
5877
- ["IN_MEMORY_DATA_ITEM" /* IN_MEMORY_DATA_ITEM */]: InMemorySupportedDataItemDBDriverEntry,
5878
- ["IN_MEMORY_FILE_ITEM" /* IN_MEMORY_FILE_ITEM */]: InMemoryFileSupportedDataItemDBDriverEntry,
5879
- ["S3_FILE_ITEM" /* S3_FILE_ITEM */]: S3SupportedFileItemDBDriverEntry
6260
+ var validateTypeInfoValue = (value, typeInfoFullName, typeInfoMap, strict = false, customValidators, typeOperation, relationshipValidationType, itemIsPartial) => {
6261
+ const typeInfo = typeInfoMap[typeInfoFullName];
6262
+ const results = {
6263
+ typeName: typeInfoFullName,
6264
+ valid: !!typeInfo,
6265
+ error: !!typeInfo ? "" : ERROR_MESSAGE_CONSTANTS.TYPE_DOES_NOT_EXIST,
6266
+ errorMap: {}
6267
+ };
6268
+ if (typeInfo) {
6269
+ const { primaryField, fields, unionFieldSets } = typeInfo;
6270
+ if (typeOperation) {
6271
+ const valueFields = typeof value === "object" ? Object.keys(value ?? {}) : [];
6272
+ const {
6273
+ valid: operationValid,
6274
+ error: operationError,
6275
+ errorMap: operationErrorMap
6276
+ } = validateTypeOperationAllowed(
6277
+ typeInfoFullName,
6278
+ valueFields,
6279
+ typeOperation,
6280
+ typeInfo
6281
+ );
6282
+ results.valid = getValidityValue(results.valid, operationValid);
6283
+ results.error = operationError;
6284
+ for (const oE in operationErrorMap) {
6285
+ const existingError = results.errorMap[oE] ?? [];
6286
+ results.errorMap[oE] = existingError ? [...existingError, ...operationErrorMap[oE]] : operationErrorMap[oE];
6287
+ }
6288
+ if (!operationValid && operationError) {
6289
+ results.error = operationError;
6290
+ }
6291
+ }
6292
+ if (unionFieldSets) {
6293
+ const valueFields = Object.keys(value || {});
6294
+ let valid = false;
6295
+ for (const uFS of unionFieldSets) {
6296
+ valid = valueFields.every((vF) => uFS.includes(vF));
6297
+ if (valid) {
6298
+ break;
6299
+ }
6300
+ }
6301
+ if (!valid) {
6302
+ results.valid = false;
6303
+ results.error = ERROR_MESSAGE_CONSTANTS.NO_UNION_TYPE_MATCHED;
6304
+ }
6305
+ } else if (strict) {
6306
+ const knownFields = Object.keys(fields || {});
6307
+ const valueFields = Object.keys(value || {});
6308
+ for (const vF of valueFields) {
6309
+ if (!knownFields.includes(vF)) {
6310
+ results.valid = false;
6311
+ results.errorMap[vF] = [ERROR_MESSAGE_CONSTANTS.INVALID_FIELD];
6312
+ }
6313
+ }
6314
+ }
6315
+ if (fields) {
6316
+ for (const key in fields) {
6317
+ if (typeOperation !== "CREATE" /* CREATE */ || typeof primaryField !== "string" || key !== primaryField) {
6318
+ const typeInfoField = fields[key];
6319
+ const fieldValue = value[key];
6320
+ const {
6321
+ valid: fieldValid,
6322
+ error: fieldError,
6323
+ errorMap: fieldErrorMap
6324
+ } = validateTypeInfoFieldValue(
6325
+ fieldValue,
6326
+ typeInfoField,
6327
+ typeInfoMap,
6328
+ false,
6329
+ strict,
6330
+ customValidators,
6331
+ typeOperation,
6332
+ relationshipValidationType,
6333
+ itemIsPartial
6334
+ );
6335
+ results.valid = getValidityValue(results.valid, fieldValid);
6336
+ results.errorMap[key] = [fieldError];
6337
+ for (const fE in fieldErrorMap) {
6338
+ results.errorMap[getPathString([key, fE])] = fieldErrorMap[fE];
6339
+ }
6340
+ }
6341
+ }
6342
+ }
6343
+ if (!results.valid && !results.error) {
6344
+ results.error = ERROR_MESSAGE_CONSTANTS.INVALID_TYPE;
6345
+ }
6346
+ }
6347
+ return results;
5880
6348
  };
5881
6349
 
5882
6350
  // src/common/SearchValidation.ts