quidproquo-actionprocessor-node 0.0.262 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/lib/commonjs/actionProcessor/core/index.d.ts +2 -12
  2. package/lib/commonjs/actionProcessor/core/index.js +10 -25
  3. package/lib/commonjs/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.d.ts +2 -0
  4. package/lib/commonjs/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js +47 -0
  5. package/lib/commonjs/actionProcessor/core/{network/getNetworkRequestActionProcessor.d.ts → inlineFunction/index.d.ts} +1 -1
  6. package/lib/commonjs/actionProcessor/core/{error → inlineFunction}/index.js +5 -5
  7. package/lib/commonjs/actionProcessor/core/{context/getContextReadActionProcessor.d.ts → stream/getStreamCloseActionProcessor.d.ts} +1 -1
  8. package/lib/commonjs/actionProcessor/core/{context/getContextReadActionProcessor.js → stream/getStreamCloseActionProcessor.js} +8 -10
  9. package/lib/commonjs/actionProcessor/core/stream/getStreamReadActionProcessor.d.ts +2 -0
  10. package/lib/commonjs/actionProcessor/core/{math/getMathRandomNumberActionProcessor.js → stream/getStreamReadActionProcessor.js} +8 -7
  11. package/lib/commonjs/actionProcessor/core/{system → stream}/index.d.ts +1 -1
  12. package/lib/commonjs/actionProcessor/core/{system → stream}/index.js +6 -5
  13. package/lib/commonjs/actionProcessor/webserver/index.js +4 -2
  14. package/lib/commonjs/dynamicActionProcessor/file/getFileDeleteActionProcessor.js +7 -4
  15. package/lib/commonjs/dynamicActionProcessor/file/getFileExistsActionProcessor.js +10 -4
  16. package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js +1 -2
  17. package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js +1 -2
  18. package/lib/commonjs/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js +6 -9
  19. package/lib/commonjs/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js +4 -6
  20. package/lib/commonjs/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js +5 -9
  21. package/lib/commonjs/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js +4 -6
  22. package/lib/commonjs/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.d.ts +3 -0
  23. package/lib/commonjs/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js +135 -0
  24. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js +10 -3
  25. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js +4 -3
  26. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js +4 -3
  27. package/lib/commonjs/dynamicActionProcessor/file/index.js +2 -1
  28. package/lib/commonjs/dynamicActionProcessor/file/utils.d.ts +2 -1
  29. package/lib/commonjs/dynamicActionProcessor/file/utils.js +11 -1
  30. package/lib/esm/actionProcessor/core/index.d.ts +2 -12
  31. package/lib/esm/actionProcessor/core/index.js +12 -35
  32. package/lib/esm/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.d.ts +2 -0
  33. package/lib/esm/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js +32 -0
  34. package/lib/esm/actionProcessor/core/{network/getNetworkRequestActionProcessor.d.ts → inlineFunction/index.d.ts} +1 -1
  35. package/lib/esm/actionProcessor/core/inlineFunction/index.js +4 -0
  36. package/lib/{commonjs/actionProcessor/core/context/getContextListActionProcessor.d.ts → esm/actionProcessor/core/stream/getStreamCloseActionProcessor.d.ts} +1 -1
  37. package/lib/esm/actionProcessor/core/stream/getStreamCloseActionProcessor.js +10 -0
  38. package/lib/esm/actionProcessor/core/stream/getStreamReadActionProcessor.d.ts +2 -0
  39. package/lib/esm/actionProcessor/core/stream/getStreamReadActionProcessor.js +10 -0
  40. package/lib/esm/actionProcessor/core/{config → stream}/index.d.ts +1 -1
  41. package/lib/esm/actionProcessor/core/stream/index.js +6 -0
  42. package/lib/esm/actionProcessor/webserver/index.js +4 -2
  43. package/lib/esm/dynamicActionProcessor/file/getFileDeleteActionProcessor.js +8 -5
  44. package/lib/esm/dynamicActionProcessor/file/getFileExistsActionProcessor.js +11 -5
  45. package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js +2 -3
  46. package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js +2 -3
  47. package/lib/esm/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js +7 -10
  48. package/lib/esm/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js +5 -7
  49. package/lib/esm/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js +6 -10
  50. package/lib/esm/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js +5 -7
  51. package/lib/esm/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.d.ts +3 -0
  52. package/lib/esm/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js +37 -0
  53. package/lib/esm/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js +11 -4
  54. package/lib/esm/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js +5 -4
  55. package/lib/esm/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js +5 -4
  56. package/lib/esm/dynamicActionProcessor/file/index.js +2 -0
  57. package/lib/esm/dynamicActionProcessor/file/utils.d.ts +2 -1
  58. package/lib/esm/dynamicActionProcessor/file/utils.js +9 -1
  59. package/package.json +5 -9
  60. package/lib/commonjs/actionProcessor/core/claudeAi/getClaudeAiMessagesApiActionProcessor.d.ts +0 -2
  61. package/lib/commonjs/actionProcessor/core/claudeAi/getClaudeAiMessagesApiActionProcessor.js +0 -74
  62. package/lib/commonjs/actionProcessor/core/claudeAi/index.d.ts +0 -2
  63. package/lib/commonjs/actionProcessor/core/claudeAi/index.js +0 -17
  64. package/lib/commonjs/actionProcessor/core/config/getConfigGetApplicationInfoActionProcessor.d.ts +0 -2
  65. package/lib/commonjs/actionProcessor/core/config/getConfigGetApplicationInfoActionProcessor.js +0 -30
  66. package/lib/commonjs/actionProcessor/core/config/index.d.ts +0 -2
  67. package/lib/commonjs/actionProcessor/core/config/index.js +0 -17
  68. package/lib/commonjs/actionProcessor/core/context/getContextListActionProcessor.js +0 -24
  69. package/lib/commonjs/actionProcessor/core/context/index.d.ts +0 -2
  70. package/lib/commonjs/actionProcessor/core/context/index.js +0 -18
  71. package/lib/commonjs/actionProcessor/core/customActions/getCustomActionActionProcessor.d.ts +0 -2
  72. package/lib/commonjs/actionProcessor/core/customActions/getCustomActionActionProcessor.js +0 -58
  73. package/lib/commonjs/actionProcessor/core/customActions/index.d.ts +0 -1
  74. package/lib/commonjs/actionProcessor/core/customActions/index.js +0 -18
  75. package/lib/commonjs/actionProcessor/core/date/getDateNowActionProcessor.d.ts +0 -2
  76. package/lib/commonjs/actionProcessor/core/date/getDateNowActionProcessor.js +0 -24
  77. package/lib/commonjs/actionProcessor/core/date/index.d.ts +0 -2
  78. package/lib/commonjs/actionProcessor/core/date/index.js +0 -17
  79. package/lib/commonjs/actionProcessor/core/error/getErrorThrowErrorActionProcessor.d.ts +0 -2
  80. package/lib/commonjs/actionProcessor/core/error/getErrorThrowErrorActionProcessor.js +0 -24
  81. package/lib/commonjs/actionProcessor/core/error/index.d.ts +0 -2
  82. package/lib/commonjs/actionProcessor/core/guid/getGuidNewActionProcessor.d.ts +0 -2
  83. package/lib/commonjs/actionProcessor/core/guid/getGuidNewActionProcessor.js +0 -25
  84. package/lib/commonjs/actionProcessor/core/guid/getGuidNewSortableActionProcessor.d.ts +0 -2
  85. package/lib/commonjs/actionProcessor/core/guid/getGuidNewSortableActionProcessor.js +0 -25
  86. package/lib/commonjs/actionProcessor/core/guid/index.d.ts +0 -2
  87. package/lib/commonjs/actionProcessor/core/guid/index.js +0 -18
  88. package/lib/commonjs/actionProcessor/core/log/getLogCreateActionProcessor.d.ts +0 -2
  89. package/lib/commonjs/actionProcessor/core/log/getLogCreateActionProcessor.js +0 -30
  90. package/lib/commonjs/actionProcessor/core/log/getLogDisableEventHistoryActionProcessor.d.ts +0 -2
  91. package/lib/commonjs/actionProcessor/core/log/getLogDisableEventHistoryActionProcessor.js +0 -25
  92. package/lib/commonjs/actionProcessor/core/log/getLogTemplateLiteralActionProcessor.d.ts +0 -2
  93. package/lib/commonjs/actionProcessor/core/log/getLogTemplateLiteralActionProcessor.js +0 -26
  94. package/lib/commonjs/actionProcessor/core/log/index.d.ts +0 -2
  95. package/lib/commonjs/actionProcessor/core/log/index.js +0 -19
  96. package/lib/commonjs/actionProcessor/core/math/getMathRandomNumberActionProcessor.d.ts +0 -2
  97. package/lib/commonjs/actionProcessor/core/math/index.d.ts +0 -2
  98. package/lib/commonjs/actionProcessor/core/math/index.js +0 -17
  99. package/lib/commonjs/actionProcessor/core/network/getNetworkRequestActionProcessor.js +0 -150
  100. package/lib/commonjs/actionProcessor/core/network/index.d.ts +0 -2
  101. package/lib/commonjs/actionProcessor/core/network/index.js +0 -17
  102. package/lib/commonjs/actionProcessor/core/platform/getPlatformDelayActionProcessor.d.ts +0 -2
  103. package/lib/commonjs/actionProcessor/core/platform/getPlatformDelayActionProcessor.js +0 -24
  104. package/lib/commonjs/actionProcessor/core/platform/index.d.ts +0 -2
  105. package/lib/commonjs/actionProcessor/core/platform/index.js +0 -17
  106. package/lib/commonjs/actionProcessor/core/system/getSystemBatchActionProcessor.d.ts +0 -2
  107. package/lib/commonjs/actionProcessor/core/system/getSystemBatchActionProcessor.js +0 -51
  108. package/lib/commonjs/actionProcessor/webserver/dns/getDnsListActionProcessor.d.ts +0 -2
  109. package/lib/commonjs/actionProcessor/webserver/dns/getDnsListActionProcessor.js +0 -26
  110. package/lib/commonjs/actionProcessor/webserver/dns/index.d.ts +0 -2
  111. package/lib/commonjs/actionProcessor/webserver/dns/index.js +0 -17
  112. package/lib/esm/actionProcessor/core/claudeAi/getClaudeAiMessagesApiActionProcessor.d.ts +0 -2
  113. package/lib/esm/actionProcessor/core/claudeAi/getClaudeAiMessagesApiActionProcessor.js +0 -26
  114. package/lib/esm/actionProcessor/core/claudeAi/index.d.ts +0 -2
  115. package/lib/esm/actionProcessor/core/claudeAi/index.js +0 -4
  116. package/lib/esm/actionProcessor/core/config/getConfigGetApplicationInfoActionProcessor.d.ts +0 -2
  117. package/lib/esm/actionProcessor/core/config/getConfigGetApplicationInfoActionProcessor.js +0 -15
  118. package/lib/esm/actionProcessor/core/config/index.js +0 -4
  119. package/lib/esm/actionProcessor/core/context/getContextListActionProcessor.d.ts +0 -2
  120. package/lib/esm/actionProcessor/core/context/getContextListActionProcessor.js +0 -9
  121. package/lib/esm/actionProcessor/core/context/getContextReadActionProcessor.d.ts +0 -2
  122. package/lib/esm/actionProcessor/core/context/getContextReadActionProcessor.js +0 -12
  123. package/lib/esm/actionProcessor/core/context/index.d.ts +0 -2
  124. package/lib/esm/actionProcessor/core/context/index.js +0 -6
  125. package/lib/esm/actionProcessor/core/customActions/getCustomActionActionProcessor.d.ts +0 -2
  126. package/lib/esm/actionProcessor/core/customActions/getCustomActionActionProcessor.js +0 -43
  127. package/lib/esm/actionProcessor/core/customActions/index.d.ts +0 -1
  128. package/lib/esm/actionProcessor/core/customActions/index.js +0 -2
  129. package/lib/esm/actionProcessor/core/date/getDateNowActionProcessor.d.ts +0 -2
  130. package/lib/esm/actionProcessor/core/date/getDateNowActionProcessor.js +0 -9
  131. package/lib/esm/actionProcessor/core/date/index.d.ts +0 -2
  132. package/lib/esm/actionProcessor/core/date/index.js +0 -4
  133. package/lib/esm/actionProcessor/core/error/getErrorThrowErrorActionProcessor.d.ts +0 -2
  134. package/lib/esm/actionProcessor/core/error/getErrorThrowErrorActionProcessor.js +0 -9
  135. package/lib/esm/actionProcessor/core/error/index.d.ts +0 -2
  136. package/lib/esm/actionProcessor/core/error/index.js +0 -4
  137. package/lib/esm/actionProcessor/core/guid/getGuidNewActionProcessor.d.ts +0 -2
  138. package/lib/esm/actionProcessor/core/guid/getGuidNewActionProcessor.js +0 -10
  139. package/lib/esm/actionProcessor/core/guid/getGuidNewSortableActionProcessor.d.ts +0 -2
  140. package/lib/esm/actionProcessor/core/guid/getGuidNewSortableActionProcessor.js +0 -10
  141. package/lib/esm/actionProcessor/core/guid/index.d.ts +0 -2
  142. package/lib/esm/actionProcessor/core/guid/index.js +0 -6
  143. package/lib/esm/actionProcessor/core/log/getLogCreateActionProcessor.d.ts +0 -2
  144. package/lib/esm/actionProcessor/core/log/getLogCreateActionProcessor.js +0 -15
  145. package/lib/esm/actionProcessor/core/log/getLogDisableEventHistoryActionProcessor.d.ts +0 -2
  146. package/lib/esm/actionProcessor/core/log/getLogDisableEventHistoryActionProcessor.js +0 -10
  147. package/lib/esm/actionProcessor/core/log/getLogTemplateLiteralActionProcessor.d.ts +0 -2
  148. package/lib/esm/actionProcessor/core/log/getLogTemplateLiteralActionProcessor.js +0 -11
  149. package/lib/esm/actionProcessor/core/log/index.d.ts +0 -2
  150. package/lib/esm/actionProcessor/core/log/index.js +0 -8
  151. package/lib/esm/actionProcessor/core/math/getMathRandomNumberActionProcessor.d.ts +0 -2
  152. package/lib/esm/actionProcessor/core/math/getMathRandomNumberActionProcessor.js +0 -9
  153. package/lib/esm/actionProcessor/core/math/index.d.ts +0 -2
  154. package/lib/esm/actionProcessor/core/math/index.js +0 -4
  155. package/lib/esm/actionProcessor/core/network/getNetworkRequestActionProcessor.js +0 -134
  156. package/lib/esm/actionProcessor/core/network/index.d.ts +0 -2
  157. package/lib/esm/actionProcessor/core/network/index.js +0 -4
  158. package/lib/esm/actionProcessor/core/platform/getPlatformDelayActionProcessor.d.ts +0 -2
  159. package/lib/esm/actionProcessor/core/platform/getPlatformDelayActionProcessor.js +0 -9
  160. package/lib/esm/actionProcessor/core/platform/index.d.ts +0 -2
  161. package/lib/esm/actionProcessor/core/platform/index.js +0 -4
  162. package/lib/esm/actionProcessor/core/system/getSystemBatchActionProcessor.d.ts +0 -2
  163. package/lib/esm/actionProcessor/core/system/getSystemBatchActionProcessor.js +0 -36
  164. package/lib/esm/actionProcessor/core/system/index.d.ts +0 -2
  165. package/lib/esm/actionProcessor/core/system/index.js +0 -4
  166. package/lib/esm/actionProcessor/webserver/dns/getDnsListActionProcessor.d.ts +0 -2
  167. package/lib/esm/actionProcessor/webserver/dns/getDnsListActionProcessor.js +0 -11
  168. package/lib/esm/actionProcessor/webserver/dns/index.d.ts +0 -2
  169. package/lib/esm/actionProcessor/webserver/dns/index.js +0 -4
