@syncmatters/connector-sdk 1.0.3 → 1.0.4

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.
@@ -64,11 +64,12 @@ whole batch by throwing is correct; don't fabricate per-row placeholders.)
64
64
  Some objects create but never update — messages that send on create, execution/run records,
65
65
  audit entries. Implement the insert path normally and throw
66
66
  `SDK.ConnectorError(SDK.ErrorCode.NotImplimented, ...)` for rows that would update (a row
67
- arriving with its key set). Two consequences: the object's test spec needs
68
- `upsert.cannotTestReason` (the harness's upsert test always includes an update phase — see
69
- [09-testing.md](./09-testing.md#insert-only--immutable-objects)), and if creating a row has
67
+ arriving with its key set). Two consequences: the object's test spec declares
68
+ `upsert.insertOnly` so the harness tests the insert path and skips the update phase —
69
+ `Passed (insert only)` see
70
+ [09-testing.md](./09-testing.md#insert-only--immutable-objects); and if creating a row has
70
71
  billable or externally visible side effects (a real message send), make sure test connections
71
- use sandbox credentials or a no-send setting.
72
+ use sandbox/test credentials or a no-send setting.
72
73
 
73
74
  ## `delete(options)` → `Promise<SDK.Row[]>`
74
75
 
@@ -146,7 +146,7 @@ Requirements that only surface as cryptic failures when unmet:
146
146
  - **The upsert test is insert THEN update, twice over.** `upsertPrepare` is called twice; both
147
147
  rows are inserted, re-queried by `idsFilter` and compared on `verifyFields` (which must be
148
148
  non-null on the payload), then BOTH are updated via the declared `upsert.key` and re-queried
149
- again. There is no insert-only mode — see below for objects that cannot update.
149
+ again. Objects whose rows can never update declare `upsert.insertOnly` — see below.
150
150
  - **relatedFilterPrepare needs a declaring-object row that actually has related rows** —
151
151
  `expectedRelatedRowIds` must be non-empty. In the parent-owns-children shape that means a
152
152
  parent with at least one child in the sandbox (create one in `before()` when the API allows;
@@ -155,22 +155,33 @@ Requirements that only surface as cryptic failures when unmet:
155
155
 
156
156
  ## Insert-only / immutable objects
157
157
 
158
- Some objects can never pass the upsert test as written: messages that send on create and are
158
+ Some objects create rows but never update them: messages that send on create and are
159
159
  immutable after (`update` correctly throws `NotImplimented`), execution/run records, audit
160
- logs. The harness's upsert test always performs the update phase, so:
161
-
162
- - Set `upsert.cannotTestReason` on the object's features with a REAL explanation —
163
- `"Messages are immutable once sent; update is NotImplimented by design"` so the result
164
- reads as a documented decision, not a gap. (`delete.cannotTestReason` likewise when rows
165
- cannot be deleted.)
166
- - The insert path still deserves coverage: exercise it yourself in another prepare hook you
167
- already need (e.g. `checkpointFilterStep1Prepare` inserting the row whose id it expects), so
168
- the code path runs even though the formal upsert test is scoped out.
160
+ logs. Declare that contract on the test spec and the harness tests exactly what exists:
161
+
162
+ ```js
163
+ // in mod Test.mjs's before(), over the generated spec (same place as cannotTestReason)
164
+ objectFeatures.messages.upsert.insertOnly = true;
165
+ ```
166
+
167
+ With `upsert.insertOnly` the upsert test runs its insert + query-back + `verifyFields`
168
+ phases as normal and SKIPS the update phase, reporting **`Passed (insert only)`** — a full
169
+ pass, with the result string honest about what was covered. `upsertPrepare` then only needs
170
+ `insert` and `verifyFields` (no `update` data). The `upsert.key` spec is still required —
171
+ the inserted rows are re-queried by id. Requires a platform runner that understands the
172
+ flag; older runners fail such objects with `"No test data for update"`.
173
+
174
+ Escalate to the blunter knobs only when the situation is stricter than "no update":
175
+
176
+ - `upsert.cannotTestReason` (with a REAL explanation) when even CREATING rows is off-limits —
177
+ a client's production system, or a billable/externally visible side effect with no safe
178
+ path. The object reports `Not tested` + reason and the suite result is `Partial`.
179
+ (`delete.cannotTestReason` likewise when rows cannot be deleted.)
169
180
  - **Billable or externally visible side effects** (a real SMS/WhatsApp send, an email) must
170
- not fire from tests: point the test connection at sandbox credentials, and when the API has
171
- no sandbox, gate sends behind a connector setting the test connection sets (a "suppress
172
- sends" / no-send mode) — then say so in the `cannotTestReason` if that leaves upsert
173
- untestable.
181
+ not fire from tests: point the test connection at sandbox/test credentials (e.g. Twilio's
182
+ test credentials with magic numbers), or gate sends behind a connector setting the test
183
+ connection sets (a "suppress sends" / no-send mode) — then `insertOnly` still gives the
184
+ insert path real coverage safely.
174
185
 
175
186
  ## Coverage bar
176
187
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncmatters/connector-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "TypeScript type definitions for the SyncMatters connector SDK (types only - connectors execute on the SyncMatters platform)",
5
5
  "types": "./index.d.ts",
6
6
  "exports": {
@@ -12,9 +12,9 @@
12
12
  "license": "MIT",
13
13
  "author": "SyncMatters",
14
14
  "homepage": "https://syncmatters.com",
15
- "typesContentHash": "e11f85e549e818527babaa7304ecca045f11b7e9fc6070519ecdd0d433e9081c",
15
+ "typesContentHash": "b47810ca30415f646b1055512fb4e342e48f3cd7459411c2dabcc7ca29959271",
16
16
  "dependencies": {
17
17
  "@types/node": "*",
18
- "@syncmatters/script-api": "^1.0.2"
18
+ "@syncmatters/script-api": "^1.0.3"
19
19
  }
20
20
  }