quidproquo-actionprocessor-node 0.1.6 → 0.1.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/lib/commonjs/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js +4 -0
- package/lib/commonjs/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileDeleteActionProcessor.js +10 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileDeleteActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileExistsActionProcessor.js +7 -3
- package/lib/commonjs/dynamicActionProcessor/file/getFileExistsActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js +13 -3
- package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js +13 -3
- package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js +3 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js +3 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js +5 -4
- package/lib/commonjs/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js +4 -3
- package/lib/commonjs/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js +3 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js +3 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js +3 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js +3 -2
- package/lib/commonjs/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js.map +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/utils.d.ts +1 -1
- package/lib/commonjs/dynamicActionProcessor/file/utils.js +9 -2
- package/lib/commonjs/dynamicActionProcessor/file/utils.js.map +1 -1
- package/lib/commonjs/traceStoryExecution/getSystemTraceStoryActionProcessor.d.ts +3 -2
- package/lib/commonjs/traceStoryExecution/getSystemTraceStoryActionProcessor.js +4 -3
- package/lib/commonjs/traceStoryExecution/getSystemTraceStoryActionProcessor.js.map +1 -1
- package/lib/commonjs/traceStoryExecution/index.d.ts +1 -0
- package/lib/commonjs/traceStoryExecution/index.js +1 -0
- package/lib/commonjs/traceStoryExecution/index.js.map +1 -1
- package/lib/commonjs/traceStoryExecution/resolveSourceMaps.d.ts +2 -1
- package/lib/commonjs/traceStoryExecution/resolveSourceMaps.js +24 -3
- package/lib/commonjs/traceStoryExecution/resolveSourceMaps.js.map +1 -1
- package/lib/commonjs/traceStoryExecution/traceStoryExecution.d.ts +1 -0
- package/lib/commonjs/traceStoryExecution/traceStoryExecution.js +1 -1
- package/lib/commonjs/traceStoryExecution/traceStoryExecution.js.map +1 -1
- package/lib/esm/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js +4 -0
- package/lib/esm/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileDeleteActionProcessor.js +10 -2
- package/lib/esm/dynamicActionProcessor/file/getFileDeleteActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileExistsActionProcessor.js +8 -4
- package/lib/esm/dynamicActionProcessor/file/getFileExistsActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js +14 -4
- package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js +14 -4
- package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js +3 -2
- package/lib/esm/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js +3 -2
- package/lib/esm/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js +6 -5
- package/lib/esm/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js +5 -4
- package/lib/esm/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js +3 -2
- package/lib/esm/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js +3 -2
- package/lib/esm/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js +3 -2
- package/lib/esm/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js +3 -2
- package/lib/esm/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js.map +1 -1
- package/lib/esm/dynamicActionProcessor/file/utils.d.ts +1 -1
- package/lib/esm/dynamicActionProcessor/file/utils.js +10 -3
- package/lib/esm/dynamicActionProcessor/file/utils.js.map +1 -1
- package/lib/esm/traceStoryExecution/getSystemTraceStoryActionProcessor.d.ts +3 -2
- package/lib/esm/traceStoryExecution/getSystemTraceStoryActionProcessor.js +4 -3
- package/lib/esm/traceStoryExecution/getSystemTraceStoryActionProcessor.js.map +1 -1
- package/lib/esm/traceStoryExecution/index.d.ts +1 -0
- package/lib/esm/traceStoryExecution/index.js +1 -0
- package/lib/esm/traceStoryExecution/index.js.map +1 -1
- package/lib/esm/traceStoryExecution/resolveSourceMaps.d.ts +2 -1
- package/lib/esm/traceStoryExecution/resolveSourceMaps.js +22 -2
- package/lib/esm/traceStoryExecution/resolveSourceMaps.js.map +1 -1
- package/lib/esm/traceStoryExecution/traceStoryExecution.d.ts +1 -0
- package/lib/esm/traceStoryExecution/traceStoryExecution.js +1 -1
- package/lib/esm/traceStoryExecution/traceStoryExecution.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileGenerateTemporaryUploadSecureUrlActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"getFileGenerateTemporaryUploadSecureUrlActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,iDAAiD,GAElD,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,6EAA6E;AAC7E,sDAAsD;AACtD,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD,MAAM,8CAA8C,GAAG,CACrD,SAAoB,EACpB,MAAyB,EAC4B,EAAE;IACvD,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;QACrE,IAAI,YAAY,GAAG,eAAe,EAAE,CAAC;YACnC,OAAO,iBAAiB,CACtB,iDAAiD,CAAC,iBAAiB,EACnE,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC;YAE5C,4BAA4B;YAC5B,MAAM,KAAK,GAAG,oBAAoB,CAChC;gBACE,YAAY,EAAE,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC;gBACxE,SAAS,EAAE,QAAQ;gBACnB,SAAS;gBACT,WAAW;aACZ,EACD,MAAM,CAAC,eAAe,CACvB,CAAC;YAEF,uBAAuB;YACvB,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,GAAG,OAAO,wBAAwB,KAAK,EAAE,CAAC;YAEtD,OAAO,CAAC,GAAG,CAAC,4BAA4B,QAAQ,aAAa,KAAK,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAEvH,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,qEAAqE;YACrE,uDAAuD;YACvD,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,iDAAiD,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;aAC/H,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sDAAsD,GACjE,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,gCAAgC,CAAC,EAAE,8CAA8C,CAAC,SAAS,EAAE,MAAM,CAAC;CACrH,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileGenerateTemporaryUploadSecureUrlActionProcessor,\n FileGenerateTemporaryUploadSecureUrlErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport { createSecureUrlToken, getSecureUrlBaseUrl } from './secureUrlUtils';\nimport { FileStorageConfig } from './types';\nimport { resolveFilePath } from './utils';\n\n// Mirror the AWS processor's SigV4 limit (7 days) so a story that would fail\n// in production fails the same way on the dev server.\nconst maxExpirationMs = 7 * 24 * 60 * 60 * 1000;\n\nconst getProcessFileGenerateTemporaryUploadSecureUrl = (\n qpqConfig: QPQConfig,\n config: FileStorageConfig,\n): FileGenerateTemporaryUploadSecureUrlActionProcessor => {\n return async ({ drive, filepath, expirationMs, contentType, scope }) => {\n if (expirationMs > maxExpirationMs) {\n return actionResultError(\n FileGenerateTemporaryUploadSecureUrlErrorTypeEnum.ExpirationTooLong,\n 'Expiration exceeds the 7 day maximum for presigned URLs',\n );\n }\n\n try {\n const expiresAt = Date.now() + expirationMs;\n\n // Create a token for upload\n const token = createSecureUrlToken(\n {\n fullFilepath: resolveFilePath(config, qpqConfig, drive, filepath, scope),\n operation: 'upload',\n expiresAt,\n contentType,\n },\n config.secureUrlSecret,\n );\n\n // Build the secure URL\n const baseUrl = getSecureUrlBaseUrl(config);\n const url = `${baseUrl}/secure-upload?token=${token}`;\n\n console.log(`Generated upload URL for ${filepath} in drive ${drive}, expires at ${new Date(expiresAt).toISOString()}`);\n\n return actionResult(url);\n } catch (error: unknown) {\n // Name-keyed, not instanceof: under npm link / module federation the\n // error can come from another copy of quidproquo-core.\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileGenerateTemporaryUploadSecureUrlErrorTypeEnum.InvalidScope, error.message),\n });\n }\n };\n};\n\nexport const getFileGenerateTemporaryUploadSecureUrlActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.GenerateTemporaryUploadSecureUrl]: getProcessFileGenerateTemporaryUploadSecureUrl(qpqConfig, config),\n });\n"]}
|
|
@@ -3,9 +3,9 @@ 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
|
-
return async ({ drive, folderPath, maxFiles, pageToken }) => {
|
|
6
|
+
return async ({ drive, folderPath, maxFiles, pageToken, scope }) => {
|
|
7
7
|
try {
|
|
8
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, folderPath || '');
|
|
8
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, folderPath || '', scope);
|
|
9
9
|
// Read all entries in the directory
|
|
10
10
|
const entries = await fs.readdir(fullPath, { withFileTypes: true });
|
|
11
11
|
// Build file info list
|
|
@@ -35,6 +35,7 @@ const getProcessFileListDirectory = (config) => (qpqConfig) => {
|
|
|
35
35
|
}
|
|
36
36
|
catch (error) {
|
|
37
37
|
return actionResultErrorFromCaughtError(error, {
|
|
38
|
+
InvalidScopeError: (error) => actionResultError(FileListDirectoryErrorTypeEnum.InvalidScope, error.message),
|
|
38
39
|
ENOENT: () => actionResultError(FileListDirectoryErrorTypeEnum.DirectoryNotFound, `Directory not found: ${folderPath}`), // node fs code
|
|
39
40
|
ENOTDIR: () => actionResultError(FileListDirectoryErrorTypeEnum.NotADirectory, `Path is not a directory: ${folderPath}`), // node fs code
|
|
40
41
|
EACCES: () => actionResultError(FileListDirectoryErrorTypeEnum.AccessDenied, `Access denied listing directory: ${folderPath}`), // node fs code
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileListDirectoryActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAEhC,cAAc,EAGd,8BAA8B,GAE/B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,2BAA2B,GAC/B,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAAoC,EAAE;IACzD,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"getFileListDirectoryActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n DirectoryList,\n FileActionType,\n FileInfo,\n FileListDirectoryActionProcessor,\n FileListDirectoryErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nimport { FileStorageConfig } from './types';\nimport { resolveFilePath } from './utils';\n\nconst getProcessFileListDirectory =\n (config: FileStorageConfig) =>\n (qpqConfig: QPQConfig): FileListDirectoryActionProcessor => {\n return async ({ drive, folderPath, maxFiles, pageToken, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, folderPath || '', scope);\n\n // Read all entries in the directory\n const entries = await fs.readdir(fullPath, { withFileTypes: true });\n\n // Build file info list\n const allFiles: FileInfo[] = [];\n for (const entry of entries) {\n allFiles.push({\n filepath: path.join(folderPath || '', entry.name),\n drive: drive,\n isDir: entry.isDirectory(),\n hashMd5: undefined,\n });\n }\n\n // Sort by filepath for consistent pagination\n allFiles.sort((a, b) => a.filepath.localeCompare(b.filepath));\n\n // Handle pagination\n const startIndex = pageToken ? parseInt(pageToken, 10) : 0;\n const endIndex = Math.min(startIndex + maxFiles, allFiles.length);\n const paginatedFiles = allFiles.slice(startIndex, endIndex);\n\n const result: DirectoryList = {\n fileInfos: paginatedFiles,\n };\n\n // Add page token if there are more files\n if (endIndex < allFiles.length) {\n result.pageToken = endIndex.toString();\n }\n\n return actionResult(result);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileListDirectoryErrorTypeEnum.InvalidScope, error.message),\n ENOENT: () => actionResultError(FileListDirectoryErrorTypeEnum.DirectoryNotFound, `Directory not found: ${folderPath}`), // node fs code\n ENOTDIR: () => actionResultError(FileListDirectoryErrorTypeEnum.NotADirectory, `Path is not a directory: ${folderPath}`), // node fs code\n EACCES: () => actionResultError(FileListDirectoryErrorTypeEnum.AccessDenied, `Access denied listing directory: ${folderPath}`), // node fs code\n });\n }\n };\n };\n\nexport const getFileListDirectoryActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.ListDirectory]: getProcessFileListDirectory(config)(qpqConfig),\n });\n"]}
|
|
@@ -3,9 +3,9 @@ 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
|
-
return async ({ drive, filepath }) => {
|
|
6
|
+
return async ({ drive, filepath, scope }) => {
|
|
7
7
|
try {
|
|
8
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
8
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
9
9
|
const buffer = await fs.readFile(fullPath);
|
|
10
10
|
// Convert Buffer to QPQBinaryData
|
|
11
11
|
const binaryData = {
|
|
@@ -17,6 +17,7 @@ const getProcessFileReadBinaryContents = (config) => (qpqConfig) => {
|
|
|
17
17
|
}
|
|
18
18
|
catch (error) {
|
|
19
19
|
return actionResultErrorFromCaughtError(error, {
|
|
20
|
+
InvalidScopeError: (error) => actionResultError(FileReadBinaryContentsErrorTypeEnum.InvalidScope, error.message),
|
|
20
21
|
ENOENT: () => actionResultError(FileReadBinaryContentsErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code
|
|
21
22
|
});
|
|
22
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileReadBinaryContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,mCAAmC,GAGpC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,gCAAgC,GACpC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAAyC,EAAE;IAC9D,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"getFileReadBinaryContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,mCAAmC,GAGpC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,gCAAgC,GACpC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAAyC,EAAE;IAC9D,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAE3C,kCAAkC;YAClC,MAAM,UAAU,GAAkB;gBAChC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACjC,QAAQ,EAAE,0BAA0B,EAAE,oCAAoC;aAC3E,CAAC;YAEF,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,mCAAmC,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;gBAChH,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,mCAAmC,CAAC,YAAY,EAAE,mBAAmB,QAAQ,EAAE,CAAC,EAAE,eAAe;aAClI,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,wCAAwC,GACnD,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,kBAAkB,CAAC,EAAE,gCAAgC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;CACzF,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileReadBinaryContentsActionProcessor,\n FileReadBinaryContentsErrorTypeEnum,\n QPQBinaryData,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nimport { FileStorageConfig } from './types';\nimport { resolveFilePath } from './utils';\n\nconst getProcessFileReadBinaryContents =\n (config: FileStorageConfig) =>\n (qpqConfig: QPQConfig): FileReadBinaryContentsActionProcessor => {\n return async ({ drive, filepath, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n const buffer = await fs.readFile(fullPath);\n\n // Convert Buffer to QPQBinaryData\n const binaryData: QPQBinaryData = {\n base64Data: buffer.toString('base64'),\n filename: path.basename(filepath),\n mimetype: 'application/octet-stream', // Default mimetype for binary files\n };\n\n return actionResult(binaryData);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileReadBinaryContentsErrorTypeEnum.InvalidScope, error.message),\n ENOENT: () => actionResultError(FileReadBinaryContentsErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code\n });\n }\n };\n };\n\nexport const getFileReadBinaryContentsActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.ReadBinaryContents]: getProcessFileReadBinaryContents(config)(qpqConfig),\n });\n"]}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { actionResult, actionResultError, actionResultErrorFromCaughtError,
|
|
1
|
+
import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileReadObjectJsonErrorTypeEnum, } from 'quidproquo-core';
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import { resolveFilePath } from './utils';
|
|
4
4
|
const getProcessFileReadObjectJson = (config) => (qpqConfig) => {
|
|
5
|
-
return async ({ drive, filepath }) => {
|
|
5
|
+
return async ({ drive, filepath, scope }) => {
|
|
6
6
|
try {
|
|
7
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
7
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
8
8
|
const content = await fs.readFile(fullPath, 'utf8');
|
|
9
9
|
const jsonObject = JSON.parse(content);
|
|
10
10
|
return actionResult(jsonObject);
|
|
11
11
|
}
|
|
12
12
|
catch (error) {
|
|
13
13
|
return actionResultErrorFromCaughtError(error, {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
InvalidScopeError: (error) => actionResultError(FileReadObjectJsonErrorTypeEnum.InvalidScope, error.message),
|
|
15
|
+
ENOENT: () => actionResultError(FileReadObjectJsonErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code
|
|
16
|
+
SyntaxError: () => actionResultError(FileReadObjectJsonErrorTypeEnum.InvalidJson, `Invalid JSON in file: ${filepath}`), // JSON.parse failure
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
19
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileReadObjectJsonActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,
|
|
1
|
+
{"version":3,"file":"getFileReadObjectJsonActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,+BAA+B,GAEhC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,4BAA4B,GAChC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAA0C,EAAE;IAC/D,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,+BAA+B,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;gBAC5G,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,+BAA+B,CAAC,YAAY,EAAE,mBAAmB,QAAQ,EAAE,CAAC,EAAE,eAAe;gBAC7H,WAAW,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,+BAA+B,CAAC,WAAW,EAAE,yBAAyB,QAAQ,EAAE,CAAC,EAAE,qBAAqB;aAC9I,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,oCAAoC,GAC/C,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,4BAA4B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;CACjF,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileReadObjectJsonActionProcessor,\n FileReadObjectJsonErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\n\nimport { FileStorageConfig } from './types';\nimport { resolveFilePath } from './utils';\n\nconst getProcessFileReadObjectJson =\n (config: FileStorageConfig) =>\n (qpqConfig: QPQConfig): FileReadObjectJsonActionProcessor<any> => {\n return async ({ drive, filepath, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n const content = await fs.readFile(fullPath, 'utf8');\n const jsonObject = JSON.parse(content);\n return actionResult(jsonObject);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileReadObjectJsonErrorTypeEnum.InvalidScope, error.message),\n ENOENT: () => actionResultError(FileReadObjectJsonErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code\n SyntaxError: () => actionResultError(FileReadObjectJsonErrorTypeEnum.InvalidJson, `Invalid JSON in file: ${filepath}`), // JSON.parse failure\n });\n }\n };\n };\n\nexport const getFileReadObjectJsonActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.ReadObjectJson]: getProcessFileReadObjectJson(config)(qpqConfig),\n });\n"]}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { actionResult, actionResultError, actionResultErrorFromCaughtError,
|
|
1
|
+
import { actionResult, actionResultError, actionResultErrorFromCaughtError, FileActionType, FileReadTextContentsErrorTypeEnum, } from 'quidproquo-core';
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import { resolveFilePath } from './utils';
|
|
4
4
|
const getProcessFileReadTextContents = (qpqConfig, config) => {
|
|
5
|
-
return async ({ drive, filepath }) => {
|
|
5
|
+
return async ({ drive, filepath, scope }) => {
|
|
6
6
|
try {
|
|
7
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
7
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
8
8
|
const content = await fs.readFile(fullPath, 'utf8');
|
|
9
9
|
return actionResult(content);
|
|
10
10
|
}
|
|
11
11
|
catch (error) {
|
|
12
12
|
return actionResultErrorFromCaughtError(error, {
|
|
13
|
-
|
|
13
|
+
InvalidScopeError: (error) => actionResultError(FileReadTextContentsErrorTypeEnum.InvalidScope, error.message),
|
|
14
|
+
ENOENT: () => actionResultError(FileReadTextContentsErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code
|
|
14
15
|
});
|
|
15
16
|
}
|
|
16
17
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileReadTextContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,
|
|
1
|
+
{"version":3,"file":"getFileReadTextContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,iCAAiC,GAElC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,8BAA8B,GAAG,CAAC,SAAoB,EAAE,MAAyB,EAAuC,EAAE;IAC9H,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpD,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,iCAAiC,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;gBAC9G,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,iCAAiC,CAAC,YAAY,EAAE,mBAAmB,QAAQ,EAAE,CAAC,EAAE,eAAe;aAChI,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sCAAsC,GACjD,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,8BAA8B,CAAC,SAAS,EAAE,MAAM,CAAC;CACrF,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileReadTextContentsActionProcessor,\n FileReadTextContentsErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\n\nimport { FileStorageConfig } from './types';\nimport { resolveFilePath } from './utils';\n\nconst getProcessFileReadTextContents = (qpqConfig: QPQConfig, config: FileStorageConfig): FileReadTextContentsActionProcessor => {\n return async ({ drive, filepath, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n const content = await fs.readFile(fullPath, 'utf8');\n return actionResult(content);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileReadTextContentsErrorTypeEnum.InvalidScope, error.message),\n ENOENT: () => actionResultError(FileReadTextContentsErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code\n });\n }\n };\n};\n\nexport const getFileReadTextContentsActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.ReadTextContents]: getProcessFileReadTextContents(qpqConfig, config),\n });\n"]}
|
|
@@ -14,9 +14,9 @@ async function* binaryStreamIterator(stream) {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
const getProcessFileStreamOpen = (qpqConfig, config) => {
|
|
17
|
-
return async ({ drive, filepath, encoding, chunkSize }, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
|
|
17
|
+
return async ({ drive, filepath, encoding, chunkSize, scope }, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry) => {
|
|
18
18
|
try {
|
|
19
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
19
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
20
20
|
const isText = encoding === 'text';
|
|
21
21
|
const highWaterMark = chunkSize ?? 65536;
|
|
22
22
|
const readStream = fs.createReadStream(fullPath, isText ? { encoding: 'utf8', highWaterMark } : { highWaterMark });
|
|
@@ -27,6 +27,7 @@ const getProcessFileStreamOpen = (qpqConfig, config) => {
|
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
29
|
return actionResultErrorFromCaughtError(error, {
|
|
30
|
+
InvalidScopeError: (error) => actionResultError(FileStreamOpenErrorTypeEnum.InvalidScope, error.message),
|
|
30
31
|
ENOENT: () => actionResultError(FileStreamOpenErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code
|
|
31
32
|
});
|
|
32
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileStreamOpenActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,2BAA2B,GAE5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAIzB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,SAAS,CAAC,CAAC,kBAAkB,CAAC,MAAgB;IACjD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,MAAM,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,KAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,oBAAoB,CAAC,MAAgB;IACnD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAgB,CAAC;QAClF,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,MAAM,wBAAwB,GAAG,CAAC,SAAoB,EAAE,MAAyB,EAAiC,EAAE;IAClH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"getFileStreamOpenActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileStreamOpenActionProcessor,\n FileStreamOpenErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport { randomUUID } from 'crypto';\nimport * as fs from 'fs';\nimport { Readable } from 'stream';\n\nimport { FileStorageConfig } from './types';\nimport { resolveFilePath } from './utils';\n\nasync function* textStreamIterator(stream: Readable): AsyncIterableIterator<string> {\n for await (const chunk of stream) {\n yield typeof chunk === 'string' ? chunk : (chunk as Buffer).toString('utf8');\n }\n}\n\nasync function* binaryStreamIterator(stream: Readable): AsyncIterableIterator<string> {\n for await (const chunk of stream) {\n const buffer = typeof chunk === 'string' ? Buffer.from(chunk) : (chunk as Buffer);\n yield buffer.toString('base64');\n }\n}\n\nconst getProcessFileStreamOpen = (qpqConfig: QPQConfig, config: FileStorageConfig): FileStreamOpenActionProcessor => {\n return async (\n { drive, filepath, encoding, chunkSize, scope },\n session,\n actionProcessors,\n logger,\n updateSession,\n dynamicModuleLoader,\n streamRegistry,\n ) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n const isText = encoding === 'text';\n const highWaterMark = chunkSize ?? 65536;\n const readStream = fs.createReadStream(fullPath, isText ? { encoding: 'utf8', highWaterMark } : { highWaterMark });\n const streamId = `file-${randomUUID()}`;\n\n const iterator = isText ? textStreamIterator(readStream) : binaryStreamIterator(readStream);\n streamRegistry.register(streamId, iterator);\n\n return actionResult({ id: streamId, encoding });\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileStreamOpenErrorTypeEnum.InvalidScope, error.message),\n ENOENT: () => actionResultError(FileStreamOpenErrorTypeEnum.FileNotFound, `File not found: ${filepath}`), // node fs code\n });\n }\n };\n};\n\nexport const getFileStreamOpenActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.StreamOpen]: getProcessFileStreamOpen(qpqConfig, config),\n });\n"]}
|
|
@@ -2,9 +2,9 @@ import { actionResult, actionResultError, actionResultErrorFromCaughtError, File
|
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import { ensureParentDirectoryExists, resolveFilePath } from './utils';
|
|
4
4
|
const getProcessFileWriteBinaryContents = (config) => (qpqConfig) => {
|
|
5
|
-
return async ({ drive, filepath, data }) => {
|
|
5
|
+
return async ({ drive, filepath, data, scope }) => {
|
|
6
6
|
try {
|
|
7
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
7
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
8
8
|
await ensureParentDirectoryExists(fullPath);
|
|
9
9
|
// Convert QPQBinaryData to Buffer
|
|
10
10
|
const buffer = Buffer.from(data.base64Data, 'base64');
|
|
@@ -19,6 +19,7 @@ const getProcessFileWriteBinaryContents = (config) => (qpqConfig) => {
|
|
|
19
19
|
}
|
|
20
20
|
catch (error) {
|
|
21
21
|
return actionResultErrorFromCaughtError(error, {
|
|
22
|
+
InvalidScopeError: (error) => actionResultError(FileWriteBinaryContentsErrorTypeEnum.InvalidScope, error.message),
|
|
22
23
|
EACCES: () => actionResultError(FileWriteBinaryContentsErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
|
|
23
24
|
});
|
|
24
25
|
}
|
package/lib/esm/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileWriteBinaryContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,oCAAoC,GAErC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,iCAAiC,GACrC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAA0C,EAAE;IAC/D,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"getFileWriteBinaryContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,oCAAoC,GAErC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,iCAAiC,GACrC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAA0C,EAAE;IAC/D,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAE5C,kCAAkC;YAClC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACtD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAErC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC7C,MAAM,EAAE,CAAC,SAAS,CAChB,GAAG,QAAQ,eAAe,EAC1B,IAAI,CAAC,SAAS,CAAC;oBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;iBAC5C,CAAC,CACH,CAAC;YACJ,CAAC;YAED,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,oCAAoC,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;gBACjH,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,oCAAoC,CAAC,YAAY,EAAE,+BAA+B,QAAQ,EAAE,CAAC,EAAE,eAAe;aAC/I,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,yCAAyC,GACpD,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,mBAAmB,CAAC,EAAE,iCAAiC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;CAC3F,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileWriteBinaryContentsActionProcessor,\n FileWriteBinaryContentsErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\n\nimport { FileStorageConfig } from './types';\nimport { ensureParentDirectoryExists, resolveFilePath } from './utils';\n\nconst getProcessFileWriteBinaryContents =\n (config: FileStorageConfig) =>\n (qpqConfig: QPQConfig): FileWriteBinaryContentsActionProcessor => {\n return async ({ drive, filepath, data, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n await ensureParentDirectoryExists(fullPath);\n\n // Convert QPQBinaryData to Buffer\n const buffer = Buffer.from(data.base64Data, 'base64');\n await fs.writeFile(fullPath, buffer);\n\n if (data.mimetype || data.contentDisposition) {\n await fs.writeFile(\n `${fullPath}.qpqmeta.json`,\n JSON.stringify({\n mimetype: data.mimetype,\n contentDisposition: data.contentDisposition,\n }),\n );\n }\n\n return actionResult(void 0);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileWriteBinaryContentsErrorTypeEnum.InvalidScope, error.message),\n EACCES: () => actionResultError(FileWriteBinaryContentsErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code\n });\n }\n };\n };\n\nexport const getFileWriteBinaryContentsActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.WriteBinaryContents]: getProcessFileWriteBinaryContents(config)(qpqConfig),\n });\n"]}
|
|
@@ -2,9 +2,9 @@ import { actionResult, actionResultError, actionResultErrorFromCaughtError, File
|
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import { ensureParentDirectoryExists, resolveFilePath } from './utils';
|
|
4
4
|
const getProcessFileWriteObjectJson = (config) => (qpqConfig) => {
|
|
5
|
-
return async ({ drive, filepath, data }) => {
|
|
5
|
+
return async ({ drive, filepath, data, scope }) => {
|
|
6
6
|
try {
|
|
7
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
7
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
8
8
|
await ensureParentDirectoryExists(fullPath);
|
|
9
9
|
const jsonString = JSON.stringify(data, null, 2);
|
|
10
10
|
await fs.writeFile(fullPath, jsonString, 'utf8');
|
|
@@ -12,6 +12,7 @@ const getProcessFileWriteObjectJson = (config) => (qpqConfig) => {
|
|
|
12
12
|
}
|
|
13
13
|
catch (error) {
|
|
14
14
|
return actionResultErrorFromCaughtError(error, {
|
|
15
|
+
InvalidScopeError: (error) => actionResultError(FileWriteObjectJsonErrorTypeEnum.InvalidScope, error.message),
|
|
15
16
|
EACCES: () => actionResultError(FileWriteObjectJsonErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
|
|
16
17
|
});
|
|
17
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileWriteObjectJsonActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,gCAAgC,GAEjC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,6BAA6B,GACjC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAA2C,EAAE;IAChE,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"getFileWriteObjectJsonActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,gCAAgC,GAEjC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,6BAA6B,GACjC,CAAC,MAAyB,EAAE,EAAE,CAC9B,CAAC,SAAoB,EAA2C,EAAE;IAChE,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACjD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YACjD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,gCAAgC,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;gBAC7G,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,gCAAgC,CAAC,YAAY,EAAE,+BAA+B,QAAQ,EAAE,CAAC,EAAE,eAAe;aAC3I,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,qCAAqC,GAChD,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,6BAA6B,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;CACnF,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileWriteObjectJsonActionProcessor,\n FileWriteObjectJsonErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\n\nimport { FileStorageConfig } from './types';\nimport { ensureParentDirectoryExists, resolveFilePath } from './utils';\n\nconst getProcessFileWriteObjectJson =\n (config: FileStorageConfig) =>\n (qpqConfig: QPQConfig): FileWriteObjectJsonActionProcessor<any> => {\n return async ({ drive, filepath, data, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n await ensureParentDirectoryExists(fullPath);\n const jsonString = JSON.stringify(data, null, 2);\n await fs.writeFile(fullPath, jsonString, 'utf8');\n return actionResult(void 0);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileWriteObjectJsonErrorTypeEnum.InvalidScope, error.message),\n EACCES: () => actionResultError(FileWriteObjectJsonErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code\n });\n }\n };\n };\n\nexport const getFileWriteObjectJsonActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.WriteObjectJson]: getProcessFileWriteObjectJson(config)(qpqConfig),\n });\n"]}
|
|
@@ -2,15 +2,16 @@ import { actionResult, actionResultError, actionResultErrorFromCaughtError, File
|
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import { ensureParentDirectoryExists, resolveFilePath } from './utils';
|
|
4
4
|
const getProcessFileWriteTextContents = (qpqConfig, config) => {
|
|
5
|
-
return async ({ drive, filepath, data }) => {
|
|
5
|
+
return async ({ drive, filepath, data, scope }) => {
|
|
6
6
|
try {
|
|
7
|
-
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath);
|
|
7
|
+
const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);
|
|
8
8
|
await ensureParentDirectoryExists(fullPath);
|
|
9
9
|
await fs.writeFile(fullPath, data, 'utf8');
|
|
10
10
|
return actionResult(void 0);
|
|
11
11
|
}
|
|
12
12
|
catch (error) {
|
|
13
13
|
return actionResultErrorFromCaughtError(error, {
|
|
14
|
+
InvalidScopeError: (error) => actionResultError(FileWriteTextContentsErrorTypeEnum.InvalidScope, error.message),
|
|
14
15
|
EACCES: () => actionResultError(FileWriteTextContentsErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code
|
|
15
16
|
});
|
|
16
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileWriteTextContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,kCAAkC,GAEnC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,+BAA+B,GAAG,CAAC,SAAoB,EAAE,MAAyB,EAAwC,EAAE;IAChI,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"getFileWriteTextContentsActionProcessor.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EAEd,kCAAkC,GAEnC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,+BAA+B,GAAG,CAAC,SAAoB,EAAE,MAAyB,EAAwC,EAAE;IAChI,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,2BAA2B,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3C,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,gCAAgC,CAAC,KAAK,EAAE;gBAC7C,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,kCAAkC,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC;gBAC/G,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,kCAAkC,CAAC,YAAY,EAAE,+BAA+B,QAAQ,EAAE,CAAC,EAAE,eAAe;aAC7I,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uCAAuC,GAClD,CAAC,MAAyB,EAA+B,EAAE,CAC3D,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,+BAA+B,CAAC,SAAS,EAAE,MAAM,CAAC;CACvF,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n actionResultErrorFromCaughtError,\n FileActionType,\n FileWriteTextContentsActionProcessor,\n FileWriteTextContentsErrorTypeEnum,\n QPQConfig,\n} from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\n\nimport { FileStorageConfig } from './types';\nimport { ensureParentDirectoryExists, resolveFilePath } from './utils';\n\nconst getProcessFileWriteTextContents = (qpqConfig: QPQConfig, config: FileStorageConfig): FileWriteTextContentsActionProcessor => {\n return async ({ drive, filepath, data, scope }) => {\n try {\n const fullPath = resolveFilePath(config, qpqConfig, drive, filepath, scope);\n await ensureParentDirectoryExists(fullPath);\n await fs.writeFile(fullPath, data, 'utf8');\n return actionResult(void 0);\n } catch (error: unknown) {\n return actionResultErrorFromCaughtError(error, {\n InvalidScopeError: (error) => actionResultError(FileWriteTextContentsErrorTypeEnum.InvalidScope, error.message),\n EACCES: () => actionResultError(FileWriteTextContentsErrorTypeEnum.AccessDenied, `Access denied writing file: ${filepath}`), // node fs code\n });\n }\n };\n};\n\nexport const getFileWriteTextContentsActionProcessor =\n (config: FileStorageConfig): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [FileActionType.WriteTextContents]: getProcessFileWriteTextContents(qpqConfig, config),\n });\n"]}
|
|
@@ -2,6 +2,6 @@ import { QPQConfig } from 'quidproquo-core';
|
|
|
2
2
|
import { FileStorageConfig } from './types';
|
|
3
3
|
export declare const isStorageDriveNameValid: (drive: string, qpqConfig: QPQConfig) => boolean;
|
|
4
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
|
+
export declare function resolveFilePath(fileStorageConfig: FileStorageConfig, qpqConfig: QPQConfig, drive: string, filepath: string, scope?: string): string;
|
|
6
6
|
export declare const ensureDirectoryExists: (dirPath: string) => Promise<void>;
|
|
7
7
|
export declare const ensureParentDirectoryExists: (filePath: string) => Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { qpqCoreUtils } from 'quidproquo-core';
|
|
1
|
+
import { qpqCoreUtils, validateScopeSegment } from 'quidproquo-core';
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
// Resolve a drive name to a filesystem path
|
|
@@ -16,9 +16,16 @@ export function resolveDriveServiceName(drive, qpqConfig) {
|
|
|
16
16
|
const storageDrive = qpqCoreUtils.getStorageDriveByName(drive, qpqConfig);
|
|
17
17
|
return storageDrive?.owner?.module ?? qpqCoreUtils.getApplicationModuleName(qpqConfig);
|
|
18
18
|
}
|
|
19
|
-
export function resolveFilePath(fileStorageConfig, qpqConfig, drive, filepath) {
|
|
19
|
+
export function resolveFilePath(fileStorageConfig, qpqConfig, drive, filepath, scope) {
|
|
20
20
|
const service = resolveDriveServiceName(drive, qpqConfig);
|
|
21
|
-
|
|
21
|
+
// A scope becomes part of the root, so the escape check below also guarantees
|
|
22
|
+
// the filepath cannot traverse out of its scope, not just out of the drive.
|
|
23
|
+
if (scope !== undefined) {
|
|
24
|
+
validateScopeSegment(scope);
|
|
25
|
+
}
|
|
26
|
+
const root = scope
|
|
27
|
+
? path.resolve(fileStorageConfig.storagePath, service, drive, scope)
|
|
28
|
+
: path.resolve(fileStorageConfig.storagePath, service, drive);
|
|
22
29
|
// Block absolute paths and null bytes outright
|
|
23
30
|
if (path.isAbsolute(filepath)) {
|
|
24
31
|
throw new Error('Absolute paths are not allowed.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/dynamicActionProcessor/file/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { QPQConfig, qpqCoreUtils, validateScopeSegment } from 'quidproquo-core';\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nimport { FileStorageConfig } from './types';\n\n// Resolve a drive name to a filesystem path\nexport const isStorageDriveNameValid = (drive: string, qpqConfig: QPQConfig): boolean => {\n const storageDrive = qpqCoreUtils.getStorageDrives(qpqConfig).find((d) => d.storageDrive === drive);\n\n if (!storageDrive) {\n return false;\n }\n\n return true;\n};\n\n// Resolve the service that owns a drive's on-disk location. Drives declared with\n// `owner.module` are shared across services, so every caller reads and writes\n// under the owner's folder — mirroring how AWS resolves the bucket by owner.\nexport function resolveDriveServiceName(drive: string, qpqConfig: QPQConfig): string {\n const storageDrive = qpqCoreUtils.getStorageDriveByName(drive, qpqConfig);\n return storageDrive?.owner?.module ?? qpqCoreUtils.getApplicationModuleName(qpqConfig);\n}\n\nexport function resolveFilePath(fileStorageConfig: FileStorageConfig, qpqConfig: QPQConfig, drive: string, filepath: string, scope?: string): string {\n const service = resolveDriveServiceName(drive, qpqConfig);\n\n // A scope becomes part of the root, so the escape check below also guarantees\n // the filepath cannot traverse out of its scope, not just out of the drive.\n if (scope !== undefined) {\n validateScopeSegment(scope);\n }\n\n const root = scope\n ? path.resolve(fileStorageConfig.storagePath, service, drive, scope)\n : path.resolve(fileStorageConfig.storagePath, service, drive);\n\n // Block absolute paths and null bytes outright\n if (path.isAbsolute(filepath)) {\n throw new Error('Absolute paths are not allowed.');\n }\n\n // Check for null to prevent directory traversal attacks in native libs\n if (filepath.includes('\\0')) {\n throw new Error('Invalid path.');\n }\n\n // Normalize user input (collapses ., .., slashes)\n const cleaned = path.normalize(filepath);\n\n // Resolve against the root\n const target = path.resolve(root, cleaned);\n\n // Ensure target stays within root\n const rel = path.relative(root, target);\n if (rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel))) {\n return target;\n }\n\n throw new Error('Invalid file path: escapes drive root.');\n}\n\n// Ensure a directory exists\nexport const ensureDirectoryExists = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\n// Ensure the parent directory of a file exists\nexport const ensureParentDirectoryExists = async (filePath: string): Promise<void> => {\n const parentDir = path.dirname(filePath);\n await ensureDirectoryExists(parentDir);\n};\n"]}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { ActionProcessorListResolver } from 'quidproquo-core';
|
|
2
|
-
export
|
|
1
|
+
import { ActionProcessorListResolver, QPQConfig, QpqFunctionRuntime } from 'quidproquo-core';
|
|
2
|
+
export type OwnCodeMarkersResolver = (qpqFunctionRuntimeInfo: QpqFunctionRuntime | undefined, qpqConfig: QPQConfig) => string[] | undefined;
|
|
3
|
+
export declare const getSystemTraceStoryActionProcessor: (defaultScriptPatterns?: string[], resolveOwnCodeMarkers?: OwnCodeMarkersResolver) => ActionProcessorListResolver;
|
|
@@ -4,7 +4,7 @@ import { traceStoryExecution } from './traceStoryExecution';
|
|
|
4
4
|
// Loads the recorded story's real code through the runtime's dynamicModuleLoader (which
|
|
5
5
|
// federates on lambda), then replays it under the tracer. defaultScriptPatterns lets the
|
|
6
6
|
// host add environment-specific scripts to trace (e.g. the lambda federated code cache).
|
|
7
|
-
const getProcessTraceStory = (qpqConfig, defaultScriptPatterns) => {
|
|
7
|
+
const getProcessTraceStory = (qpqConfig, defaultScriptPatterns, resolveOwnCodeMarkers) => {
|
|
8
8
|
return async (payload, session, actionProcessors, logger, updateSession, dynamicModuleLoader) => {
|
|
9
9
|
const { storyResult, scriptPatterns, onlyOwnCode } = payload;
|
|
10
10
|
if (!storyResult.qpqFunctionRuntimeInfo) {
|
|
@@ -18,6 +18,7 @@ const getProcessTraceStory = (qpqConfig, defaultScriptPatterns) => {
|
|
|
18
18
|
const { trace } = await traceStoryExecution(storyResult, story, {
|
|
19
19
|
scriptPatterns: [...defaultScriptPatterns, ...(scriptPatterns || [])],
|
|
20
20
|
onlyOwnCode,
|
|
21
|
+
ownCodeMarkers: resolveOwnCodeMarkers?.(storyResult.qpqFunctionRuntimeInfo, qpqConfig),
|
|
21
22
|
});
|
|
22
23
|
return actionResult(trace);
|
|
23
24
|
}
|
|
@@ -26,7 +27,7 @@ const getProcessTraceStory = (qpqConfig, defaultScriptPatterns) => {
|
|
|
26
27
|
}
|
|
27
28
|
};
|
|
28
29
|
};
|
|
29
|
-
export const getSystemTraceStoryActionProcessor = (defaultScriptPatterns = []) => async (qpqConfig) => ({
|
|
30
|
-
[SystemActionType.TraceStory]: getProcessTraceStory(qpqConfig, defaultScriptPatterns),
|
|
30
|
+
export const getSystemTraceStoryActionProcessor = (defaultScriptPatterns = [], resolveOwnCodeMarkers) => async (qpqConfig) => ({
|
|
31
|
+
[SystemActionType.TraceStory]: getProcessTraceStory(qpqConfig, defaultScriptPatterns, resolveOwnCodeMarkers),
|
|
31
32
|
});
|
|
32
33
|
//# sourceMappingURL=getSystemTraceStoryActionProcessor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSystemTraceStoryActionProcessor.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/getSystemTraceStoryActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EAEjB,aAAa,
|
|
1
|
+
{"version":3,"file":"getSystemTraceStoryActionProcessor.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/getSystemTraceStoryActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EAEjB,aAAa,EAMb,gBAAgB,GAGjB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAS5D,qFAAqF;AACrF,wFAAwF;AACxF,yFAAyF;AACzF,yFAAyF;AACzF,MAAM,oBAAoB,GAAG,CAC3B,SAAoB,EACpB,qBAA+B,EAC/B,qBAA8C,EACb,EAAE;IACnC,OAAO,KAAK,EACV,OAAsC,EACtC,OAAqB,EACrB,gBAAqC,EACrC,MAAiB,EACjB,aAAkC,EAClC,mBAAwC,EACxC,EAAE;QACF,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;QAE7D,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE,CAAC;YACxC,OAAO,iBAAiB,CACtB,aAAa,CAAC,UAAU,EACxB,UAAU,WAAW,CAAC,WAAW,mEAAmE,CACrG,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC;QAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,iBAAiB,CAAC,aAAa,CAAC,QAAQ,EAAE,yCAAyC,WAAW,CAAC,WAAW,GAAG,CAAC,CAAC;QACxH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,KAAK,EAAE;gBAC9D,cAAc,EAAE,CAAC,GAAG,qBAAqB,EAAE,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;gBACrE,WAAW;gBACX,cAAc,EAAE,qBAAqB,EAAE,CAAC,WAAW,CAAC,sBAAsB,EAAE,SAAS,CAAC;aACvF,CAAC,CAAC;YAEH,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,iBAAiB,CAAC,aAAa,CAAC,YAAY,EAAE,qBAAqB,WAAW,CAAC,WAAW,MAAO,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACrI,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAC7C,CAAC,wBAAkC,EAAE,EAAE,qBAA8C,EAA+B,EAAE,CACtH,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC,SAAS,EAAE,qBAAqB,EAAE,qBAAqB,CAAC;CAC7G,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n DynamicModuleLoader,\n ErrorTypeEnum,\n QPQConfig,\n QpqFunctionRuntime,\n QpqLogger,\n StorySession,\n StorySessionUpdater,\n SystemActionType,\n SystemTraceStoryActionPayload,\n SystemTraceStoryActionProcessor,\n} from 'quidproquo-core';\n\nimport { traceStoryExecution } from './traceStoryExecution';\n\n// Resolves extra own-code markers (see resolveSourceMaps.filterOwnCodeLocations) for the\n// story being traced. Opt-in: lambda's federated remotes stay on the plain \"not\n// node_modules\" heuristic that already works for them; hosts whose bundle layout defeats\n// that heuristic (the dev server bundles every hosted service plus the whole framework\n// into one script) pass a resolver to narrow onlyOwnCode to the traced service.\nexport type OwnCodeMarkersResolver = (qpqFunctionRuntimeInfo: QpqFunctionRuntime | undefined, qpqConfig: QPQConfig) => string[] | undefined;\n\n// Shared System::TraceStory processor for node runtimes (lambda and the dev server).\n// Loads the recorded story's real code through the runtime's dynamicModuleLoader (which\n// federates on lambda), then replays it under the tracer. defaultScriptPatterns lets the\n// host add environment-specific scripts to trace (e.g. the lambda federated code cache).\nconst getProcessTraceStory = (\n qpqConfig: QPQConfig,\n defaultScriptPatterns: string[],\n resolveOwnCodeMarkers?: OwnCodeMarkersResolver,\n): SystemTraceStoryActionProcessor => {\n return async (\n payload: SystemTraceStoryActionPayload,\n session: StorySession,\n actionProcessors: ActionProcessorList,\n logger: QpqLogger,\n updateSession: StorySessionUpdater,\n dynamicModuleLoader: DynamicModuleLoader,\n ) => {\n const { storyResult, scriptPatterns, onlyOwnCode } = payload;\n\n if (!storyResult.qpqFunctionRuntimeInfo) {\n return actionResultError(\n ErrorTypeEnum.BadRequest,\n `Story [${storyResult.correlation}] has no qpqFunctionRuntimeInfo - cannot locate its code to trace`,\n );\n }\n\n const story = await dynamicModuleLoader(storyResult.qpqFunctionRuntimeInfo);\n if (!story) {\n return actionResultError(ErrorTypeEnum.NotFound, `Unable to dynamically load story for [${storyResult.correlation}]`);\n }\n\n try {\n const { trace } = await traceStoryExecution(storyResult, story, {\n scriptPatterns: [...defaultScriptPatterns, ...(scriptPatterns || [])],\n onlyOwnCode,\n ownCodeMarkers: resolveOwnCodeMarkers?.(storyResult.qpqFunctionRuntimeInfo, qpqConfig),\n });\n\n return actionResult(trace);\n } catch (error) {\n return actionResultError(ErrorTypeEnum.GenericError, `Trace failed for [${storyResult.correlation}]: ${(error as Error).message}`);\n }\n };\n};\n\nexport const getSystemTraceStoryActionProcessor =\n (defaultScriptPatterns: string[] = [], resolveOwnCodeMarkers?: OwnCodeMarkersResolver): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [SystemActionType.TraceStory]: getProcessTraceStory(qpqConfig, defaultScriptPatterns, resolveOwnCodeMarkers),\n });\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,uBAAuB,CAAC","sourcesContent":["export * from './getSystemTraceStoryActionProcessor';\nexport * from './traceStoryExecution';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC","sourcesContent":["export * from './getSystemTraceStoryActionProcessor';\nexport * from './resolveSourceMaps';\nexport * from './traceStoryExecution';\n"]}
|
|
@@ -10,7 +10,8 @@ interface RawTraceStep {
|
|
|
10
10
|
export declare const filterOwnCodeLocations: <TLocation extends {
|
|
11
11
|
lineNumber: number;
|
|
12
12
|
columnNumber?: number;
|
|
13
|
-
}>(scriptUrl: string, locations: TLocation[]) => TLocation[];
|
|
13
|
+
}>(scriptUrl: string, locations: TLocation[], ownCodeMarkers?: string[]) => TLocation[];
|
|
14
|
+
export declare const getOwnCodeMarkersFromRoot: (root: string) => string[];
|
|
14
15
|
export interface ResolvedTraceSteps {
|
|
15
16
|
sources: QpqExecutionTraceSource[];
|
|
16
17
|
steps: QpqExecutionTraceStep[];
|
|
@@ -42,16 +42,36 @@ const loadTraceMap = (scriptPath) => {
|
|
|
42
42
|
// worker can't load trace-mapping itself). Positions mapping into node_modules
|
|
43
43
|
// (framework/deps) or not mapping at all (webpack runtime glue) are dropped. No map
|
|
44
44
|
// means the bundle can't be classified — everything stays traced.
|
|
45
|
-
|
|
45
|
+
//
|
|
46
|
+
// ownCodeMarkers is a second, opt-in signal: substrings identifying the traced story's
|
|
47
|
+
// own source root. The node_modules check alone assumes framework/deps are bundled from
|
|
48
|
+
// real node_modules — true for lambda's federated remotes, but not for hosts (the dev
|
|
49
|
+
// server) that bundle workspace framework packages from source alongside every hosted
|
|
50
|
+
// service in one script, where framework code never lands in node_modules either. When
|
|
51
|
+
// markers are given, a location must ALSO map into one of them to count as own code.
|
|
52
|
+
export const filterOwnCodeLocations = (scriptUrl, locations, ownCodeMarkers) => {
|
|
46
53
|
const traceMap = scriptUrl ? loadTraceMap(scriptUrlToPath(scriptUrl)) : null;
|
|
47
54
|
if (!traceMap) {
|
|
48
55
|
return locations;
|
|
49
56
|
}
|
|
50
57
|
return locations.filter((location) => {
|
|
51
58
|
const original = originalPositionFor(traceMap, { line: location.lineNumber + 1, column: location.columnNumber ?? 0 });
|
|
52
|
-
|
|
59
|
+
if (!original.source || original.source.includes('node_modules'))
|
|
60
|
+
return false;
|
|
61
|
+
return !ownCodeMarkers?.length || ownCodeMarkers.some((marker) => original.source.includes(marker));
|
|
53
62
|
});
|
|
54
63
|
};
|
|
64
|
+
// Derives own-code markers from a service's absolute source root (QpqFunctionRuntimeAdvanced.basePath,
|
|
65
|
+
// or getApplicationConfigRoot(qpqConfig) for the relative-string runtime form). Bundlers emit
|
|
66
|
+
// source-map `source` entries as either real filesystem paths or webpack://<namespace>/./<path
|
|
67
|
+
// relative to the build context> pseudo urls — both preserve the original directory names
|
|
68
|
+
// verbatim, so matching on the root's own trailing segments works for either form without
|
|
69
|
+
// needing to know the bundler's exact context/namespace.
|
|
70
|
+
export const getOwnCodeMarkersFromRoot = (root) => {
|
|
71
|
+
const normalized = root.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
72
|
+
const tailSegments = normalized.split('/').filter(Boolean).slice(-3).join('/');
|
|
73
|
+
return tailSegments && tailSegments !== normalized ? [normalized, tailSegments] : [normalized];
|
|
74
|
+
};
|
|
55
75
|
export const resolveSourceMappedSteps = (rawSteps, scriptUrlsById) => {
|
|
56
76
|
const traceMapsByScriptId = new Map();
|
|
57
77
|
const sourceIndexByPath = new Map();
|