@@ -47,17 +47,18 @@ const quidproquo_core_1 = require("quidproquo-core");
47
47
  const fs = __importStar(require("fs/promises"));
48
48
  const utils_1 = require("./utils");
49
49
  const getProcessFileWriteObjectJson = (config) => (qpqConfig) => {
50
- const serviceName = quidproquo_core_1.qpqCoreUtils.getApplicationModuleName(qpqConfig);
51
50
  return (_a) => __awaiter(void 0, [_a], void 0, function* ({ drive, filepath, data }) {
52
51
  try {
53
- const fullPath = (0, utils_1.resolveFilePath)(config, serviceName, drive, filepath);
52
+ const fullPath = (0, utils_1.resolveFilePath)(config, qpqConfig, drive, filepath);
54
53
  yield (0, utils_1.ensureParentDirectoryExists)(fullPath);
55
54
  const jsonString = JSON.stringify(data, null, 2);
56
55
  yield fs.writeFile(fullPath, jsonString, 'utf8');
57
56
  return (0, quidproquo_core_1.actionResult)(void 0);
58
57
  }
59
58
  catch (error) {
60
- return (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.ErrorTypeEnum.GenericError, `Error writing JSON file: ${error.message}`);
59
+ return (0, quidproquo_core_1.actionResultErrorFromCaughtError)(error, {
60
+ EACCES: () => (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.FileWriteObjectJsonErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
61
+ });
61
62
  }
62
63
  });
63
64
  };
@@ -47,16 +47,17 @@ const quidproquo_core_1 = require("quidproquo-core");
47
47
  const fs = __importStar(require("fs/promises"));
48
48
  const utils_1 = require("./utils");
49
49
  const getProcessFileWriteTextContents = (qpqConfig, config) => {
50
- const serviceName = quidproquo_core_1.qpqCoreUtils.getApplicationModuleName(qpqConfig);
51
50
  return (_a) => __awaiter(void 0, [_a], void 0, function* ({ drive, filepath, data }) {
52
51
  try {
53
- const fullPath = (0, utils_1.resolveFilePath)(config, serviceName, drive, filepath);
52
+ const fullPath = (0, utils_1.resolveFilePath)(config, qpqConfig, drive, filepath);
54
53
  yield (0, utils_1.ensureParentDirectoryExists)(fullPath);
55
54
  yield fs.writeFile(fullPath, data, 'utf8');
56
55
  return (0, quidproquo_core_1.actionResult)(void 0);
57
56
  }
58
57
  catch (error) {
59
- return (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.ErrorTypeEnum.GenericError, `Error writing file: ${error.message}`);
58
+ return (0, quidproquo_core_1.actionResultErrorFromCaughtError)(error, {
59
+ EACCES: () => (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.FileWriteTextContentsErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
60
+ });
60
61
  }
61
62
  });
62
63
  };
@@ -33,6 +33,7 @@ const getFileListDirectoryActionProcessor_1 = require("./getFileListDirectoryAct
33
33
  const getFileReadBinaryContentsActionProcessor_1 = require("./getFileReadBinaryContentsActionProcessor");
34
34
  const getFileReadObjectJsonActionProcessor_1 = require("./getFileReadObjectJsonActionProcessor");
35
35
  const getFileReadTextContentsActionProcessor_1 = require("./getFileReadTextContentsActionProcessor");
36
+ const getFileStreamOpenActionProcessor_1 = require("./getFileStreamOpenActionProcessor");
36
37
  const getFileWriteBinaryContentsActionProcessor_1 = require("./getFileWriteBinaryContentsActionProcessor");
37
38
  const getFileWriteObjectJsonActionProcessor_1 = require("./getFileWriteObjectJsonActionProcessor");
38
39
  const getFileWriteTextContentsActionProcessor_1 = require("./getFileWriteTextContentsActionProcessor");
@@ -40,7 +41,7 @@ __exportStar(require("./types"), exports);
40
41
  // Main export that accepts configuration
41
42
  const getFileActionProcessor = (fileStorageConfig) => {
42
43
  return (qpqConfig, dynamicModuleLoader) => __awaiter(void 0, void 0, void 0, function* () {
43
- return (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (yield (0, getFileReadTextContentsActionProcessor_1.getFileReadTextContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileWriteTextContentsActionProcessor_1.getFileWriteTextContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileReadObjectJsonActionProcessor_1.getFileReadObjectJsonActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileWriteObjectJsonActionProcessor_1.getFileWriteObjectJsonActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileReadBinaryContentsActionProcessor_1.getFileReadBinaryContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileWriteBinaryContentsActionProcessor_1.getFileWriteBinaryContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileListDirectoryActionProcessor_1.getFileListDirectoryActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileExistsActionProcessor_1.getFileExistsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileDeleteActionProcessor_1.getFileDeleteActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileGenerateTemporarySecureUrlActionProcessor_1.getFileGenerateTemporarySecureUrlActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileGenerateTemporaryUploadSecureUrlActionProcessor_1.getFileGenerateTemporaryUploadSecureUrlActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileIsColdStorageActionProcessor_1.getFileIsColdStorageActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))));
44
+ return (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (yield (0, getFileReadTextContentsActionProcessor_1.getFileReadTextContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileWriteTextContentsActionProcessor_1.getFileWriteTextContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileReadObjectJsonActionProcessor_1.getFileReadObjectJsonActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileWriteObjectJsonActionProcessor_1.getFileWriteObjectJsonActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileReadBinaryContentsActionProcessor_1.getFileReadBinaryContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileWriteBinaryContentsActionProcessor_1.getFileWriteBinaryContentsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileListDirectoryActionProcessor_1.getFileListDirectoryActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileExistsActionProcessor_1.getFileExistsActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileDeleteActionProcessor_1.getFileDeleteActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileGenerateTemporarySecureUrlActionProcessor_1.getFileGenerateTemporarySecureUrlActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileGenerateTemporaryUploadSecureUrlActionProcessor_1.getFileGenerateTemporaryUploadSecureUrlActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileIsColdStorageActionProcessor_1.getFileIsColdStorageActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))), (yield (0, getFileStreamOpenActionProcessor_1.getFileStreamOpenActionProcessor)(fileStorageConfig)(qpqConfig, dynamicModuleLoader))));
44
45
  });
45
46
  };
