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