@t4h.framework/sftp 0.5.0 → 0.7.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.
@@ -2,10 +2,10 @@
2
2
  name: framework-sftp
3
3
  description: >-
4
4
  Guides correct use of @t4h.framework/sftp in T4H Framework workflows: SFTP
5
- SyncActivities, SftpClaim runtime dependency, the reconciler-aware Sftp client,
6
- Binary file payloads, and local testing with Claim.run and History.run. Use when
5
+ activities, SftpClaim runtime dependency, the reconciler-aware Sftp client,
6
+ Binary file payloads, and testing with TestWorkflowEnvironment. Use when
7
7
  implementing SFTP upload/download/list in workflows, wiring SftpClaim providers,
8
- mocking SFTP in activity unit tests, working in packages/sftp, or integrating
8
+ mocking SftpClaim in workflow tests, working in packages/sftp, or integrating
9
9
  remote file transfer (sftp:// connection strings, put/get, mkdir, stat, exists).
10
10
  ---
11
11
 
@@ -63,16 +63,12 @@ Node `>=22`. See [README.md](../../../README.md).
63
63
 
64
64
  ## Architecture
65
65
 
66
- `Workflow` → **`Sftp`** (`History.bind` per activity) → **`SyncActivity.run`** → **`SftpClaim.<method>(input)`**.
66
+ `Workflow` → **`Sftp`** (`History.bind` per activity) → shipped `Sftp*Activity` → **`SftpClaim.<method>(input)`** (runtime impl).
67
67
 
68
- Every activity:
69
-
70
- - Extends **`SyncActivity`** with a private **`Claim({ sftp: SftpClaim })`** keyed by a unique `Symbol`.
71
- - **`toInput`** maps `(sftp: Sftp, ...args)` → serializable input including **`connectionString: sftp.connectionString`**.
72
- - **`run`** delegates to **`this[CLAIMS_KEY].sftp.<method>(payload)`** (claim method name matches activity: `get`, `put`, `delete`, etc.).
73
- - Void activities: **`toOutput()`** returns **`undefined`**.
74
-
75
- `Sftp` stores **`public readonly connectionString`** and forwards each method to the bound activity reconciler.
68
+ From a workflow you call the **`Sftp`** client; it forwards each method to the
69
+ bound, replay-safe activity for you. The claim method name matches the client
70
+ method (`get`, `put`, `delete`, …) and the runtime supplies the `SftpClaim`
71
+ implementation.
76
72
 
77
73
  ---
78
74
 
@@ -120,7 +116,7 @@ import { Sftp } from '@t4h.framework/sftp'
120
116
  const sftp = new Sftp('sftp://user:pass@sftp.example.com:22')
121
117
  ```
122
118
 
123
- All calls must run inside **`History.run`** (workflow runtime / `WorkflowTesting` provide this). Outside history, reconciler throws **`PushActivity`**.
119
+ All calls run inside a workflow (the runtime, or `TestWorkflowEnvironment` in tests, provides the reconciler context).
124
120
 
125
121
  ### Methods
126
122
 
@@ -176,9 +172,12 @@ Use **`Binary`** from `@t4h.framework/core` for upload/download content (`put`,
176
172
 
177
173
  ---
178
174
 
179
- ## Activities (direct reconciler)
175
+ ## Using SFTP in a workflow via `History.reconciler`
180
176
 
181
- Prefer **`Sftp`** unless you need the activity class explicitly (custom wrappers, tests asserting activity type).
177
+ Prefer the **`Sftp`** client. When you need the exported activity directly,
178
+ drive the **shipped** `Sftp*Activity` class through `History.reconciler` — this
179
+ is a ready, replay-safe helper. **Never define or extend your own activity**;
180
+ only pass the activity classes this package exports.
182
181
 
183
182
  ```typescript
184
183
  import { History } from '@t4h.framework/core'
@@ -282,75 +281,30 @@ type SftpStat = {
282
281
 
283
282
  ## Testing
284
283
 
285
- Run package tests: `yarn test` in `packages/sftp` (Vitest).
286
-
287
- ### 1. Unit-test activity `run` with mocked `SftpClaim`
288
-
289
- Pattern from `SftpGetActivity.spec.ts` / `SftpDeleteActivity.spec.ts`:
284
+ Test the **workflow** with `TestWorkflowEnvironment` from
285
+ `@t4h.framework/core/testing`, mocking `SftpClaim` — the single claim every
286
+ `Sftp*Activity` resolves. Provide only the methods your workflow triggers
287
+ (`get`, `put`, `delete`, …). See the **framework-workflow-testing** skill for the
288
+ harness API.
290
289
 
291
290
  ```typescript
292
- import { Claim } from '@t4h.framework/core'
293
- import { describe, expect, it, vi } from 'vitest'
291
+ import { TestWorkflowEnvironment, mockClaim } from '@t4h.framework/core/testing'
294
292
  import { SftpClaim } from '@t4h.framework/sftp'
295
- import { SftpGetActivity, type SftpGetActivityInput } from '@t4h.framework/sftp'
296
-
297
- const connectionString = 'sftp://user:pass@sftp.example.com:22'
298
- const mockGet = vi.fn().mockReturnValue('binary-data' as any)
299
-
300
- Claim.run(
301
- [{ provide: SftpClaim, value: { get: mockGet } as unknown as SftpClaim }],
302
- () => {
303
- const activity: SftpGetActivity = Reflect.construct(SftpGetActivity, [])
304
- const input: SftpGetActivityInput = {
305
- connectionString,
306
- filepath: '/remote/file.txt',
307
- }
308
- const output = activity.run(input)
309
- expect(mockGet).toHaveBeenCalledWith(input)
310
- expect(output).toBe('binary-data')
311
- },
312
- )
313
- ```
314
293
 
315
- Test **`toInput`** with `new Sftp(connectionString)` and assert mapped fields. Test **`toOutput`** separately (pass-through for `Binary`/`string`/arrays; `undefined` for void activities).
294
+ const mockGet = vi.fn().mockImplementation(async () => someBinary)
316
295
 
317
- ### 2. Assert `Sftp` schedules the correct activity
318
-
319
- Pattern from `models/__tests__/Sftp.spec.ts`:
320
-
321
- ```typescript
322
- import { History, PushActivity, type Activity } from '@t4h.framework/core'
323
- import { Sftp, SftpGetActivity } from '@t4h.framework/sftp'
296
+ const env = TestWorkflowEnvironment.create({ now: 0 })
324
297
 
325
- async function captureReconcilerTrigger(fn: () => unknown) {
326
- try {
327
- await History.run([], fn)
328
- } catch (error) {
329
- if (error instanceof PushActivity) return error as PushActivity<Activity>
330
- throw error
331
- }
332
- }
333
-
334
- const client = new Sftp('sftp://user:pass@sftp.example.com:22')
335
- const trigger = await captureReconcilerTrigger(() =>
336
- client.get('/remote/file.txt'),
337
- )
338
- expect(trigger.activity.constructor).toBe(SftpGetActivity)
339
- ```
340
-
341
- Replay with canned output:
298
+ const output = await env.execute(workflow, input, {
299
+ claims: [mockClaim(SftpClaim, { get: mockGet })],
300
+ })
342
301
 
343
- ```typescript
344
- const result = await History.run(
345
- [{ output: mockBinary, type: 'sync' }],
346
- () => client.get('/remote/file.txt'),
347
- )
348
- expect(result).toBe(mockBinary)
302
+ // each SftpClaim method receives the activity's serializable input
303
+ expect(mockGet.mock.calls[0][0]).toMatchObject({ filepath: '/remote/file.txt' })
349
304
  ```
350
305
 
351
- ### 3. Integration-test workflows
352
-
353
- Use `WorkflowTesting.run` with a mocked `SftpClaim` provider. See **framework-core** skill for `WorkflowTesting` and claim wiring.
306
+ An unconfigured claim method throws a clear error, so mock every method the
307
+ workflow reaches.
354
308
 
355
309
  ---
356
310
 
@@ -363,7 +317,7 @@ Use `WorkflowTesting.run` with a mocked `SftpClaim` provider. See **framework-co
363
317
  5. Use **`filepath`** for get/put/append; **`path`** for most other operations; **`srcPath`/`destPath`** for copy/rename.
364
318
  6. Use **`exists`** before destructive ops when idempotency matters; use **`delete(..., true)`** for tolerant deletes.
365
319
  7. Use **`mkdir(..., true)`** / **`rmdir(..., true)`** only when recursive tree ops are intended.
366
- 8. When adding tests, mirror **`Claim.run`** + partial `SftpClaim` mocks or **`History.run`** + **`PushActivity`** from `packages/sftp/src/**/__tests__`.
320
+ 8. Test workflows with **`TestWorkflowEnvironment`** + **`mockClaim(SftpClaim, ...)`**; assert on the mock's `mock.calls`.
367
321
  9. Do not document or import APIs not exported from `@t4h.framework/sftp`.
368
322
 
369
- See also: `packages/sftp/README.md`, `framework-core` skill for `History`, `SyncActivity`, and `WorkflowTesting`.
323
+ See also: `packages/sftp/README.md`; **framework-workflow-testing** for the test harness.
package/CHANGELOG.md ADDED
@@ -0,0 +1,38 @@
1
+ # @t4h.framework/sftp
2
+
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Updated dependencies [[`8098041`](https://github.com/tech4humans-brasil/framework/commit/80980419d59a987378b7c94372ee2f7b7dcc00f5)]:
8
+ - @t4h.framework/core@0.10.0
9
+
10
+ ## 0.6.0
11
+
12
+ ### Minor Changes
13
+
14
+ - Update history to satisfies core contract ([`30b3d38`](https://github.com/tech4humans-brasil/framework/commit/30b3d38bfd631990e4c4f740344910d5958ddfb9))
15
+
16
+ ### Patch Changes
17
+
18
+ - Update skills ([`6d7e7bc`](https://github.com/tech4humans-brasil/framework/commit/6d7e7bca0c780a9c53a0c9e5aa0a865c5af67959))
19
+
20
+ ## 0.5.0
21
+
22
+ ### Minor Changes
23
+
24
+ - Adds sftp binary ([#94](https://github.com/tech4humans-brasil/framework/pull/94))
25
+
26
+ ## 0.4.0
27
+
28
+ ### Patch Changes
29
+
30
+ - Internal dependency updates
31
+
32
+ ## 0.3.0
33
+
34
+ ### Minor Changes
35
+
36
+ - Adds sftp framework lib ([#29](https://github.com/tech4humans-brasil/framework/pull/29))
37
+ - Adds type to history item ([#47](https://github.com/tech4humans-brasil/framework/pull/47))
38
+ - Adds .ai/skills in packages ([#88](https://github.com/tech4humans-brasil/framework/pull/88))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t4h.framework/sftp",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "SFTP module for the T4H Framework",
5
5
  "homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/sftp",
6
6
  "bugs": "https://github.com/tech4humans-brasil/framework/issues",
@@ -31,12 +31,12 @@
31
31
  "test:watch": "vitest"
32
32
  },
33
33
  "devDependencies": {
34
- "@t4h.framework/core": "^0.6.0",
34
+ "@t4h.framework/core": "^0.10.0",
35
35
  "typescript": "^5.9.3",
36
36
  "vitest": "^4.0.18"
37
37
  },
38
38
  "peerDependencies": {
39
- "@t4h.framework/core": "^0.6.0"
39
+ "@t4h.framework/core": "^0.10.0"
40
40
  },
41
41
  "packageManager": "yarn@4.12.0",
42
42
  "engines": {