46
47
  exports.getFileActionProcessor = getFileActionProcessor;
@@ -1,6 +1,7 @@
1
1
  import { QPQConfig } from 'quidproquo-core';
2
2
  import { FileStorageConfig } from './types';
3
3
  export declare const isStorageDriveNameValid: (drive: string, qpqConfig: QPQConfig) => boolean;
4
- export declare function resolveFilePath(fileStorageConfig: FileStorageConfig, service: string, drive: string, filepath: string): string;
4
+ export declare function resolveDriveServiceName(drive: string, qpqConfig: QPQConfig): string;
5
+ export declare function resolveFilePath(fileStorageConfig: FileStorageConfig, qpqConfig: QPQConfig, drive: string, filepath: string): string;
5
6
  export declare const ensureDirectoryExists: (dirPath: string) => Promise<void>;
6
7
  export declare const ensureParentDirectoryExists: (filePath: string) => Promise<void>;
@@ -43,6 +43,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.ensureParentDirectoryExists = exports.ensureDirectoryExists = exports.isStorageDriveNameValid = void 0;
46
+ exports.resolveDriveServiceName = resolveDriveServiceName;
46
47
  exports.resolveFilePath = resolveFilePath;
47
48
  const quidproquo_core_1 = require("quidproquo-core");
48
49
  const fs = __importStar(require("fs/promises"));
