@strapi/data-transfer 5.42.1 → 5.44.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 (126) hide show
  1. package/dist/directory/providers/source/index.d.ts.map +1 -1
  2. package/dist/directory/providers/source/index.js +3 -2
  3. package/dist/directory/providers/source/index.js.map +1 -1
  4. package/dist/directory/providers/source/index.mjs +3 -2
  5. package/dist/directory/providers/source/index.mjs.map +1 -1
  6. package/dist/engine/index.d.ts.map +1 -1
  7. package/dist/engine/index.js +130 -5
  8. package/dist/engine/index.js.map +1 -1
  9. package/dist/engine/index.mjs +130 -5
  10. package/dist/engine/index.mjs.map +1 -1
  11. package/dist/engine/validation/schemas/index.js +2 -0
  12. package/dist/engine/validation/schemas/index.js.map +1 -1
  13. package/dist/engine/validation/schemas/index.mjs +2 -0
  14. package/dist/engine/validation/schemas/index.mjs.map +1 -1
  15. package/dist/file/providers/source/index.d.ts.map +1 -1
  16. package/dist/file/providers/source/index.js +84 -45
  17. package/dist/file/providers/source/index.js.map +1 -1
  18. package/dist/file/providers/source/index.mjs +85 -46
  19. package/dist/file/providers/source/index.mjs.map +1 -1
  20. package/dist/strapi/providers/index.js +2 -0
  21. package/dist/strapi/providers/index.js.map +1 -1
  22. package/dist/strapi/providers/index.mjs +1 -0
  23. package/dist/strapi/providers/index.mjs.map +1 -1
  24. package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts +22 -0
  25. package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts.map +1 -0
  26. package/dist/strapi/providers/local-destination/assets-destination-writable.js +107 -0
  27. package/dist/strapi/providers/local-destination/assets-destination-writable.js.map +1 -0
  28. package/dist/strapi/providers/local-destination/assets-destination-writable.mjs +105 -0
  29. package/dist/strapi/providers/local-destination/assets-destination-writable.mjs.map +1 -0
  30. package/dist/strapi/providers/local-destination/index.d.ts +2 -0
  31. package/dist/strapi/providers/local-destination/index.d.ts.map +1 -1
  32. package/dist/strapi/providers/local-destination/index.js +18 -79
  33. package/dist/strapi/providers/local-destination/index.js.map +1 -1
  34. package/dist/strapi/providers/local-destination/index.mjs +18 -79
  35. package/dist/strapi/providers/local-destination/index.mjs.map +1 -1
  36. package/dist/strapi/providers/local-destination/strategies/restore/entities.js +2 -0
  37. package/dist/strapi/providers/local-destination/strategies/restore/entities.js.map +1 -1
  38. package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs +2 -0
  39. package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs.map +1 -1
  40. package/dist/strapi/providers/local-destination/strategies/restore/index.js +2 -0
  41. package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -1
  42. package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +2 -0
  43. package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -1
  44. package/dist/strapi/providers/local-source/assets.d.ts +8 -1
  45. package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
  46. package/dist/strapi/providers/local-source/assets.js +47 -19
  47. package/dist/strapi/providers/local-source/assets.js.map +1 -1
  48. package/dist/strapi/providers/local-source/assets.mjs +46 -20
  49. package/dist/strapi/providers/local-source/assets.mjs.map +1 -1
  50. package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts +11 -0
  51. package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts.map +1 -0
  52. package/dist/strapi/providers/local-source/estimate-asset-totals.js +130 -0
  53. package/dist/strapi/providers/local-source/estimate-asset-totals.js.map +1 -0
  54. package/dist/strapi/providers/local-source/estimate-asset-totals.mjs +128 -0
  55. package/dist/strapi/providers/local-source/estimate-asset-totals.mjs.map +1 -0
  56. package/dist/strapi/providers/local-source/index.d.ts +3 -2
  57. package/dist/strapi/providers/local-source/index.d.ts.map +1 -1
  58. package/dist/strapi/providers/local-source/index.js +30 -3
  59. package/dist/strapi/providers/local-source/index.js.map +1 -1
  60. package/dist/strapi/providers/local-source/index.mjs +30 -4
  61. package/dist/strapi/providers/local-source/index.mjs.map +1 -1
  62. package/dist/strapi/providers/remote-destination/index.d.ts +3 -1
  63. package/dist/strapi/providers/remote-destination/index.d.ts.map +1 -1
  64. package/dist/strapi/providers/remote-destination/index.js +88 -19
  65. package/dist/strapi/providers/remote-destination/index.js.map +1 -1
  66. package/dist/strapi/providers/remote-destination/index.mjs +89 -20
  67. package/dist/strapi/providers/remote-destination/index.mjs.map +1 -1
  68. package/dist/strapi/providers/remote-source/index.d.ts +6 -3
  69. package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
  70. package/dist/strapi/providers/remote-source/index.js +180 -47
  71. package/dist/strapi/providers/remote-source/index.js.map +1 -1
  72. package/dist/strapi/providers/remote-source/index.mjs +181 -48
  73. package/dist/strapi/providers/remote-source/index.mjs.map +1 -1
  74. package/dist/strapi/providers/utils.d.ts +9 -6
  75. package/dist/strapi/providers/utils.d.ts.map +1 -1
  76. package/dist/strapi/providers/utils.js +9 -4
  77. package/dist/strapi/providers/utils.js.map +1 -1
  78. package/dist/strapi/providers/utils.mjs +9 -4
  79. package/dist/strapi/providers/utils.mjs.map +1 -1
  80. package/dist/strapi/remote/handlers/pull.d.ts +1 -0
  81. package/dist/strapi/remote/handlers/pull.d.ts.map +1 -1
  82. package/dist/strapi/remote/handlers/pull.js +36 -15
  83. package/dist/strapi/remote/handlers/pull.js.map +1 -1
  84. package/dist/strapi/remote/handlers/pull.mjs +37 -16
  85. package/dist/strapi/remote/handlers/pull.mjs.map +1 -1
  86. package/dist/strapi/remote/handlers/push.d.ts +13 -2
  87. package/dist/strapi/remote/handlers/push.d.ts.map +1 -1
  88. package/dist/strapi/remote/handlers/push.js +81 -34
  89. package/dist/strapi/remote/handlers/push.js.map +1 -1
  90. package/dist/strapi/remote/handlers/push.mjs +82 -35
  91. package/dist/strapi/remote/handlers/push.mjs.map +1 -1
  92. package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
  93. package/dist/strapi/remote/handlers/utils.js +5 -3
  94. package/dist/strapi/remote/handlers/utils.js.map +1 -1
  95. package/dist/strapi/remote/handlers/utils.mjs +5 -3
  96. package/dist/strapi/remote/handlers/utils.mjs.map +1 -1
  97. package/dist/utils/index.d.ts +2 -0
  98. package/dist/utils/index.d.ts.map +1 -1
  99. package/dist/utils/index.js +7 -0
  100. package/dist/utils/index.js.map +1 -1
  101. package/dist/utils/index.mjs +2 -0
  102. package/dist/utils/index.mjs.map +1 -1
  103. package/dist/utils/stream.d.ts.map +1 -1
  104. package/dist/utils/stream.js +40 -3
  105. package/dist/utils/stream.js.map +1 -1
  106. package/dist/utils/stream.mjs +40 -3
  107. package/dist/utils/stream.mjs.map +1 -1
  108. package/dist/utils/transfer-asset-chunk.d.ts +41 -0
  109. package/dist/utils/transfer-asset-chunk.d.ts.map +1 -0
  110. package/dist/utils/transfer-asset-chunk.js +93 -0
  111. package/dist/utils/transfer-asset-chunk.js.map +1 -0
  112. package/dist/utils/transfer-asset-chunk.mjs +88 -0
  113. package/dist/utils/transfer-asset-chunk.mjs.map +1 -0
  114. package/dist/utils/transfer-websocket-json.d.ts +24 -0
  115. package/dist/utils/transfer-websocket-json.d.ts.map +1 -0
  116. package/dist/utils/transfer-websocket-json.js +67 -0
  117. package/dist/utils/transfer-websocket-json.js.map +1 -0
  118. package/dist/utils/transfer-websocket-json.mjs +63 -0
  119. package/dist/utils/transfer-websocket-json.mjs.map +1 -0
  120. package/dist/utils/writable-async-write.d.ts +17 -0
  121. package/dist/utils/writable-async-write.d.ts.map +1 -0
  122. package/dist/utils/writable-async-write.js +61 -0
  123. package/dist/utils/writable-async-write.js.map +1 -0
  124. package/dist/utils/writable-async-write.mjs +59 -0
  125. package/dist/utils/writable-async-write.mjs.map +1 -0
  126. package/package.json +8 -8
@@ -3,6 +3,7 @@
3
3
  var crypto = require('crypto');
4
4
  var ws = require('ws');
5
5
  var providers = require('../../errors/providers.js');
6
+ var transferWebsocketJson = require('../../utils/transfer-websocket-json.js');
6
7
 