@@ -56,7 +57,16 @@ const isStorageDriveNameValid = (drive, qpqConfig) => {
56
57
  return true;
57
58
  };
58
59
  exports.isStorageDriveNameValid = isStorageDriveNameValid;
59
- function resolveFilePath(fileStorageConfig, service, drive, filepath) {
60
+ // Resolve the service that owns a drive's on-disk location. Drives declared with
61
+ // `owner.module` are shared across services, so every caller reads and writes
62
+ // under the owner's folder — mirroring how AWS resolves the bucket by owner.
63
+ function resolveDriveServiceName(drive, qpqConfig) {
64
+ var _a, _b;
65
+ const storageDrive = quidproquo_core_1.qpqCoreUtils.getStorageDriveByName(drive, qpqConfig);
66
+ return (_b = (_a = storageDrive === null || storageDrive === void 0 ? void 0 : storageDrive.owner) === null || _a === void 0 ? void 0 : _a.module) !== null && _b !== void 0 ? _b : quidproquo_core_1.qpqCoreUtils.getApplicationModuleName(qpqConfig);
67
+ }
68
+ function resolveFilePath(fileStorageConfig, qpqConfig, drive, filepath) {
69
+ const service = resolveDriveServiceName(drive, qpqConfig);
60
70
  const root = path.resolve(fileStorageConfig.storagePath, service, drive);
61
71
  // Block absolute paths and null bytes outright
62
72
  if (path.isAbsolute(filepath)) {
@@ -1,14 +1,4 @@
1
1
  import { ActionProcessorListResolver } from 'quidproquo-core';
2
- export * from './claudeAi';
3
- export * from './config';
4
- export * from './context';
5
- export * from './date';
6
- export * from './error';
7
- export * from './guid';
8
- export * from './log';
9
- export * from './math';
10
- export * from './network';
11
- export * from './platform';
12
- export * from './system';
13
- export * from './customActions';
2
+ export * from './inlineFunction';
3
+ export * from './stream';
14
4
  export declare const getCoreActionProcessor: ActionProcessorListResolver;
@@ -1,37 +1,14 @@
1
- import { getClaudeAiActionProcessor } from './claudeAi';
2
- import { getConfigActionProcessor } from './config';
3
- import { getContextActionProcessor } from './context';
4
- import { getDateActionProcessor } from './date';
5
- import { getErrorActionProcessor } from './error';
6
- import { getGuidProcessor } from './guid';
7
- import { getLogActionProcessor } from './log';
8
- import { getMathActionProcessor } from './math';
9
- import { getNetworkActionProcessor } from './network';
10
- import { getPlatformActionProcessor } from './platform';
11
- import { getSystemActionProcessor } from './system';
12
- export * from './claudeAi';
13
- export * from './config';
14
- export * from './context';
15
- export * from './date';
16
- export * from './error';
17
- export * from './guid';
18
- export * from './log';
19
- export * from './math';
20
- export * from './network';
21
- export * from './platform';
22
- export * from './system';
23
- // Custom actions is not done here, as it has to be done last after all
24
- export * from './customActions';
1
+ import { getCoreActionProcessor as getJsCoreActionProcessor } from 'quidproquo-actionprocessor-js';
2
+ import { getInlineFunctionActionProcessor } from './inlineFunction';
3
+ import { getStreamActionProcessor } from './stream';
4
+ // The shared core processors (config, context, claudeAi, date, error, guid, log,
5
+ // math, network, platform, system, customActions) are owned by
6
+ // quidproquo-actionprocessor-js. Node builds on top of js and only adds the
7
+ // processors that need a Node runtime (stream, inlineFunction).
8
+ export * from './inlineFunction';
9
+ export * from './stream';
25
10
  export const getCoreActionProcessor = async (qpqConfig, dynamicModuleLoader) => ({
26
- ...(await getConfigActionProcessor(qpqConfig, dynamicModuleLoader)),
27
- ...(await getContextActionProcessor(qpqConfig, dynamicModuleLoader)),
28
- ...(await getClaudeAiActionProcessor(qpqConfig, dynamicModuleLoader)),
29
- ...(await getDateActionProcessor(qpqConfig, dynamicModuleLoader)),
30
- ...(await getErrorActionProcessor(qpqConfig, dynamicModuleLoader)),
31
- ...(await getGuidProcessor(qpqConfig, dynamicModuleLoader)),
32
- ...(await getLogActionProcessor(qpqConfig, dynamicModuleLoader)),
33
- ...(await getMathActionProcessor(qpqConfig, dynamicModuleLoader)),
34
- ...(await getNetworkActionProcessor(qpqConfig, dynamicModuleLoader)),
35
- ...(await getPlatformActionProcessor(qpqConfig, dynamicModuleLoader)),
36
- ...(await getSystemActionProcessor(qpqConfig, dynamicModuleLoader)),
11
+ ...(await getJsCoreActionProcessor(qpqConfig, dynamicModuleLoader)),
12
+ ...(await getStreamActionProcessor(qpqConfig, dynamicModuleLoader)),
13
+ ...(await getInlineFunctionActionProcessor(qpqConfig, dynamicModuleLoader)),
37
14
  });
@@ -0,0 +1,2 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ export declare const getInlineFunctionExecuteActionProcessor: ActionProcessorListResolver;
@@ -0,0 +1,32 @@
1
+ import { actionResult, actionResultError, createRuntime, ErrorTypeEnum, InlineFunctionActionType, qpqCoreUtils, QpqRuntimeType, } from 'quidproquo-core';
2
+ import { randomUUID } from 'crypto';
3
+ const getDateNow = () => new Date().toISOString();
4
+ const getProcessExecute = (qpqConfig) => {
5
+ const moduleName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
+ return async (payload, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
7
+ const inlineFunctions = qpqCoreUtils.getAllInlineFunctions(qpqConfig);
8
+ const inlineFunction = inlineFunctions.find((f) => f.functionName === payload.functionName);
9
+ if (!inlineFunction) {
10
+ return actionResultError(ErrorTypeEnum.NotFound, `Inline function not found: [${payload.functionName}]`);
11
+ }
12
+ const story = await dynamicModuleLoader(inlineFunction.runtime);
13
+ if (!story) {
14
+ return actionResultError(ErrorTypeEnum.NotFound, `Unable to dynamically load inline function: [${payload.functionName}]`);
15
+ }
16
+ const resolveStory = createRuntime(qpqConfig, {
17
+ context: session.context,
18
+ localContext: session.localContext,
19
+ depth: (session.depth || 0) + 1,
20
+ decodedAccessToken: session.decodedAccessToken,
21
+ correlation: session.correlation,
22
+ }, async () => actionProcessors, getDateNow, logger, `${moduleName}::${randomUUID()}`, QpqRuntimeType.EXECUTE_STORY, dynamicModuleLoader, inlineFunction.runtime, [], streamRegistry);
23
+ const storyResult = await resolveStory(story, [payload.payload]);
24
+ if (storyResult.error) {
25
+ return actionResultError(storyResult.error.errorType, storyResult.error.errorText, storyResult.error.errorStack ? `${payload.functionName} -> [${storyResult.error.errorStack}]` : payload.functionName);
26
+ }
27
+ return actionResult(storyResult.result);
28
+ };
29
+ };
30
+ export const getInlineFunctionExecuteActionProcessor = async (qpqConfig) => ({
31
+ [InlineFunctionActionType.Execute]: getProcessExecute(qpqConfig),
32
+ });
@@ -1,2 +1,2 @@
1
1
  import { ActionProcessorListResolver } from 'quidproquo-core';
2
- export declare const getNetworkRequestActionProcessor: ActionProcessorListResolver;
2
+ export declare const getInlineFunctionActionProcessor: ActionProcessorListResolver;
@@ -0,0 +1,4 @@
1
+ import { getInlineFunctionExecuteActionProcessor } from './getInlineFunctionExecuteActionProcessor';
2
+ export const getInlineFunctionActionProcessor = async (qpqConfig, dynamicModuleLoader) => ({
3
+ ...(await getInlineFunctionExecuteActionProcessor(qpqConfig, dynamicModuleLoader)),
4
+ });
@@ -1,2 +1,2 @@
1
1
  import { ActionProcessorListResolver } from 'quidproquo-core';
2
- export declare const getContextListActionProcessor: ActionProcessorListResolver;
2
+ export declare const getStreamCloseActionProcessor: ActionProcessorListResolver;
@@ -0,0 +1,10 @@
1
+ import { actionResult, StreamActionType, } from 'quidproquo-core';
2
+ const getProcessStreamClose = (qpqConfig) => {
3
+ return async ({ streamId }, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
4
+ streamRegistry.close(streamId);
5
+ return actionResult(undefined);
6
+ };
7
+ };
8
+ export const getStreamCloseActionProcessor = async (qpqConfig) => ({
9
+ [StreamActionType.Close]: getProcessStreamClose(qpqConfig),
10
+ });
@@ -0,0 +1,2 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ export declare const getStreamReadActionProcessor: ActionProcessorListResolver;
@@ -0,0 +1,10 @@
1
+ import { actionResult, StreamActionType, } from 'quidproquo-core';
2
+ const getProcessStreamRead = (qpqConfig) => {
3
+ return async ({ streamId, noWait }, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
4
+ const chunk = await streamRegistry.read(streamId, noWait);
5
+ return actionResult(chunk);
6
+ };
7
+ };
8
+ export const getStreamReadActionProcessor = async (qpqConfig) => ({
9
+ [StreamActionType.Read]: getProcessStreamRead(qpqConfig),
10
+ });
@@ -1,2 +1,2 @@
1
1
  import { ActionProcessorListResolver } from 'quidproquo-core';
2
- export declare const getConfigActionProcessor: ActionProcessorListResolver;
2
+ export declare const getStreamActionProcessor: ActionProcessorListResolver;
@@ -0,0 +1,6 @@
1
+ import { getStreamCloseActionProcessor } from './getStreamCloseActionProcessor';
2
+ import { getStreamReadActionProcessor } from './getStreamReadActionProcessor';
3
+ export const getStreamActionProcessor = async (qpqConfig, dynamicModuleLoader) => ({
4
+ ...(await getStreamCloseActionProcessor(qpqConfig, dynamicModuleLoader)),
5
+ ...(await getStreamReadActionProcessor(qpqConfig, dynamicModuleLoader)),
6
+ });
@@ -1,4 +1,6 @@
1
- import { getDnsActionProcessor } from './dns';
1
+ import { getWebserverActionProcessor as getJsWebserverActionProcessor } from 'quidproquo-actionprocessor-js';
2
+ // The shared webserver processors (dns, ...) are owned by quidproquo-actionprocessor-js.
3
+ // Node builds on top of js; it currently adds no node-specific webserver processors.
2
4
  export const getWebserverActionProcessor = async (qpqConfig, dynamicModuleLoader) => ({
3
- ...(await getDnsActionProcessor(qpqConfig, dynamicModuleLoader)),
5
+ ...(await getJsWebserverActionProcessor(qpqConfig, dynamicModuleLoader)),
4
6
  });
@@ -1,14 +1,13 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, FileDeleteErrorTypeEnum, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import { resolveFilePath } from './utils';
4
4
  const getProcessFileDelete = (qpqConfig, config) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepaths }) => {
7
6
  const deletedFiles = [];
8
7
  const errors = [];
9
8
  for (const filepath of filepaths) {
10
9
  try {
11
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
10
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
12
11
  await fs.unlink(fullPath);
13
12
  deletedFiles.push(filepath);
14
13
  }
@@ -18,12 +17,16 @@ const getProcessFileDelete = (qpqConfig, config) => {
18
17
  deletedFiles.push(filepath);
19
18
  }
20
19
  else {
21
- errors.push(`Failed to delete ${filepath}: ${error.message}`);
20
+ errors.push({ filepath, error });
22
21
  }
23
22
  }
24
23
  }
25
24
  if (errors.length > 0 && deletedFiles.length === 0) {
26
- return actionResultError(ErrorTypeEnum.GenericError, `Failed to delete files: ${errors.join(', ')}`);
25
+ // EACCES maps to the same typed error the S3 processor returns for AccessDenied
26
+ if (errors.some(({ error }) => error.code === 'EACCES')) {
27
+ return actionResultError(FileDeleteErrorTypeEnum.AccessDenied, 'Access denied deleting files');
28
+ }
29
+ return actionResultError(ErrorTypeEnum.GenericError, `Failed to delete files: ${errors.map(({ filepath, error }) => `Failed to delete ${filepath}: ${error.message}`).join(', ')}`);
27
30
  }
28
31
  return actionResult(deletedFiles);
29
32
  };
@@ -1,17 +1,23 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, FileExistsErrorTypeEnum, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import { resolveFilePath } from './utils';
4
4
  const getProcessFileExists = (qpqConfig, config) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath }) => {
7
6
  try {
8
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
7
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
9
8
  try {
10
9
  await fs.access(fullPath);
11
10
  return actionResult(true);
12
11
  }
13
- catch {
14
- return actionResult(false);
12
+ catch (error) {
13
+ // Missing file is a definitive false; permission problems must surface.
14
+ if (error.code === 'ENOENT') {
15
+ return actionResult(false);
16
+ }
17
+ if (error.code === 'EACCES') {
18
+ return actionResultError(FileExistsErrorTypeEnum.AccessDenied, `Access denied checking file existence: ${filepath}`);
19
+ }
20
+ throw error;
15
21
  }
16
22
  }
17
23
  catch (error) {
@@ -1,13 +1,12 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, } from 'quidproquo-core';
2
2
  import { createSecureUrlToken, getSecureUrlBaseUrl } from './secureUrlUtils';
3
3
  import { resolveFilePath } from './utils';
4
4
  const getProcessFileGenerateTemporarySecureUrl = (qpqConfig, config) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath, expirationMs }) => {
7
6
  try {
8
7
  // Create a token for download
9
8
  const token = createSecureUrlToken({
10
- fullFilepath: resolveFilePath(config, serviceName, drive, filepath),
9
+ fullFilepath: resolveFilePath(config, qpqConfig, drive, filepath),
11
10
  operation: 'download',
12
11
  expiresAt: Date.now() + expirationMs,
13
12
  }, config.secureUrlSecret);
@@ -1,14 +1,13 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, } from 'quidproquo-core';
2
2
  import { createSecureUrlToken, getSecureUrlBaseUrl } from './secureUrlUtils';
3
3
  import { resolveFilePath } from './utils';
4
4
  const getProcessFileGenerateTemporaryUploadSecureUrl = (qpqConfig, config) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath, expirationMs, contentType }) => {
7
6
  try {
8
7
  const expiresAt = Date.now() + expirationMs;
9
8
  // Create a token for upload
10
9
  const token = createSecureUrlToken({
11
- fullFilepath: resolveFilePath(config, serviceName, drive, filepath),
10
+ fullFilepath: resolveFilePath(config, qpqConfig, drive, filepath),
12
11
  operation: 'upload',
13
12
  expiresAt,
14
13
  contentType,
@@ -1,12 +1,11 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileListDirectoryErrorTypeEnum, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import * as path from 'path';
4
4
  import { resolveFilePath } from './utils';
5
5
  const getProcessFileListDirectory = (config) => (qpqConfig) => {
6
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
7
6
  return async ({ drive, folderPath, maxFiles, pageToken }) => {
8
7
  try {
9
- const fullPath = resolveFilePath(config, serviceName, drive, folderPath || '');
8
+ const fullPath = resolveFilePath(config, qpqConfig, drive, folderPath || '');
10
9
  // Read all entries in the directory
11
10
  const entries = await fs.readdir(fullPath, { withFileTypes: true });
12
11
  // Build file info list
@@ -35,13 +34,11 @@ const getProcessFileListDirectory = (config) => (qpqConfig) => {
35
34
  return actionResult(result);
36
35
  }
37
36
  catch (error) {
38
- if (error.code === 'ENOENT') {
39
- return actionResultError(ErrorTypeEnum.NotFound, `Directory not found: ${folderPath}`);
40
- }
41
- if (error.code === 'ENOTDIR') {
42
- return actionResultError(ErrorTypeEnum.GenericError, `Path is not a directory: ${folderPath}`);
43
- }
44
- return actionResultError(ErrorTypeEnum.GenericError, `Error listing directory: ${error.message}`);
37
+ return actionResultErrorFromCaughtError(error, {
38
+ ENOENT: () => actionResultError(FileListDirectoryErrorTypeEnum.DirectoryNotFound, `Directory not found: ${folderPath}`), // node fs code
39
+ ENOTDIR: () => actionResultError(FileListDirectoryErrorTypeEnum.NotADirectory, `Path is not a directory: ${folderPath}`), // node fs code
40
+ EACCES: () => actionResultError(FileListDirectoryErrorTypeEnum.AccessDenied, `Access denied listing directory: ${folderPath}`), // node fs code
41
+ });
45
42
  }
46
43
  };
47
44
  };
@@ -1,12 +1,11 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileReadBinaryContentsErrorTypeEnum, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import * as path from 'path';
4
4
  import { resolveFilePath } from './utils';
5
5
  const getProcessFileReadBinaryContents = (config) => (qpqConfig) => {
6
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
7
6
  return async ({ drive, filepath }) => {
8
7
  try {
9
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
8
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
10
9
  const buffer = await fs.readFile(fullPath);
11
10
  // Convert Buffer to QPQBinaryData
12
11
  const binaryData = {
@@ -17,10 +16,9 @@ const getProcessFileReadBinaryContents = (config) => (qpqConfig) => {
17
16
  return actionResult(binaryData);
18
17
  }
19
18
  catch (error) {
20
- if (error.code === 'ENOENT') {
21
- return actionResultError(ErrorTypeEnum.NotFound, `File not found: ${filepath}`);
22
- }
23
- return actionResultError(ErrorTypeEnum.GenericError, `Error reading binary file: ${error.message}`);
19
+ return actionResultErrorFromCaughtError(error, {
20
+ ENOENT: () => actionResultError(FileReadBinaryContentsErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code
21
+ });
24
22
  }
25
23
  };
26
24
  };
@@ -1,23 +1,19 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, ErrorTypeEnum, FileActionType, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import { resolveFilePath } from './utils';
4
4
  const getProcessFileReadObjectJson = (config) => (qpqConfig) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath }) => {
7
6
  try {
8
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
7
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
9
8
  const content = await fs.readFile(fullPath, 'utf8');
10
9
  const jsonObject = JSON.parse(content);
11
10
  return actionResult(jsonObject);
12
11
  }
13
12
  catch (error) {
14
- if (error.code === 'ENOENT') {
15
- return actionResultError(ErrorTypeEnum.NotFound, `File not found: ${filepath}`);
16
- }
17
- if (error instanceof SyntaxError) {
18
- return actionResultError(ErrorTypeEnum.GenericError, `Invalid JSON in file: ${filepath}`);
19
- }
20
- return actionResultError(ErrorTypeEnum.GenericError, `Error reading JSON file: ${error.message}`);
13
+ return actionResultErrorFromCaughtError(error, {
14
+ ENOENT: () => actionResultError(ErrorTypeEnum.NotFound, `File not found: ${filepath}`), // node fs code
15
+ SyntaxError: () => actionResultError(ErrorTypeEnum.GenericError, `Invalid JSON in file: ${filepath}`), // JSON.parse failure
16
+ });
21
17
  }
22
18
  };
23
19
  };
@@ -1,19 +1,17 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, ErrorTypeEnum, FileActionType, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import { resolveFilePath } from './utils';
4
4
  const getProcessFileReadTextContents = (qpqConfig, config) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath }) => {
7
6
  try {
8
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
7
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
9
8
  const content = await fs.readFile(fullPath, 'utf8');
10
9
  return actionResult(content);
11
10
  }
12
11
  catch (error) {
13
- if (error.code === 'ENOENT') {
14
- return actionResultError(ErrorTypeEnum.NotFound, `File not found: ${filepath}`);
15
- }
16
- return actionResultError(ErrorTypeEnum.GenericError, `Error reading file: ${error.message}`);
12
+ return actionResultErrorFromCaughtError(error, {
13
+ ENOENT: () => actionResultError(ErrorTypeEnum.NotFound, `File not found: ${filepath}`), // node fs code
14
+ });
17
15
  }
18
16
  };
19
17
  };
@@ -0,0 +1,3 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ import { FileStorageConfig } from './types';
3
+ export declare const getFileStreamOpenActionProcessor: (config: FileStorageConfig) => ActionProcessorListResolver;
@@ -0,0 +1,37 @@
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileStreamOpenErrorTypeEnum, } from 'quidproquo-core';
2
+ import { randomUUID } from 'crypto';
3
+ import * as fs from 'fs';
4
+ import { resolveFilePath } from './utils';
5
+ async function* textStreamIterator(stream) {
6
+ for await (const chunk of stream) {
7
+ yield typeof chunk === 'string' ? chunk : chunk.toString('utf8');
8
+ }
9
+ }
10
+ async function* binaryStreamIterator(stream) {
11
+ for await (const chunk of stream) {
12
+ const buffer = typeof chunk === 'string' ? Buffer.from(chunk) : chunk;
13
+ yield buffer.toString('base64');
14
+ }
15
+ }
16
+ const getProcessFileStreamOpen = (qpqConfig, config) => {
17
+ return async ({ drive, filepath, encoding, chunkSize }, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
18
+ try {
19
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
20
+ const isText = encoding === 'text';
21
+ const highWaterMark = chunkSize ?? 65536;
22
+ const readStream = fs.createReadStream(fullPath, isText ? { encoding: 'utf8', highWaterMark } : { highWaterMark });
23
+ const streamId = `file-${randomUUID()}`;
24
+ const iterator = isText ? textStreamIterator(readStream) : binaryStreamIterator(readStream);
25
+ streamRegistry.register(streamId, iterator);
26
+ return actionResult({ id: streamId, encoding });
27
+ }
28
+ catch (error) {
29
+ return actionResultErrorFromCaughtError(error, {
30
+ ENOENT: () => actionResultError(FileStreamOpenErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code
31
+ });
32
+ }
33
+ };
34
+ };
35
+ export const getFileStreamOpenActionProcessor = (config) => async (qpqConfig) => ({
36
+ [FileActionType.StreamOpen]: getProcessFileStreamOpen(qpqConfig, config),
37
+ });
@@ -1,19 +1,26 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileWriteBinaryContentsErrorTypeEnum, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import { ensureParentDirectoryExists, resolveFilePath } from './utils';
4
4
  const getProcessFileWriteBinaryContents = (config) => (qpqConfig) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath, data }) => {
7
6
  try {
8
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
7
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
9
8
  await ensureParentDirectoryExists(fullPath);
10
9
  // Convert QPQBinaryData to Buffer
11
10
  const buffer = Buffer.from(data.base64Data, 'base64');
12
11
  await fs.writeFile(fullPath, buffer);
12
+ if (data.mimetype || data.contentDisposition) {
13
+ await fs.writeFile(`${fullPath}.qpqmeta.json`, JSON.stringify({
14
+ mimetype: data.mimetype,
15
+ contentDisposition: data.contentDisposition,
16
+ }));
17
+ }
13
18
  return actionResult(void 0);
14
19
  }
15
20
  catch (error) {
16
- return actionResultError(ErrorTypeEnum.GenericError, `Error writing binary file: ${error.message}`);
21
+ return actionResultErrorFromCaughtError(error, {
22
+ EACCES: () => actionResultError(FileWriteBinaryContentsErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
23
+ });
17
24
  }
18
25
  };
19
26
  };