7
8
  const createDispatcher = (ws, retryMessageOptions = {
8
9
  retryMessageMaxRetries: 5,
@@ -31,13 +32,16 @@ const createDispatcher = (ws, retryMessageOptions = {
31
32
  const messageToSend = message;
32
33
  reportInfo?.(`dispatching message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`);
33
34
  }
34
- const stringifiedPayload = JSON.stringify(payload);
35
+ const stringifiedPayload = transferWebsocketJson.stringifyTransferWebSocketPayload(payload);
35
36
  ws.send(stringifiedPayload, (error)=>{
36
37
  if (error) {
37
38
  reject(error);
38
39
  }
39
40
  });
40
- const { retryMessageMaxRetries, retryMessageTimeout } = retryMessageOptions;
41
+ const { retryMessageMaxRetries, retryMessageTimeout } = {
42
+ ...retryMessageOptions,
43
+ ...options.retryOverrides
44
+ };
41
45
  const sendPeriodically = ()=>{
42
46
  if (numberOfTimesMessageWasSent <= retryMessageMaxRetries) {
43
47
  numberOfTimesMessageWasSent += 1;
@@ -99,14 +103,15 @@ const createDispatcher = (ws, retryMessageOptions = {
99
103
  attachTransfer: true
100
104
  }) ?? Promise.resolve(null);
101
105
  };
102
- const dispatchTransferStep = async (payload)=>{
106
+ const dispatchTransferStep = async (payload, dispatchOptions)=>{
103
107
  const message = {
104
108
  type: 'transfer',
105
109
  kind: 'step',
106
110
  ...payload
107
111
  };
108
112
  return dispatch(message, {
109
- attachTransfer: true
113
+ attachTransfer: true,
114
+ ...dispatchOptions
110
115
  }) ?? Promise.resolve(null);
111
116
  };
112
117
  const setTransferProperties = (properties)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/strapi/providers/utils.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { RawData, WebSocket } from 'ws';\n\nimport type { Client, Server } from '../../../types/remote/protocol';\n\nimport {\n ProviderError,\n ProviderTransferError,\n ProviderInitializationError,\n ProviderValidationError,\n ProviderErrorDetails,\n} from '../../errors/providers';\nimport { IDiagnosticReporter } from '../../utils/diagnostic';\n\ninterface IDispatcherState {\n transfer?: { kind: Client.TransferKind; id: string };\n}\n\ninterface IDispatchOptions {\n attachTransfer?: boolean;\n}\n\ntype Dispatch<T> = Omit<T, 'transferID' | 'uuid'>;\n\nexport const createDispatcher = (\n ws: WebSocket,\n retryMessageOptions = {\n retryMessageMaxRetries: 5,\n retryMessageTimeout: 30000,\n },\n reportInfo?: (message: string) => void\n) => {\n const state: IDispatcherState = {};\n\n type DispatchMessage = Dispatch<Client.Message>;\n\n const dispatch = async <U = null>(\n message: DispatchMessage,\n options: IDispatchOptions = {}\n ): Promise<U | null> => {\n if (!ws) {\n throw new Error('No websocket connection found');\n }\n\n return new Promise<U | null>((resolve, reject) => {\n const uuid = randomUUID();\n const payload = { ...message, uuid };\n let numberOfTimesMessageWasSent = 0;\n\n if (options.attachTransfer) {\n Object.assign(payload, { transferID: state.transfer?.id });\n }\n\n if (message.type === 'command') {\n reportInfo?.(\n `dispatching message command:${(message as Client.CommandMessage).command} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `dispatching message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n const stringifiedPayload = JSON.stringify(payload);\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n const { retryMessageMaxRetries, retryMessageTimeout } = retryMessageOptions;\n const sendPeriodically = () => {\n if (numberOfTimesMessageWasSent <= retryMessageMaxRetries) {\n numberOfTimesMessageWasSent += 1;\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n } else {\n reject(new ProviderError('error', 'Request timed out'));\n }\n };\n const interval = setInterval(sendPeriodically, retryMessageTimeout);\n\n const onResponse = (raw: RawData) => {\n const response: Server.Message<U> = JSON.parse(raw.toString());\n if (message.type === 'command') {\n reportInfo?.(\n `received response to message command: ${(message as Client.CommandMessage).command} uuid: ${uuid} sent: ${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `received response to message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n if (response.uuid === uuid) {\n clearInterval(interval);\n if (response.error) {\n const message = response.error.message;\n const details = response.error.details?.details as ProviderErrorDetails;\n const step = response.error.details?.step;\n let error = new ProviderError('error', message, details);\n if (step === 'transfer') {\n error = new ProviderTransferError(message, details);\n } else if (step === 'validation') {\n error = new ProviderValidationError(message, details);\n } else if (step === 'initialization') {\n error = new ProviderInitializationError(message);\n }\n return reject(error);\n }\n resolve(response.data ?? null);\n } else {\n ws.once('message', onResponse);\n }\n };\n\n ws.once('message', onResponse);\n });\n };\n\n const dispatchCommand = <U extends Client.Command>(\n payload: {\n command: U;\n } & ([Client.GetCommandParams<U>] extends [never]\n ? unknown\n : { params?: Client.GetCommandParams<U> })\n ) => {\n return dispatch({ type: 'command', ...payload } as Client.CommandMessage);\n };\n\n const dispatchTransferAction = async <T>(action: Client.Action['action']) => {\n const payload: Dispatch<Client.Action> = { type: 'transfer', kind: 'action', action };\n\n return dispatch<T>(payload, { attachTransfer: true }) ?? Promise.resolve(null);\n };\n\n const dispatchTransferStep = async <\n T,\n A extends Client.TransferPushMessage['action'] = Client.TransferPushMessage['action'],\n S extends Client.TransferPushStep = Client.TransferPushStep,\n >(\n payload: {\n step: S;\n action: A;\n } & (A extends 'stream' ? { data: Client.GetTransferPushStreamData<S> } : unknown)\n ) => {\n const message: Dispatch<Client.TransferPushMessage> = {\n type: 'transfer',\n kind: 'step',\n ...payload,\n };\n\n return dispatch<T>(message, { attachTransfer: true }) ?? Promise.resolve(null);\n };\n\n const setTransferProperties = (\n properties: Exclude<IDispatcherState['transfer'], undefined>\n ): void => {\n state.transfer = { ...properties };\n };\n\n return {\n get transferID() {\n return state.transfer?.id;\n },\n\n get transferKind() {\n return state.transfer?.kind;\n },\n\n setTransferProperties,\n\n dispatch,\n dispatchCommand,\n dispatchTransferAction,\n dispatchTransferStep,\n };\n};\n\ntype WebsocketParams = ConstructorParameters<typeof WebSocket>;\ntype Address = WebsocketParams[0];\ntype Options = WebsocketParams[2];\n\nexport const connectToWebsocket = (\n address: Address,\n options?: Options,\n diagnostics?: IDiagnosticReporter\n): Promise<WebSocket> => {\n return new Promise((resolve, reject) => {\n const server = new WebSocket(address, options);\n server.once('open', () => {\n resolve(server);\n });\n\n server.on('unexpected-response', (_req, res) => {\n if (res.statusCode === 401) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authentication Error'\n )\n );\n }\n\n if (res.statusCode === 403) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authorization Error'\n )\n );\n }\n\n if (res.statusCode === 404) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Data transfer is not enabled on the remote host'\n )\n );\n }\n\n return reject(\n new ProviderInitializationError(\n `Failed to initialize the connection: Unexpected server response ${res.statusCode}`\n )\n );\n });\n\n server.on('message', (raw: RawData) => {\n const response: Server.Message = JSON.parse(raw.toString());\n if (response.diagnostic) {\n diagnostics?.report({\n ...response.diagnostic,\n });\n }\n });\n\n server.once('error', (err) => {\n reject(\n new ProviderTransferError(err.message, {\n details: {\n error: err.message,\n },\n })\n );\n });\n });\n};\n\nexport const trimTrailingSlash = (input: string): string => {\n return input.replace(/\\/$/, '');\n};\n\nexport const wait = (ms: number) => {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n};\n\nexport const waitUntil = async (test: () => boolean, interval: number): Promise<void> => {\n while (!test()) {\n await wait(interval);\n }\n\n return Promise.resolve();\n};\n"],"names":["createDispatcher","ws","retryMessageOptions","retryMessageMaxRetries","retryMessageTimeout","reportInfo","state","dispatch","message","options","Error","Promise","resolve","reject","uuid","randomUUID","payload","numberOfTimesMessageWasSent","attachTransfer","Object","assign","transferID","transfer","id","type","command","messageToSend","action","kind","step","stringifiedPayload","JSON","stringify","send","error","sendPeriodically","ProviderError","interval","setInterval","onResponse","raw","response","parse","toString","clearInterval","details","ProviderTransferError","ProviderValidationError","ProviderInitializationError","data","once","dispatchCommand","dispatchTransferAction","dispatchTransferStep","setTransferProperties","properties","transferKind","connectToWebsocket","address","diagnostics","server","WebSocket","on","_req","res","statusCode","diagnostic","report","err","trimTrailingSlash","input","replace"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/strapi/providers/utils.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { RawData, WebSocket } from 'ws';\n\nimport type { Client, Server } from '../../../types/remote/protocol';\n\nimport {\n ProviderError,\n ProviderTransferError,\n ProviderInitializationError,\n ProviderValidationError,\n ProviderErrorDetails,\n} from '../../errors/providers';\nimport { IDiagnosticReporter } from '../../utils/diagnostic';\nimport { stringifyTransferWebSocketPayload } from '../../utils/transfer-websocket-json';\n\ninterface IDispatcherState {\n transfer?: { kind: Client.TransferKind; id: string };\n}\n\nexport interface RetryMessageOptions {\n retryMessageMaxRetries: number;\n retryMessageTimeout: number;\n}\n\ninterface IDispatchOptions {\n attachTransfer?: boolean;\n /** Merged onto the dispatcher's default `retryMessageOptions` for this message only. */\n retryOverrides?: Partial<RetryMessageOptions>;\n}\n\ntype Dispatch<T> = Omit<T, 'transferID' | 'uuid'>;\n\nexport const createDispatcher = (\n ws: WebSocket,\n retryMessageOptions: RetryMessageOptions = {\n retryMessageMaxRetries: 5,\n retryMessageTimeout: 30000,\n },\n reportInfo?: (message: string) => void\n) => {\n const state: IDispatcherState = {};\n\n type DispatchMessage = Dispatch<Client.Message>;\n\n const dispatch = async <U = null>(\n message: DispatchMessage,\n options: IDispatchOptions = {}\n ): Promise<U | null> => {\n if (!ws) {\n throw new Error('No websocket connection found');\n }\n\n return new Promise<U | null>((resolve, reject) => {\n const uuid = randomUUID();\n const payload = { ...message, uuid };\n let numberOfTimesMessageWasSent = 0;\n\n if (options.attachTransfer) {\n Object.assign(payload, { transferID: state.transfer?.id });\n }\n\n if (message.type === 'command') {\n reportInfo?.(\n `dispatching message command:${(message as Client.CommandMessage).command} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `dispatching message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n const stringifiedPayload = stringifyTransferWebSocketPayload(\n payload as Record<string, unknown>\n );\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n const { retryMessageMaxRetries, retryMessageTimeout } = {\n ...retryMessageOptions,\n ...options.retryOverrides,\n };\n const sendPeriodically = () => {\n if (numberOfTimesMessageWasSent <= retryMessageMaxRetries) {\n numberOfTimesMessageWasSent += 1;\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n } else {\n reject(new ProviderError('error', 'Request timed out'));\n }\n };\n const interval = setInterval(sendPeriodically, retryMessageTimeout);\n\n const onResponse = (raw: RawData) => {\n const response: Server.Message<U> = JSON.parse(raw.toString());\n if (message.type === 'command') {\n reportInfo?.(\n `received response to message command: ${(message as Client.CommandMessage).command} uuid: ${uuid} sent: ${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `received response to message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n if (response.uuid === uuid) {\n clearInterval(interval);\n if (response.error) {\n const message = response.error.message;\n const details = response.error.details?.details as ProviderErrorDetails;\n const step = response.error.details?.step;\n let error = new ProviderError('error', message, details);\n if (step === 'transfer') {\n error = new ProviderTransferError(message, details);\n } else if (step === 'validation') {\n error = new ProviderValidationError(message, details);\n } else if (step === 'initialization') {\n error = new ProviderInitializationError(message);\n }\n return reject(error);\n }\n resolve(response.data ?? null);\n } else {\n ws.once('message', onResponse);\n }\n };\n\n ws.once('message', onResponse);\n });\n };\n\n const dispatchCommand = <U extends Client.Command>(\n payload: {\n command: U;\n } & ([Client.GetCommandParams<U>] extends [never]\n ? unknown\n : { params?: Client.GetCommandParams<U> })\n ) => {\n return dispatch({ type: 'command', ...payload } as Client.CommandMessage);\n };\n\n const dispatchTransferAction = async <T>(action: Client.Action['action']) => {\n const payload: Dispatch<Client.Action> = { type: 'transfer', kind: 'action', action };\n\n return dispatch<T>(payload, { attachTransfer: true }) ?? Promise.resolve(null);\n };\n\n const dispatchTransferStep = async <\n T,\n A extends Client.TransferPushMessage['action'] = Client.TransferPushMessage['action'],\n S extends Client.TransferPushStep = Client.TransferPushStep,\n >(\n payload: {\n step: S;\n action: A;\n } & (A extends 'stream' ? { data: Client.GetTransferPushStreamData<S> } : unknown),\n dispatchOptions?: Omit<IDispatchOptions, 'attachTransfer'>\n ) => {\n const message: Dispatch<Client.TransferPushMessage> = {\n type: 'transfer',\n kind: 'step',\n ...payload,\n };\n\n return (\n dispatch<T>(message, { attachTransfer: true, ...dispatchOptions }) ?? Promise.resolve(null)\n );\n };\n\n const setTransferProperties = (\n properties: Exclude<IDispatcherState['transfer'], undefined>\n ): void => {\n state.transfer = { ...properties };\n };\n\n return {\n get transferID() {\n return state.transfer?.id;\n },\n\n get transferKind() {\n return state.transfer?.kind;\n },\n\n setTransferProperties,\n\n dispatch,\n dispatchCommand,\n dispatchTransferAction,\n dispatchTransferStep,\n };\n};\n\ntype WebsocketParams = ConstructorParameters<typeof WebSocket>;\ntype Address = WebsocketParams[0];\ntype Options = WebsocketParams[2];\n\nexport const connectToWebsocket = (\n address: Address,\n options?: Options,\n diagnostics?: IDiagnosticReporter\n): Promise<WebSocket> => {\n return new Promise((resolve, reject) => {\n const server = new WebSocket(address, options);\n server.once('open', () => {\n resolve(server);\n });\n\n server.on('unexpected-response', (_req, res) => {\n if (res.statusCode === 401) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authentication Error'\n )\n );\n }\n\n if (res.statusCode === 403) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authorization Error'\n )\n );\n }\n\n if (res.statusCode === 404) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Data transfer is not enabled on the remote host'\n )\n );\n }\n\n return reject(\n new ProviderInitializationError(\n `Failed to initialize the connection: Unexpected server response ${res.statusCode}`\n )\n );\n });\n\n server.on('message', (raw: RawData) => {\n const response: Server.Message = JSON.parse(raw.toString());\n if (response.diagnostic) {\n diagnostics?.report({\n ...response.diagnostic,\n });\n }\n });\n\n server.once('error', (err) => {\n reject(\n new ProviderTransferError(err.message, {\n details: {\n error: err.message,\n },\n })\n );\n });\n });\n};\n\nexport const trimTrailingSlash = (input: string): string => {\n return input.replace(/\\/$/, '');\n};\n\nexport const wait = (ms: number) => {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n};\n\nexport const waitUntil = async (test: () => boolean, interval: number): Promise<void> => {\n while (!test()) {\n await wait(interval);\n }\n\n return Promise.resolve();\n};\n"],"names":["createDispatcher","ws","retryMessageOptions","retryMessageMaxRetries","retryMessageTimeout","reportInfo","state","dispatch","message","options","Error","Promise","resolve","reject","uuid","randomUUID","payload","numberOfTimesMessageWasSent","attachTransfer","Object","assign","transferID","transfer","id","type","command","messageToSend","action","kind","step","stringifiedPayload","stringifyTransferWebSocketPayload","send","error","retryOverrides","sendPeriodically","ProviderError","interval","setInterval","onResponse","raw","response","JSON","parse","toString","clearInterval","details","ProviderTransferError","ProviderValidationError","ProviderInitializationError","data","once","dispatchCommand","dispatchTransferAction","dispatchTransferStep","dispatchOptions","setTransferProperties","properties","transferKind","connectToWebsocket","address","diagnostics","server","WebSocket","on","_req","res","statusCode","diagnostic","report","err","trimTrailingSlash","input","replace"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import { WebSocket } from 'ws';
3
3
  import { ProviderInitializationError, ProviderTransferError, ProviderError, ProviderValidationError } from '../../errors/providers.mjs';
4
+ import { stringifyTransferWebSocketPayload } from '../../utils/transfer-websocket-json.mjs';
4
5
 
5
6
  const createDispatcher = (ws, retryMessageOptions = {
6
7
  retryMessageMaxRetries: 5,
@@ -29,13 +30,16 @@ const createDispatcher = (ws, retryMessageOptions = {
29
30
  const messageToSend = message;
30
31
  reportInfo?.(`dispatching message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`);
31
32
  }
32
- const stringifiedPayload = JSON.stringify(payload);
33
+ const stringifiedPayload = stringifyTransferWebSocketPayload(payload);
33
34
  ws.send(stringifiedPayload, (error)=>{
34
35
  if (error) {
35
36
  reject(error);
36
37
  }
37
38
  });
38
- const { retryMessageMaxRetries, retryMessageTimeout } = retryMessageOptions;
39
+ const { retryMessageMaxRetries, retryMessageTimeout } = {
40
+ ...retryMessageOptions,
41
+ ...options.retryOverrides
42
+ };
39
43
  const sendPeriodically = ()=>{
40
44
  if (numberOfTimesMessageWasSent <= retryMessageMaxRetries) {
41
45
  numberOfTimesMessageWasSent += 1;
@@ -97,14 +101,15 @@ const createDispatcher = (ws, retryMessageOptions = {
97
101
  attachTransfer: true
98
102
  }) ?? Promise.resolve(null);
99
103
  };
100
- const dispatchTransferStep = async (payload)=>{
104
+ const dispatchTransferStep = async (payload, dispatchOptions)=>{
101
105
  const message = {
102
106
  type: 'transfer',
103
107
  kind: 'step',
104
108
  ...payload
105
109
  };
106
110
  return dispatch(message, {
107
- attachTransfer: true
111
+ attachTransfer: true,
112
+ ...dispatchOptions
108
113
  }) ?? Promise.resolve(null);
109
114
  };
110
115
  const setTransferProperties = (properties)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","sources":["../../../src/strapi/providers/utils.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { RawData, WebSocket } from 'ws';\n\nimport type { Client, Server } from '../../../types/remote/protocol';\n\nimport {\n ProviderError,\n ProviderTransferError,\n ProviderInitializationError,\n ProviderValidationError,\n ProviderErrorDetails,\n} from '../../errors/providers';\nimport { IDiagnosticReporter } from '../../utils/diagnostic';\n\ninterface IDispatcherState {\n transfer?: { kind: Client.TransferKind; id: string };\n}\n\ninterface IDispatchOptions {\n attachTransfer?: boolean;\n}\n\ntype Dispatch<T> = Omit<T, 'transferID' | 'uuid'>;\n\nexport const createDispatcher = (\n ws: WebSocket,\n retryMessageOptions = {\n retryMessageMaxRetries: 5,\n retryMessageTimeout: 30000,\n },\n reportInfo?: (message: string) => void\n) => {\n const state: IDispatcherState = {};\n\n type DispatchMessage = Dispatch<Client.Message>;\n\n const dispatch = async <U = null>(\n message: DispatchMessage,\n options: IDispatchOptions = {}\n ): Promise<U | null> => {\n if (!ws) {\n throw new Error('No websocket connection found');\n }\n\n return new Promise<U | null>((resolve, reject) => {\n const uuid = randomUUID();\n const payload = { ...message, uuid };\n let numberOfTimesMessageWasSent = 0;\n\n if (options.attachTransfer) {\n Object.assign(payload, { transferID: state.transfer?.id });\n }\n\n if (message.type === 'command') {\n reportInfo?.(\n `dispatching message command:${(message as Client.CommandMessage).command} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `dispatching message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n const stringifiedPayload = JSON.stringify(payload);\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n const { retryMessageMaxRetries, retryMessageTimeout } = retryMessageOptions;\n const sendPeriodically = () => {\n if (numberOfTimesMessageWasSent <= retryMessageMaxRetries) {\n numberOfTimesMessageWasSent += 1;\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n } else {\n reject(new ProviderError('error', 'Request timed out'));\n }\n };\n const interval = setInterval(sendPeriodically, retryMessageTimeout);\n\n const onResponse = (raw: RawData) => {\n const response: Server.Message<U> = JSON.parse(raw.toString());\n if (message.type === 'command') {\n reportInfo?.(\n `received response to message command: ${(message as Client.CommandMessage).command} uuid: ${uuid} sent: ${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `received response to message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n if (response.uuid === uuid) {\n clearInterval(interval);\n if (response.error) {\n const message = response.error.message;\n const details = response.error.details?.details as ProviderErrorDetails;\n const step = response.error.details?.step;\n let error = new ProviderError('error', message, details);\n if (step === 'transfer') {\n error = new ProviderTransferError(message, details);\n } else if (step === 'validation') {\n error = new ProviderValidationError(message, details);\n } else if (step === 'initialization') {\n error = new ProviderInitializationError(message);\n }\n return reject(error);\n }\n resolve(response.data ?? null);\n } else {\n ws.once('message', onResponse);\n }\n };\n\n ws.once('message', onResponse);\n });\n };\n\n const dispatchCommand = <U extends Client.Command>(\n payload: {\n command: U;\n } & ([Client.GetCommandParams<U>] extends [never]\n ? unknown\n : { params?: Client.GetCommandParams<U> })\n ) => {\n return dispatch({ type: 'command', ...payload } as Client.CommandMessage);\n };\n\n const dispatchTransferAction = async <T>(action: Client.Action['action']) => {\n const payload: Dispatch<Client.Action> = { type: 'transfer', kind: 'action', action };\n\n return dispatch<T>(payload, { attachTransfer: true }) ?? Promise.resolve(null);\n };\n\n const dispatchTransferStep = async <\n T,\n A extends Client.TransferPushMessage['action'] = Client.TransferPushMessage['action'],\n S extends Client.TransferPushStep = Client.TransferPushStep,\n >(\n payload: {\n step: S;\n action: A;\n } & (A extends 'stream' ? { data: Client.GetTransferPushStreamData<S> } : unknown)\n ) => {\n const message: Dispatch<Client.TransferPushMessage> = {\n type: 'transfer',\n kind: 'step',\n ...payload,\n };\n\n return dispatch<T>(message, { attachTransfer: true }) ?? Promise.resolve(null);\n };\n\n const setTransferProperties = (\n properties: Exclude<IDispatcherState['transfer'], undefined>\n ): void => {\n state.transfer = { ...properties };\n };\n\n return {\n get transferID() {\n return state.transfer?.id;\n },\n\n get transferKind() {\n return state.transfer?.kind;\n },\n\n setTransferProperties,\n\n dispatch,\n dispatchCommand,\n dispatchTransferAction,\n dispatchTransferStep,\n };\n};\n\ntype WebsocketParams = ConstructorParameters<typeof WebSocket>;\ntype Address = WebsocketParams[0];\ntype Options = WebsocketParams[2];\n\nexport const connectToWebsocket = (\n address: Address,\n options?: Options,\n diagnostics?: IDiagnosticReporter\n): Promise<WebSocket> => {\n return new Promise((resolve, reject) => {\n const server = new WebSocket(address, options);\n server.once('open', () => {\n resolve(server);\n });\n\n server.on('unexpected-response', (_req, res) => {\n if (res.statusCode === 401) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authentication Error'\n )\n );\n }\n\n if (res.statusCode === 403) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authorization Error'\n )\n );\n }\n\n if (res.statusCode === 404) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Data transfer is not enabled on the remote host'\n )\n );\n }\n\n return reject(\n new ProviderInitializationError(\n `Failed to initialize the connection: Unexpected server response ${res.statusCode}`\n )\n );\n });\n\n server.on('message', (raw: RawData) => {\n const response: Server.Message = JSON.parse(raw.toString());\n if (response.diagnostic) {\n diagnostics?.report({\n ...response.diagnostic,\n });\n }\n });\n\n server.once('error', (err) => {\n reject(\n new ProviderTransferError(err.message, {\n details: {\n error: err.message,\n },\n })\n );\n });\n });\n};\n\nexport const trimTrailingSlash = (input: string): string => {\n return input.replace(/\\/$/, '');\n};\n\nexport const wait = (ms: number) => {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n};\n\nexport const waitUntil = async (test: () => boolean, interval: number): Promise<void> => {\n while (!test()) {\n await wait(interval);\n }\n\n return Promise.resolve();\n};\n"],"names":["createDispatcher","ws","retryMessageOptions","retryMessageMaxRetries","retryMessageTimeout","reportInfo","state","dispatch","message","options","Error","Promise","resolve","reject","uuid","randomUUID","payload","numberOfTimesMessageWasSent","attachTransfer","Object","assign","transferID","transfer","id","type","command","messageToSend","action","kind","step","stringifiedPayload","JSON","stringify","send","error","sendPeriodically","ProviderError","interval","setInterval","onResponse","raw","response","parse","toString","clearInterval","details","ProviderTransferError","ProviderValidationError","ProviderInitializationError","data","once","dispatchCommand","dispatchTransferAction","dispatchTransferStep","setTransferProperties","properties","transferKind","connectToWebsocket","address","diagnostics","server","WebSocket","on","_req","res","statusCode","diagnostic","report","err","trimTrailingSlash","input","replace"],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","sources":["../../../src/strapi/providers/utils.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport { RawData, WebSocket } from 'ws';\n\nimport type { Client, Server } from '../../../types/remote/protocol';\n\nimport {\n ProviderError,\n ProviderTransferError,\n ProviderInitializationError,\n ProviderValidationError,\n ProviderErrorDetails,\n} from '../../errors/providers';\nimport { IDiagnosticReporter } from '../../utils/diagnostic';\nimport { stringifyTransferWebSocketPayload } from '../../utils/transfer-websocket-json';\n\ninterface IDispatcherState {\n transfer?: { kind: Client.TransferKind; id: string };\n}\n\nexport interface RetryMessageOptions {\n retryMessageMaxRetries: number;\n retryMessageTimeout: number;\n}\n\ninterface IDispatchOptions {\n attachTransfer?: boolean;\n /** Merged onto the dispatcher's default `retryMessageOptions` for this message only. */\n retryOverrides?: Partial<RetryMessageOptions>;\n}\n\ntype Dispatch<T> = Omit<T, 'transferID' | 'uuid'>;\n\nexport const createDispatcher = (\n ws: WebSocket,\n retryMessageOptions: RetryMessageOptions = {\n retryMessageMaxRetries: 5,\n retryMessageTimeout: 30000,\n },\n reportInfo?: (message: string) => void\n) => {\n const state: IDispatcherState = {};\n\n type DispatchMessage = Dispatch<Client.Message>;\n\n const dispatch = async <U = null>(\n message: DispatchMessage,\n options: IDispatchOptions = {}\n ): Promise<U | null> => {\n if (!ws) {\n throw new Error('No websocket connection found');\n }\n\n return new Promise<U | null>((resolve, reject) => {\n const uuid = randomUUID();\n const payload = { ...message, uuid };\n let numberOfTimesMessageWasSent = 0;\n\n if (options.attachTransfer) {\n Object.assign(payload, { transferID: state.transfer?.id });\n }\n\n if (message.type === 'command') {\n reportInfo?.(\n `dispatching message command:${(message as Client.CommandMessage).command} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `dispatching message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n const stringifiedPayload = stringifyTransferWebSocketPayload(\n payload as Record<string, unknown>\n );\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n const { retryMessageMaxRetries, retryMessageTimeout } = {\n ...retryMessageOptions,\n ...options.retryOverrides,\n };\n const sendPeriodically = () => {\n if (numberOfTimesMessageWasSent <= retryMessageMaxRetries) {\n numberOfTimesMessageWasSent += 1;\n ws.send(stringifiedPayload, (error) => {\n if (error) {\n reject(error);\n }\n });\n } else {\n reject(new ProviderError('error', 'Request timed out'));\n }\n };\n const interval = setInterval(sendPeriodically, retryMessageTimeout);\n\n const onResponse = (raw: RawData) => {\n const response: Server.Message<U> = JSON.parse(raw.toString());\n if (message.type === 'command') {\n reportInfo?.(\n `received response to message command: ${(message as Client.CommandMessage).command} uuid: ${uuid} sent: ${numberOfTimesMessageWasSent}`\n );\n } else if (message.type === 'transfer') {\n const messageToSend = message as Client.TransferMessage;\n reportInfo?.(\n `received response to message action:${messageToSend.action} ${messageToSend.kind === 'step' ? `step:${messageToSend.step}` : ''} uuid:${uuid} sent:${numberOfTimesMessageWasSent}`\n );\n }\n if (response.uuid === uuid) {\n clearInterval(interval);\n if (response.error) {\n const message = response.error.message;\n const details = response.error.details?.details as ProviderErrorDetails;\n const step = response.error.details?.step;\n let error = new ProviderError('error', message, details);\n if (step === 'transfer') {\n error = new ProviderTransferError(message, details);\n } else if (step === 'validation') {\n error = new ProviderValidationError(message, details);\n } else if (step === 'initialization') {\n error = new ProviderInitializationError(message);\n }\n return reject(error);\n }\n resolve(response.data ?? null);\n } else {\n ws.once('message', onResponse);\n }\n };\n\n ws.once('message', onResponse);\n });\n };\n\n const dispatchCommand = <U extends Client.Command>(\n payload: {\n command: U;\n } & ([Client.GetCommandParams<U>] extends [never]\n ? unknown\n : { params?: Client.GetCommandParams<U> })\n ) => {\n return dispatch({ type: 'command', ...payload } as Client.CommandMessage);\n };\n\n const dispatchTransferAction = async <T>(action: Client.Action['action']) => {\n const payload: Dispatch<Client.Action> = { type: 'transfer', kind: 'action', action };\n\n return dispatch<T>(payload, { attachTransfer: true }) ?? Promise.resolve(null);\n };\n\n const dispatchTransferStep = async <\n T,\n A extends Client.TransferPushMessage['action'] = Client.TransferPushMessage['action'],\n S extends Client.TransferPushStep = Client.TransferPushStep,\n >(\n payload: {\n step: S;\n action: A;\n } & (A extends 'stream' ? { data: Client.GetTransferPushStreamData<S> } : unknown),\n dispatchOptions?: Omit<IDispatchOptions, 'attachTransfer'>\n ) => {\n const message: Dispatch<Client.TransferPushMessage> = {\n type: 'transfer',\n kind: 'step',\n ...payload,\n };\n\n return (\n dispatch<T>(message, { attachTransfer: true, ...dispatchOptions }) ?? Promise.resolve(null)\n );\n };\n\n const setTransferProperties = (\n properties: Exclude<IDispatcherState['transfer'], undefined>\n ): void => {\n state.transfer = { ...properties };\n };\n\n return {\n get transferID() {\n return state.transfer?.id;\n },\n\n get transferKind() {\n return state.transfer?.kind;\n },\n\n setTransferProperties,\n\n dispatch,\n dispatchCommand,\n dispatchTransferAction,\n dispatchTransferStep,\n };\n};\n\ntype WebsocketParams = ConstructorParameters<typeof WebSocket>;\ntype Address = WebsocketParams[0];\ntype Options = WebsocketParams[2];\n\nexport const connectToWebsocket = (\n address: Address,\n options?: Options,\n diagnostics?: IDiagnosticReporter\n): Promise<WebSocket> => {\n return new Promise((resolve, reject) => {\n const server = new WebSocket(address, options);\n server.once('open', () => {\n resolve(server);\n });\n\n server.on('unexpected-response', (_req, res) => {\n if (res.statusCode === 401) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authentication Error'\n )\n );\n }\n\n if (res.statusCode === 403) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Authorization Error'\n )\n );\n }\n\n if (res.statusCode === 404) {\n return reject(\n new ProviderInitializationError(\n 'Failed to initialize the connection: Data transfer is not enabled on the remote host'\n )\n );\n }\n\n return reject(\n new ProviderInitializationError(\n `Failed to initialize the connection: Unexpected server response ${res.statusCode}`\n )\n );\n });\n\n server.on('message', (raw: RawData) => {\n const response: Server.Message = JSON.parse(raw.toString());\n if (response.diagnostic) {\n diagnostics?.report({\n ...response.diagnostic,\n });\n }\n });\n\n server.once('error', (err) => {\n reject(\n new ProviderTransferError(err.message, {\n details: {\n error: err.message,\n },\n })\n );\n });\n });\n};\n\nexport const trimTrailingSlash = (input: string): string => {\n return input.replace(/\\/$/, '');\n};\n\nexport const wait = (ms: number) => {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n};\n\nexport const waitUntil = async (test: () => boolean, interval: number): Promise<void> => {\n while (!test()) {\n await wait(interval);\n }\n\n return Promise.resolve();\n};\n"],"names":["createDispatcher","ws","retryMessageOptions","retryMessageMaxRetries","retryMessageTimeout","reportInfo","state","dispatch","message","options","Error","Promise","resolve","reject","uuid","randomUUID","payload","numberOfTimesMessageWasSent","attachTransfer","Object","assign","transferID","transfer","id","type","command","messageToSend","action","kind","step","stringifiedPayload","stringifyTransferWebSocketPayload","send","error","retryOverrides","sendPeriodically","ProviderError","interval","setInterval","onResponse","raw","response","JSON","parse","toString","clearInterval","details","ProviderTransferError","ProviderValidationError","ProviderInitializationError","data","once","dispatchCommand","dispatchTransferAction","dispatchTransferStep","dispatchOptions","setTransferProperties","properties","transferKind","connectToWebsocket","address","diagnostics","server","WebSocket","on","_req","res","statusCode","diagnostic","report","err","trimTrailingSlash","input","replace"],"mappings":"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"}
@@ -11,6 +11,7 @@ export interface PullHandler extends Handler {
11
11
  streams?: {
12
12
  [stage in TransferStage]?: Readable;
13
13
  };
14
+ checksumsEnabled?: boolean;
14
15
  assertValidTransferAction(action: string): asserts action is PullTransferAction;
15
16
  onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;
16
17
  onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../../src/strapi/remote/handlers/pull.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAmC,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE9F,OAAO,KAAK,EAAU,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIzE,QAAA,MAAM,sBAAsB,8DAA+D,CAAC;AAE5F,KAAK,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IAEtC,OAAO,CAAC,EAAE;SAAG,KAAK,IAAI,aAAa,CAAC,CAAC,EAAE,QAAQ;KAAE,CAAC;IAElD,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC;IAEhF,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACpF,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC1E,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAErF,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,oBAAoB,8FAyW9B,CAAC"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../../src/strapi/remote/handlers/pull.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAMrC,OAAO,EAGL,0BAA0B,EAC3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAA+B,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI9F,QAAA,MAAM,sBAAsB,8DAA+D,CAAC;AAE5F,KAAK,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IAEtC,OAAO,CAAC,EAAE;SAAG,KAAK,IAAI,aAAa,CAAC,CAAC,EAAE,QAAQ;KAAE,CAAC;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC;IAEhF,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACpF,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC1E,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAErF,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,oBAAoB,8FA2X9B,CAAC"}
@@ -3,17 +3,21 @@
3
3
  var stream = require('stream');
4
4
  var crypto = require('crypto');
5
5
  var utils = require('./utils.js');
6
+ var transferAssetChunk = require('../../../utils/transfer-asset-chunk.js');
6
7
  require('path');
7
8
  require('fs-extra');
8
9
  var providers = require('../../../errors/providers.js');
9
10
  require('../../queries/entity.js');
10
11
  require('lodash/fp');
12
+ require('node:events');
13
+ require('node:stream/promises');
11
14
  require('events');
12
15
  require('lodash');
13
16
  require('@strapi/utils');
14
17
  require('../../providers/local-destination/strategies/restore/configuration.js');
15
18
  var index = require('../../providers/local-source/index.js');
16
19
  require('ws');
20
+ var estimateAssetTotals = require('../../providers/local-source/estimate-asset-totals.js');
17
21
 
18
22
  const TRANSFER_KIND = 'pull';
19
23
  const VALID_TRANSFER_ACTIONS = [
@@ -32,6 +36,7 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
32
36
  cleanup () {
33
37
  proto.cleanup.call(this);
34
38
  this.streams = {};
39
+ this.checksumsEnabled = false;
35
40
  delete this.provider;
36
41
  },
37
42
  onInfo (message) {
@@ -158,10 +163,10 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
158
163
  });
159
164
  batch = [];
160
165
  };
161
- if (!stream) {
162
- throw new providers.ProviderTransferError(`No available stream found for ${stage}`);
163
- }
164
166
  try {
167
+ if (!stream) {
168
+ throw new providers.ProviderTransferError(`No available stream found for ${stage}`);
169
+ }
165
170
  for await (const chunk of stream){
166
171
  if (stage !== 'assets') {
167
172
  batch.push(chunk);
@@ -208,11 +213,20 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
208
213
  throw new Error('Stream already created, something went wrong');
209
214
  }
210
215
  const flushUUID = crypto.randomUUID();
216
+ let totals;
217
+ if (step === 'assets') {
218
+ totals = await estimateAssetTotals.estimateAssetTotals(strapi);
219
+ }
211
220
  await this.createReadableStreamForStep(step);
212
- this.flush(step, flushUUID);
221
+ Promise.resolve(this.flush(step, flushUUID)).catch((err)=>{
222
+ this.onError(err instanceof Error ? err : new Error(String(err)));
223
+ });
213
224
  return {
214
225
  ok: true,
215
- id: flushUUID
226
+ id: flushUUID,
227
+ ...totals !== undefined ? {
228
+ totals
229
+ } : {}
216
230
  };
217
231
  }
218
232
  if (action === 'end') {
@@ -236,8 +250,9 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
236
250
  assets: ()=>{
237
251
  const assets = this.provider?.createAssetsReadStream();
238
252
  let batch = [];
253
+ const checksumsEnabled = this.checksumsEnabled === true;
239
254
  const batchLength = ()=>{
240
- return batch.reduce((acc, chunk)=>chunk.action === 'stream' ? acc + chunk.data.byteLength : acc, 0);
255
+ return batch.reduce((acc, chunk)=>acc + transferAssetChunk.transferAssetStreamChunkByteLength(chunk), 0);
241
256
  };
242
257
  const BATCH_MAX_SIZE = 1024 * 1024; // 1MB
243
258
  if (!assets) {
@@ -251,10 +266,12 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
251
266
  */ async function* generator(stream) {
252
267
  let hasStarted = false;
253
268
  let assetID = '';
269
+ let assetChecksum;
254
270
  for await (const chunk of stream){
255
271
  const { stream: assetStream, ...assetData } = chunk;
256
272
  if (!hasStarted) {
257
273
  assetID = crypto.randomUUID();
274
+ assetChecksum = checksumsEnabled ? crypto.createHash('sha256') : undefined;
258
275
  // Start the transfer of a new asset
259
276
  batch.push({
260
277
  action: 'start',
@@ -264,12 +281,8 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
264
281
  hasStarted = true;
265
282
  }
266
283
  for await (const assetChunk of assetStream){
267
- // Add the asset data to the batch
268
- batch.push({
269
- action: 'stream',
270
- assetID,
271
- data: assetChunk
272
- });
284
+ assetChecksum?.update(assetChunk);
285
+ batch.push(transferAssetChunk.createTransferAssetStreamChunk(assetID, assetChunk));
273
286
  // if the batch size is bigger than BATCH_MAX_SIZE stream the batch
274
287
  if (batchLength() >= BATCH_MAX_SIZE) {
275
288
  yield batch;
@@ -280,7 +293,13 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
280
293
  hasStarted = false;
281
294
  batch.push({
282
295
  action: 'end',
283
- assetID
296
+ assetID,
297
+ ...assetChecksum ? {
298
+ checksum: {
299
+ algorithm: 'sha256',
300
+ value: assetChecksum.digest('hex')
301
+ }
302
+ } : {}
284
303
  });
285
304
  yield batch;
286
305
  batch = [];
@@ -298,20 +317,22 @@ const createPullController = utils.handlerControllerFactory((proto)=>({
298
317
  this.streams[step] = await mapper[step]();
299
318
  },
300
319
  // Commands
301
- async init () {
320
+ async init (params) {
302
321
  if (this.transferID || this.provider) {
303
322
  throw new Error('Transfer already in progress');
304
323
  }
305
324
  await this.verifyAuth();
306
325
  this.transferID = crypto.randomUUID();
307
326
  this.startedAt = Date.now();
327
+ this.checksumsEnabled = params?.checksums === true;
308
328
  this.streams = {};
309
329
  this.provider = index.createLocalStrapiSourceProvider({
310
330
  autoDestroy: false,
311
331
  getStrapi: ()=>strapi
312
332
  });
313
333
  return {
314
- transferID: this.transferID
334
+ transferID: this.transferID,
335
+ checksums: true
315
336
  };
316
337
  },
317
338
  async end (params) {
@@ -1 +1 @@
1
- {"version":3,"file":"pull.js","sources":["../../../../src/strapi/remote/handlers/pull.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport { randomUUID } from 'crypto';\nimport type { Core } from '@strapi/types';\n\nimport { Handler } from './abstract';\nimport { handlerControllerFactory, isDataTransferMessage } from './utils';\nimport { createLocalStrapiSourceProvider, ILocalStrapiSourceProvider } from '../../providers';\nimport { ProviderTransferError } from '../../../errors/providers';\nimport type { IAsset, TransferStage, Protocol } from '../../../../types';\nimport { Client } from '../../../../types/remote/protocol';\n\nconst TRANSFER_KIND = 'pull';\nconst VALID_TRANSFER_ACTIONS = ['bootstrap', 'close', 'getMetadata', 'getSchemas'] as const;\n\ntype PullTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];\n\nexport interface PullHandler extends Handler {\n provider?: ILocalStrapiSourceProvider;\n\n streams?: { [stage in TransferStage]?: Readable };\n\n assertValidTransferAction(action: string): asserts action is PullTransferAction;\n\n onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;\n onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;\n onTransferStep(msg: Protocol.Client.TransferPullMessage): Promise<unknown> | unknown;\n\n createReadableStreamForStep(step: TransferStage): Promise<void>;\n\n flush(stage: TransferStage, id: string): Promise<void> | void;\n}\n\nexport const createPullController = handlerControllerFactory<Partial<PullHandler>>((proto) => ({\n isTransferStarted(this: PullHandler) {\n return proto.isTransferStarted.call(this) && this.provider !== undefined;\n },\n\n verifyAuth(this: PullHandler) {\n return proto.verifyAuth.call(this, TRANSFER_KIND);\n },\n\n cleanup(this: PullHandler) {\n proto.cleanup.call(this);\n\n this.streams = {};\n\n delete this.provider;\n },\n\n onInfo(message) {\n this.diagnostics?.report({\n details: {\n message,\n origin: 'pull-handler',\n createdAt: new Date(),\n },\n kind: 'info',\n });\n },\n onWarning(message) {\n this.diagnostics?.report({\n details: {\n message,\n createdAt: new Date(),\n origin: 'pull-handler',\n },\n kind: 'warning',\n });\n },\n\n onError(error) {\n this.diagnostics?.report({\n details: {\n message: error.message,\n error,\n createdAt: new Date(),\n name: error.name,\n severity: 'fatal',\n },\n kind: 'error',\n });\n },\n\n assertValidTransferAction(this: PullHandler, action) {\n // Abstract the constant to string[] to allow looser check on the given action\n const validActions = VALID_TRANSFER_ACTIONS as unknown as string[];\n\n if (validActions.includes(action)) {\n return;\n }\n\n throw new ProviderTransferError(`Invalid action provided: \"${action}\"`, {\n action,\n validActions: Object.keys(VALID_TRANSFER_ACTIONS),\n });\n },\n\n async onMessage(this: PullHandler, raw) {\n const msg = JSON.parse(raw.toString());\n\n if (!isDataTransferMessage(msg)) {\n return;\n }\n\n if (!msg.uuid) {\n await this.respond(undefined, new Error('Missing uuid in message'));\n }\n\n if (proto.hasUUID(msg.uuid)) {\n const previousResponse = proto.response;\n if (previousResponse?.uuid === msg.uuid) {\n await this.respond(previousResponse?.uuid, previousResponse.e, previousResponse.data);\n }\n return;\n }\n\n const { uuid, type } = msg;\n proto.addUUID(uuid);\n // Regular command message (init, end, status)\n if (type === 'command') {\n const { command } = msg;\n this.onInfo(`received command:${command} uuid:${uuid}`);\n await this.executeAndRespond(uuid, () => {\n this.assertValidTransferCommand(command);\n\n // The status command don't have params\n if (command === 'status') {\n return this.status();\n }\n\n return this[command](msg.params);\n });\n }\n\n // Transfer message (the transfer must be init first)\n else if (type === 'transfer') {\n this.onInfo(`received transfer action:${msg.action} step:${msg.kind} uuid:${uuid}`);\n await this.executeAndRespond(uuid, async () => {\n await this.verifyAuth();\n\n this.assertValidTransfer();\n\n return this.onTransferMessage(msg);\n });\n }\n\n // Invalid messages\n else {\n await this.respond(uuid, new Error('Bad Request'));\n }\n },\n\n async onTransferMessage(this: PullHandler, msg) {\n const { kind } = msg;\n\n if (kind === 'action') {\n return this.onTransferAction(msg);\n }\n\n if (kind === 'step') {\n return this.onTransferStep(msg as Protocol.Client.TransferPullMessage);\n }\n },\n\n async onTransferAction(this: PullHandler, msg) {\n const { action } = msg;\n\n this.assertValidTransferAction(action);\n\n if (action === 'bootstrap') {\n return this.provider?.[action](this.diagnostics);\n }\n return this.provider?.[action]();\n },\n\n async flush(this: PullHandler, stage: Client.TransferPullStep, id) {\n type Stage = typeof stage;\n const batchSize = 1024 * 1024;\n let batch = [] as Client.GetTransferPullStreamData<Stage>;\n const stream = this.streams?.[stage];\n\n const batchLength = () => Buffer.byteLength(JSON.stringify(batch));\n\n const maybeConfirm = async (data: any) => {\n try {\n await this.confirm(data);\n } catch (error) {\n // Handle the error, log it, or take other appropriate actions\n\n strapi?.log.error(\n `[Data transfer] Message confirmation failed: ${(error as Error)?.message}`\n );\n this.onError(error as Error);\n }\n };\n\n const sendBatch = async () => {\n await this.confirm({\n type: 'transfer',\n data: batch,\n ended: false,\n error: null,\n id,\n });\n batch = [];\n };\n\n if (!stream) {\n throw new ProviderTransferError(`No available stream found for ${stage}`);\n }\n\n try {\n for await (const chunk of stream) {\n if (stage !== 'assets') {\n batch.push(chunk);\n if (batchLength() >= batchSize) {\n await sendBatch();\n }\n } else {\n await this.confirm({\n type: 'transfer',\n data: [chunk],\n ended: false,\n error: null,\n id,\n });\n }\n }\n\n if (batch.length > 0 && stage !== 'assets') {\n await sendBatch();\n }\n await this.confirm({ type: 'transfer', data: null, ended: true, error: null, id });\n } catch (e) {\n // TODO: if this confirm fails, can we abort the whole transfer?\n await maybeConfirm({ type: 'transfer', data: null, ended: true, error: e, id });\n }\n },\n\n async onTransferStep(this: PullHandler, msg) {\n const { step, action } = msg;\n\n if (action === 'start') {\n if (this.streams?.[step] instanceof Readable) {\n throw new Error('Stream already created, something went wrong');\n }\n\n const flushUUID = randomUUID();\n\n await this.createReadableStreamForStep(step);\n this.flush(step, flushUUID);\n\n return { ok: true, id: flushUUID };\n }\n\n if (action === 'end') {\n const stream = this.streams?.[step];\n\n if (stream?.readableEnded === false) {\n await new Promise((resolve) => {\n stream?.on('close', resolve).destroy();\n });\n }\n\n delete this.streams?.[step];\n\n return { ok: true };\n }\n },\n\n async createReadableStreamForStep(this: PullHandler, step: Exclude<TransferStage, 'schemas'>) {\n const mapper = {\n entities: () => this.provider?.createEntitiesReadStream(),\n links: () => this.provider?.createLinksReadStream(),\n configuration: () => this.provider?.createConfigurationReadStream(),\n assets: () => {\n const assets = this.provider?.createAssetsReadStream();\n let batch: Protocol.Client.TransferAssetFlow[] = [];\n\n const batchLength = () => {\n return batch.reduce(\n (acc, chunk) => (chunk.action === 'stream' ? acc + chunk.data.byteLength : acc),\n 0\n );\n };\n\n const BATCH_MAX_SIZE = 1024 * 1024; // 1MB\n\n if (!assets) {\n throw new Error('Assets read stream could not be created');\n }\n /**\n * Generates batches of 1MB of data from the assets stream to avoid\n * sending too many small chunks\n *\n * @param stream Assets stream from the local source provider\n */\n async function* generator(stream: Readable) {\n let hasStarted = false;\n let assetID = '';\n\n for await (const chunk of stream) {\n const { stream: assetStream, ...assetData } = chunk as IAsset;\n if (!hasStarted) {\n assetID = randomUUID();\n // Start the transfer of a new asset\n batch.push({ action: 'start', assetID, data: assetData });\n hasStarted = true;\n }\n\n for await (const assetChunk of assetStream) {\n // Add the asset data to the batch\n batch.push({ action: 'stream', assetID, data: assetChunk });\n\n // if the batch size is bigger than BATCH_MAX_SIZE stream the batch\n if (batchLength() >= BATCH_MAX_SIZE) {\n yield batch;\n batch = [];\n }\n }\n\n // All the asset data has been streamed and gets ready for the next one\n hasStarted = false;\n batch.push({ action: 'end', assetID });\n yield batch;\n batch = [];\n }\n }\n\n return Readable.from(generator(assets));\n },\n };\n\n if (!(step in mapper)) {\n throw new Error('Invalid transfer step, impossible to create a stream');\n }\n\n if (!this.streams) {\n throw new Error('Invalid transfer state');\n }\n\n this.streams[step] = await mapper[step]();\n },\n\n // Commands\n async init(this: PullHandler) {\n if (this.transferID || this.provider) {\n throw new Error('Transfer already in progress');\n }\n await this.verifyAuth();\n\n this.transferID = randomUUID();\n this.startedAt = Date.now();\n\n this.streams = {};\n\n this.provider = createLocalStrapiSourceProvider({\n autoDestroy: false,\n getStrapi: () => strapi as Core.Strapi,\n });\n\n return { transferID: this.transferID };\n },\n\n async end(\n this: PullHandler,\n params: Protocol.Client.GetCommandParams<'end'>\n ): Promise<Protocol.Server.Payload<Protocol.Server.EndMessage>> {\n await this.verifyAuth();\n\n if (this.transferID !== params?.transferID) {\n throw new ProviderTransferError('Bad transfer ID provided');\n }\n\n this.cleanup();\n\n return { ok: true };\n },\n\n async status(this: PullHandler) {\n const isStarted = this.isTransferStarted();\n\n if (!isStarted) {\n const startedAt = this.startedAt as number;\n return {\n active: true,\n kind: TRANSFER_KIND,\n startedAt,\n elapsed: Date.now() - startedAt,\n };\n }\n return { active: false, kind: null, elapsed: null, startedAt: null };\n },\n}));\n"],"names":["TRANSFER_KIND","VALID_TRANSFER_ACTIONS","createPullController","handlerControllerFactory","proto","isTransferStarted","call","provider","undefined","verifyAuth","cleanup","streams","onInfo","message","diagnostics","report","details","origin","createdAt","Date","kind","onWarning","onError","error","name","severity","assertValidTransferAction","action","validActions","includes","ProviderTransferError","Object","keys","onMessage","raw","msg","JSON","parse","toString","isDataTransferMessage","uuid","respond","Error","hasUUID","previousResponse","response","e","data","type","addUUID","command","executeAndRespond","assertValidTransferCommand","status","params","assertValidTransfer","onTransferMessage","onTransferAction","onTransferStep","flush","stage","id","batchSize","batch","stream","batchLength","Buffer","byteLength","stringify","maybeConfirm","confirm","strapi","log","sendBatch","ended","chunk","push","length","step","Readable","flushUUID","randomUUID","createReadableStreamForStep","ok","readableEnded","Promise","resolve","on","destroy","mapper","entities","createEntitiesReadStream","links","createLinksReadStream","configuration","createConfigurationReadStream","assets","createAssetsReadStream","reduce","acc","BATCH_MAX_SIZE","generator","hasStarted","assetID","assetStream","assetData","assetChunk","from","init","transferID","startedAt","now","createLocalStrapiSourceProvider","autoDestroy","getStrapi","end","isStarted","active","elapsed"],"mappings":"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"}
1
+ {"version":3,"file":"pull.js","sources":["../../../../src/strapi/remote/handlers/pull.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport { randomUUID, createHash } from 'crypto';\nimport type { Core } from '@strapi/types';\n\nimport { Handler } from './abstract';\nimport { handlerControllerFactory, isDataTransferMessage } from './utils';\nimport {\n createTransferAssetStreamChunk,\n transferAssetStreamChunkByteLength,\n} from '../../../utils/transfer-asset-chunk';\nimport {\n createLocalStrapiSourceProvider,\n estimateAssetTotals,\n ILocalStrapiSourceProvider,\n} from '../../providers';\nimport { ProviderTransferError } from '../../../errors/providers';\nimport type { IAsset, StageTotalsEstimate, TransferStage, Protocol } from '../../../../types';\nimport { Client } from '../../../../types/remote/protocol';\n\nconst TRANSFER_KIND = 'pull';\nconst VALID_TRANSFER_ACTIONS = ['bootstrap', 'close', 'getMetadata', 'getSchemas'] as const;\n\ntype PullTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];\n\nexport interface PullHandler extends Handler {\n provider?: ILocalStrapiSourceProvider;\n\n streams?: { [stage in TransferStage]?: Readable };\n checksumsEnabled?: boolean;\n\n assertValidTransferAction(action: string): asserts action is PullTransferAction;\n\n onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;\n onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;\n onTransferStep(msg: Protocol.Client.TransferPullMessage): Promise<unknown> | unknown;\n\n createReadableStreamForStep(step: TransferStage): Promise<void>;\n\n flush(stage: TransferStage, id: string): Promise<void> | void;\n}\n\nexport const createPullController = handlerControllerFactory<Partial<PullHandler>>((proto) => ({\n isTransferStarted(this: PullHandler) {\n return proto.isTransferStarted.call(this) && this.provider !== undefined;\n },\n\n verifyAuth(this: PullHandler) {\n return proto.verifyAuth.call(this, TRANSFER_KIND);\n },\n\n cleanup(this: PullHandler) {\n proto.cleanup.call(this);\n\n this.streams = {};\n this.checksumsEnabled = false;\n\n delete this.provider;\n },\n\n onInfo(message) {\n this.diagnostics?.report({\n details: {\n message,\n origin: 'pull-handler',\n createdAt: new Date(),\n },\n kind: 'info',\n });\n },\n onWarning(message) {\n this.diagnostics?.report({\n details: {\n message,\n createdAt: new Date(),\n origin: 'pull-handler',\n },\n kind: 'warning',\n });\n },\n\n onError(error) {\n this.diagnostics?.report({\n details: {\n message: error.message,\n error,\n createdAt: new Date(),\n name: error.name,\n severity: 'fatal',\n },\n kind: 'error',\n });\n },\n\n assertValidTransferAction(this: PullHandler, action) {\n // Abstract the constant to string[] to allow looser check on the given action\n const validActions = VALID_TRANSFER_ACTIONS as unknown as string[];\n\n if (validActions.includes(action)) {\n return;\n }\n\n throw new ProviderTransferError(`Invalid action provided: \"${action}\"`, {\n action,\n validActions: Object.keys(VALID_TRANSFER_ACTIONS),\n });\n },\n\n async onMessage(this: PullHandler, raw) {\n const msg = JSON.parse(raw.toString());\n\n if (!isDataTransferMessage(msg)) {\n return;\n }\n\n if (!msg.uuid) {\n await this.respond(undefined, new Error('Missing uuid in message'));\n }\n\n if (proto.hasUUID(msg.uuid)) {\n const previousResponse = proto.response;\n if (previousResponse?.uuid === msg.uuid) {\n await this.respond(previousResponse?.uuid, previousResponse.e, previousResponse.data);\n }\n return;\n }\n\n const { uuid, type } = msg;\n proto.addUUID(uuid);\n // Regular command message (init, end, status)\n if (type === 'command') {\n const { command } = msg;\n this.onInfo(`received command:${command} uuid:${uuid}`);\n await this.executeAndRespond(uuid, () => {\n this.assertValidTransferCommand(command);\n\n // The status command don't have params\n if (command === 'status') {\n return this.status();\n }\n\n return this[command](msg.params);\n });\n }\n\n // Transfer message (the transfer must be init first)\n else if (type === 'transfer') {\n this.onInfo(`received transfer action:${msg.action} step:${msg.kind} uuid:${uuid}`);\n await this.executeAndRespond(uuid, async () => {\n await this.verifyAuth();\n\n this.assertValidTransfer();\n\n return this.onTransferMessage(msg);\n });\n }\n\n // Invalid messages\n else {\n await this.respond(uuid, new Error('Bad Request'));\n }\n },\n\n async onTransferMessage(this: PullHandler, msg) {\n const { kind } = msg;\n\n if (kind === 'action') {\n return this.onTransferAction(msg);\n }\n\n if (kind === 'step') {\n return this.onTransferStep(msg as Protocol.Client.TransferPullMessage);\n }\n },\n\n async onTransferAction(this: PullHandler, msg) {\n const { action } = msg;\n\n this.assertValidTransferAction(action);\n\n if (action === 'bootstrap') {\n return this.provider?.[action](this.diagnostics);\n }\n return this.provider?.[action]();\n },\n\n async flush(this: PullHandler, stage: Client.TransferPullStep, id) {\n type Stage = typeof stage;\n const batchSize = 1024 * 1024;\n let batch = [] as Client.GetTransferPullStreamData<Stage>;\n const stream = this.streams?.[stage];\n\n const batchLength = () => Buffer.byteLength(JSON.stringify(batch));\n\n const maybeConfirm = async (data: any) => {\n try {\n await this.confirm(data);\n } catch (error) {\n // Handle the error, log it, or take other appropriate actions\n\n strapi?.log.error(\n `[Data transfer] Message confirmation failed: ${(error as Error)?.message}`\n );\n this.onError(error as Error);\n }\n };\n\n const sendBatch = async () => {\n await this.confirm({\n type: 'transfer',\n data: batch,\n ended: false,\n error: null,\n id,\n });\n batch = [];\n };\n\n try {\n if (!stream) {\n throw new ProviderTransferError(`No available stream found for ${stage}`);\n }\n\n for await (const chunk of stream) {\n if (stage !== 'assets') {\n batch.push(chunk);\n if (batchLength() >= batchSize) {\n await sendBatch();\n }\n } else {\n await this.confirm({\n type: 'transfer',\n data: [chunk],\n ended: false,\n error: null,\n id,\n });\n }\n }\n\n if (batch.length > 0 && stage !== 'assets') {\n await sendBatch();\n }\n await this.confirm({ type: 'transfer', data: null, ended: true, error: null, id });\n } catch (e) {\n // TODO: if this confirm fails, can we abort the whole transfer?\n await maybeConfirm({ type: 'transfer', data: null, ended: true, error: e, id });\n }\n },\n\n async onTransferStep(this: PullHandler, msg) {\n const { step, action } = msg;\n\n if (action === 'start') {\n if (this.streams?.[step] instanceof Readable) {\n throw new Error('Stream already created, something went wrong');\n }\n\n const flushUUID = randomUUID();\n\n let totals: StageTotalsEstimate | undefined;\n if (step === 'assets') {\n totals = await estimateAssetTotals(strapi as Core.Strapi);\n }\n await this.createReadableStreamForStep(step);\n Promise.resolve(this.flush(step, flushUUID)).catch((err: unknown) => {\n this.onError(err instanceof Error ? err : new Error(String(err)));\n });\n\n return {\n ok: true,\n id: flushUUID,\n ...(totals !== undefined ? { totals } : {}),\n };\n }\n\n if (action === 'end') {\n const stream = this.streams?.[step];\n\n if (stream?.readableEnded === false) {\n await new Promise((resolve) => {\n stream?.on('close', resolve).destroy();\n });\n }\n\n delete this.streams?.[step];\n\n return { ok: true };\n }\n },\n\n async createReadableStreamForStep(this: PullHandler, step: Exclude<TransferStage, 'schemas'>) {\n const mapper = {\n entities: () => this.provider?.createEntitiesReadStream(),\n links: () => this.provider?.createLinksReadStream(),\n configuration: () => this.provider?.createConfigurationReadStream(),\n assets: () => {\n const assets = this.provider?.createAssetsReadStream();\n let batch: Protocol.Client.TransferAssetFlow[] = [];\n const checksumsEnabled = this.checksumsEnabled === true;\n\n const batchLength = () => {\n return batch.reduce((acc, chunk) => acc + transferAssetStreamChunkByteLength(chunk), 0);\n };\n\n const BATCH_MAX_SIZE = 1024 * 1024; // 1MB\n\n if (!assets) {\n throw new Error('Assets read stream could not be created');\n }\n /**\n * Generates batches of 1MB of data from the assets stream to avoid\n * sending too many small chunks\n *\n * @param stream Assets stream from the local source provider\n */\n async function* generator(stream: Readable) {\n let hasStarted = false;\n let assetID = '';\n let assetChecksum: ReturnType<typeof createHash> | undefined;\n\n for await (const chunk of stream) {\n const { stream: assetStream, ...assetData } = chunk as IAsset;\n if (!hasStarted) {\n assetID = randomUUID();\n assetChecksum = checksumsEnabled ? createHash('sha256') : undefined;\n // Start the transfer of a new asset\n batch.push({ action: 'start', assetID, data: assetData });\n hasStarted = true;\n }\n\n for await (const assetChunk of assetStream) {\n assetChecksum?.update(assetChunk);\n batch.push(createTransferAssetStreamChunk(assetID, assetChunk));\n\n // if the batch size is bigger than BATCH_MAX_SIZE stream the batch\n if (batchLength() >= BATCH_MAX_SIZE) {\n yield batch;\n batch = [];\n }\n }\n\n // All the asset data has been streamed and gets ready for the next one\n hasStarted = false;\n batch.push({\n action: 'end',\n assetID,\n ...(assetChecksum\n ? { checksum: { algorithm: 'sha256' as const, value: assetChecksum.digest('hex') } }\n : {}),\n });\n yield batch;\n batch = [];\n }\n }\n\n return Readable.from(generator(assets));\n },\n };\n\n if (!(step in mapper)) {\n throw new Error('Invalid transfer step, impossible to create a stream');\n }\n\n if (!this.streams) {\n throw new Error('Invalid transfer state');\n }\n\n this.streams[step] = await mapper[step]();\n },\n\n // Commands\n async init(this: PullHandler, params?: Protocol.Client.GetCommandParams<'init'>) {\n if (this.transferID || this.provider) {\n throw new Error('Transfer already in progress');\n }\n await this.verifyAuth();\n\n this.transferID = randomUUID();\n this.startedAt = Date.now();\n this.checksumsEnabled = params?.checksums === true;\n\n this.streams = {};\n\n this.provider = createLocalStrapiSourceProvider({\n autoDestroy: false,\n getStrapi: () => strapi as Core.Strapi,\n });\n\n return { transferID: this.transferID, checksums: true };\n },\n\n async end(\n this: PullHandler,\n params: Protocol.Client.GetCommandParams<'end'>\n ): Promise<Protocol.Server.Payload<Protocol.Server.EndMessage>> {\n await this.verifyAuth();\n\n if (this.transferID !== params?.transferID) {\n throw new ProviderTransferError('Bad transfer ID provided');\n }\n\n this.cleanup();\n\n return { ok: true };\n },\n\n async status(this: PullHandler) {\n const isStarted = this.isTransferStarted();\n\n if (!isStarted) {\n const startedAt = this.startedAt as number;\n return {\n active: true,\n kind: TRANSFER_KIND,\n startedAt,\n elapsed: Date.now() - startedAt,\n };\n }\n return { active: false, kind: null, elapsed: null, startedAt: null };\n },\n}));\n"],"names":["TRANSFER_KIND","VALID_TRANSFER_ACTIONS","createPullController","handlerControllerFactory","proto","isTransferStarted","call","provider","undefined","verifyAuth","cleanup","streams","checksumsEnabled","onInfo","message","diagnostics","report","details","origin","createdAt","Date","kind","onWarning","onError","error","name","severity","assertValidTransferAction","action","validActions","includes","ProviderTransferError","Object","keys","onMessage","raw","msg","JSON","parse","toString","isDataTransferMessage","uuid","respond","Error","hasUUID","previousResponse","response","e","data","type","addUUID","command","executeAndRespond","assertValidTransferCommand","status","params","assertValidTransfer","onTransferMessage","onTransferAction","onTransferStep","flush","stage","id","batchSize","batch","stream","batchLength","Buffer","byteLength","stringify","maybeConfirm","confirm","strapi","log","sendBatch","ended","chunk","push","length","step","Readable","flushUUID","randomUUID","totals","estimateAssetTotals","createReadableStreamForStep","Promise","resolve","catch","err","String","ok","readableEnded","on","destroy","mapper","entities","createEntitiesReadStream","links","createLinksReadStream","configuration","createConfigurationReadStream","assets","createAssetsReadStream","reduce","acc","transferAssetStreamChunkByteLength","BATCH_MAX_SIZE","generator","hasStarted","assetID","assetChecksum","assetStream","assetData","createHash","assetChunk","update","createTransferAssetStreamChunk","checksum","algorithm","value","digest","from","init","transferID","startedAt","now","checksums","createLocalStrapiSourceProvider","autoDestroy","getStrapi","end","isStarted","active","elapsed"],"mappings":"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"}