@@ -1,18 +1,19 @@
1
- import { actionResult, actionResultError, ErrorTypeEnum, FileActionType, qpqCoreUtils, } from 'quidproquo-core';
1
+ import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileWriteObjectJsonErrorTypeEnum, } from 'quidproquo-core';
2
2
  import * as fs from 'fs/promises';
3
3
  import { ensureParentDirectoryExists, resolveFilePath } from './utils';
4
4
  const getProcessFileWriteObjectJson = (config) => (qpqConfig) => {
5
- const serviceName = qpqCoreUtils.getApplicationModuleName(qpqConfig);
6
5
  return async ({ drive, filepath, data }) => {
7
6
  try {
8
- const fullPath = resolveFilePath(config, serviceName, drive, filepath);
7
+ const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
9
8
  await ensureParentDirectoryExists(fullPath);
10
9
  const jsonString = JSON.stringify(data, null, 2);
11
10
  await fs.writeFile(fullPath, jsonString, 'utf8');
12
11
  return actionResult(void 0);
13
12
  }
14
13
  catch (error) {
15
- return actionResultError(ErrorTypeEnum.GenericError, `Error writing JSON file: ${error.message}`);
14
+ return actionResultErrorFromCaughtError(error, {
15
+ EACCES: () => actionResultError(FileWriteObjectJsonErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
16
+ });
16
17
  }
17
18
  };
18
19
  };