@nodrel-dev/n8n-nodes-ups 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/dist/credentials/UpsOAuth2Api.credentials.d.ts +10 -0
- package/dist/credentials/UpsOAuth2Api.credentials.js +76 -0
- package/dist/credentials/UpsOAuth2Api.credentials.js.map +1 -0
- package/dist/credentials/ups.svg +5 -0
- package/dist/nodes/Ups/Ups.node.d.ts +4 -0
- package/dist/nodes/Ups/Ups.node.js +53 -0
- package/dist/nodes/Ups/Ups.node.js.map +1 -0
- package/dist/nodes/Ups/Ups.node.json +18 -0
- package/dist/nodes/Ups/core/buildCommodities.d.ts +10 -0
- package/dist/nodes/Ups/core/buildCommodities.js +21 -0
- package/dist/nodes/Ups/core/buildCommodities.js.map +1 -0
- package/dist/nodes/Ups/core/buildInternationalForms.d.ts +17 -0
- package/dist/nodes/Ups/core/buildInternationalForms.js +34 -0
- package/dist/nodes/Ups/core/buildInternationalForms.js.map +1 -0
- package/dist/nodes/Ups/core/extractCharges.d.ts +20 -0
- package/dist/nodes/Ups/core/extractCharges.js +13 -0
- package/dist/nodes/Ups/core/extractCharges.js.map +1 -0
- package/dist/nodes/Ups/core/extractForms.d.ts +23 -0
- package/dist/nodes/Ups/core/extractForms.js +25 -0
- package/dist/nodes/Ups/core/extractForms.js.map +1 -0
- package/dist/nodes/Ups/core/extractLabel.d.ts +30 -0
- package/dist/nodes/Ups/core/extractLabel.js +35 -0
- package/dist/nodes/Ups/core/extractLabel.js.map +1 -0
- package/dist/nodes/Ups/core/flattenRates.d.ts +36 -0
- package/dist/nodes/Ups/core/flattenRates.js +58 -0
- package/dist/nodes/Ups/core/flattenRates.js.map +1 -0
- package/dist/nodes/Ups/core/isInternational.d.ts +9 -0
- package/dist/nodes/Ups/core/isInternational.js +15 -0
- package/dist/nodes/Ups/core/isInternational.js.map +1 -0
- package/dist/nodes/Ups/core/mapTrackStatus.d.ts +48 -0
- package/dist/nodes/Ups/core/mapTrackStatus.js +55 -0
- package/dist/nodes/Ups/core/mapTrackStatus.js.map +1 -0
- package/dist/nodes/Ups/core/mapUpsError.d.ts +2 -0
- package/dist/nodes/Ups/core/mapUpsError.js +52 -0
- package/dist/nodes/Ups/core/mapUpsError.js.map +1 -0
- package/dist/nodes/Ups/core/shapeCandidates.d.ts +37 -0
- package/dist/nodes/Ups/core/shapeCandidates.js +68 -0
- package/dist/nodes/Ups/core/shapeCandidates.js.map +1 -0
- package/dist/nodes/Ups/core/toMoney.d.ts +6 -0
- package/dist/nodes/Ups/core/toMoney.js +16 -0
- package/dist/nodes/Ups/core/toMoney.js.map +1 -0
- package/dist/nodes/Ups/core/toUpsAddress.d.ts +12 -0
- package/dist/nodes/Ups/core/toUpsAddress.js +17 -0
- package/dist/nodes/Ups/core/toUpsAddress.js.map +1 -0
- package/dist/nodes/Ups/core/toXavAddress.d.ts +16 -0
- package/dist/nodes/Ups/core/toXavAddress.js +26 -0
- package/dist/nodes/Ups/core/toXavAddress.js.map +1 -0
- package/dist/nodes/Ups/core/types.d.ts +73 -0
- package/dist/nodes/Ups/core/types.js +3 -0
- package/dist/nodes/Ups/core/types.js.map +1 -0
- package/dist/nodes/Ups/resources/address/index.d.ts +2 -0
- package/dist/nodes/Ups/resources/address/index.js +20 -0
- package/dist/nodes/Ups/resources/address/index.js.map +1 -0
- package/dist/nodes/Ups/resources/address/validate.operation.d.ts +24 -0
- package/dist/nodes/Ups/resources/address/validate.operation.js +109 -0
- package/dist/nodes/Ups/resources/address/validate.operation.js.map +1 -0
- package/dist/nodes/Ups/resources/shipping/create.operation.d.ts +24 -0
- package/dist/nodes/Ups/resources/shipping/create.operation.js +363 -0
- package/dist/nodes/Ups/resources/shipping/create.operation.js.map +1 -0
- package/dist/nodes/Ups/resources/shipping/getRates.operation.d.ts +24 -0
- package/dist/nodes/Ups/resources/shipping/getRates.operation.js +126 -0
- package/dist/nodes/Ups/resources/shipping/getRates.operation.js.map +1 -0
- package/dist/nodes/Ups/resources/shipping/index.d.ts +2 -0
- package/dist/nodes/Ups/resources/shipping/index.js +22 -0
- package/dist/nodes/Ups/resources/shipping/index.js.map +1 -0
- package/dist/nodes/Ups/resources/shipping/shared.d.ts +34 -0
- package/dist/nodes/Ups/resources/shipping/shared.js +165 -0
- package/dist/nodes/Ups/resources/shipping/shared.js.map +1 -0
- package/dist/nodes/Ups/resources/tracking/index.d.ts +2 -0
- package/dist/nodes/Ups/resources/tracking/index.js +20 -0
- package/dist/nodes/Ups/resources/tracking/index.js.map +1 -0
- package/dist/nodes/Ups/resources/tracking/track.operation.d.ts +24 -0
- package/dist/nodes/Ups/resources/tracking/track.operation.js +73 -0
- package/dist/nodes/Ups/resources/tracking/track.operation.js.map +1 -0
- package/dist/nodes/Ups/ups.dark.svg +13 -0
- package/dist/nodes/Ups/ups.svg +13 -0
- package/dist/package.json +61 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 nodrel-dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 📦 n8n-nodes-ups
|
|
4
|
+
|
|
5
|
+
**Use the UPS REST API directly in your n8n workflows.**
|
|
6
|
+
|
|
7
|
+
Track shipments · validate addresses · quote rates · create labels (with international customs forms) — against _your own_ UPS account, with no aggregator in the middle.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@nodrel-dev/n8n-nodes-ups)
|
|
10
|
+
[](https://www.npmjs.com/package/@nodrel-dev/n8n-nodes-ups)
|
|
11
|
+
[](https://github.com/nodrel-dev/n8n-nodes-ups/actions/workflows/ci.yml)
|
|
12
|
+
[](https://www.npmjs.com/package/@nodrel-dev/n8n-nodes-ups)
|
|
13
|
+
[](https://www.npmjs.com/package/@nodrel-dev/n8n-nodes-ups#provenance)
|
|
14
|
+
|
|
15
|
+
[Installation](#installation) · [Operations](#operations) · [Credentials](#credentials) · [Usage](#usage) · [npm](https://www.npmjs.com/package/@nodrel-dev/n8n-nodes-ups) · [UPS Developer Portal](https://developer.ups.com/) · [Report an issue](https://github.com/nodrel-dev/n8n-nodes-ups/issues)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
## What is this?
|
|
20
|
+
|
|
21
|
+
This is an [n8n](https://n8n.io/) community node for the **UPS REST API**. It lets your workflows track shipments, validate addresses, quote rates, and create shipping labels — talking straight to UPS with your own API credentials.
|
|
22
|
+
|
|
23
|
+
Because there's no aggregator in the middle, you get **your own negotiated rates** and UPS bills your account directly. [n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/sustainable-use-license/) workflow automation platform.
|
|
24
|
+
|
|
25
|
+
### Highlights
|
|
26
|
+
|
|
27
|
+
- 🚚 **Direct to UPS** — your API keys, your negotiated rates, your account billed. No aggregator markup or middleman.
|
|
28
|
+
- 🏷️ **Labels as real binary** — Create returns a print-ready GIF / ZPL / EPL / SPL label as n8n binary data, not a base64 blob buried in JSON.
|
|
29
|
+
- 🌍 **International built in** — cross-border Create assembles the UPS commercial-invoice customs forms and returns the UPS-generated invoice as a PDF binary alongside the label.
|
|
30
|
+
- 🔑 **One credential, all four APIs** — a single UPS OAuth app entitles Track, Address Validation, Rating, and Ship, so there is exactly one credential to set up.
|
|
31
|
+
- 🔀 **One sandbox / production switch** — a single credential field repoints every API request and the OAuth token URL together, so a call can never straddle environments.
|
|
32
|
+
- 🔐 **Native OAuth2, no token code** — n8n performs the client-credentials exchange and refreshes the token for you.
|
|
33
|
+
- 📦 **Zero runtime dependencies** — ships only `dist/`, published to npm with signed [provenance](https://docs.npmjs.com/generating-provenance-statements).
|
|
34
|
+
|
|
35
|
+
## Who it's for
|
|
36
|
+
|
|
37
|
+
- **E-commerce & retail** — print labels at fulfillment, surface tracking to customers, and rate-shop services per order.
|
|
38
|
+
- **3PLs & fulfillment ops** — automate shipping for many accounts and wire labels into existing pick-and-pack flows.
|
|
39
|
+
- **Cross-border sellers** — generate the commercial invoice and customs forms UPS needs for international shipments, automatically.
|
|
40
|
+
- **Finance & operations teams** — quote live negotiated rates inside approval and reconciliation workflows.
|
|
41
|
+
- **Developers & integrators** — embed UPS tracking, address validation, rates, and labels into any n8n automation without hand-rolling OAuth.
|
|
42
|
+
|
|
43
|
+
## How it works
|
|
44
|
+
|
|
45
|
+
The node sits between your workflow and UPS. A single **UPS OAuth2** credential holds your Client ID/Secret and the sandbox-or-production switch; n8n handles the token exchange, and every request is routed to the matching UPS host.
|
|
46
|
+
|
|
47
|
+
```mermaid
|
|
48
|
+
flowchart LR
|
|
49
|
+
subgraph wf["n8n workflow"]
|
|
50
|
+
prev["Upstream node"] --> ups["UPS node"]
|
|
51
|
+
ups --> down["Downstream node<br/>(Write Binary File,<br/>Send Email, …)"]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
cred["UPS OAuth2 credential<br/>Client ID + Secret<br/>Sandbox (CIE) / Production"]
|
|
55
|
+
cred -. "n8n exchanges and refreshes token" .-> ups
|
|
56
|
+
|
|
57
|
+
ups -->|"HTTPS + bearer token"| api["UPS REST API<br/>(your account and rates)"]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation. In n8n, go to **Settings → Community Nodes → Install** and enter `@nodrel-dev/n8n-nodes-ups`.
|
|
63
|
+
|
|
64
|
+
## Operations
|
|
65
|
+
|
|
66
|
+
The node exposes three resources: **Tracking**, **Address**, and **Shipping**.
|
|
67
|
+
|
|
68
|
+
```mermaid
|
|
69
|
+
flowchart TD
|
|
70
|
+
node["UPS node"]
|
|
71
|
+
node --> tracking["📍 Tracking"]
|
|
72
|
+
node --> address["🏠 Address"]
|
|
73
|
+
node --> shipping["📦 Shipping"]
|
|
74
|
+
|
|
75
|
+
tracking --> track["Track<br/>GET /track/v1/details/{number}"]
|
|
76
|
+
address --> validate["Validate<br/>POST /addressvalidation/v2/3"]
|
|
77
|
+
shipping --> rates["Get Rates<br/>POST /rating/v2409/Shoptimeintransit"]
|
|
78
|
+
shipping --> create["Create<br/>POST /shipments/v2409/ship"]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Tracking → Track
|
|
82
|
+
|
|
83
|
+
Get the current status and scan history for one UPS inquiry number per item (`GET /track/v1/details/{number}`).
|
|
84
|
+
|
|
85
|
+
- **Tracking Number** (required) — one inquiry number per input item.
|
|
86
|
+
- **Detail** — _Detailed_ (status + scan history) or _Status Only_ (current status only).
|
|
87
|
+
- **Locale** — e.g. `en_US`.
|
|
88
|
+
|
|
89
|
+
Unknown numbers are flagged on their own item; with **Continue On Fail** the rest still process.
|
|
90
|
+
|
|
91
|
+
### Address → Validate
|
|
92
|
+
|
|
93
|
+
Standardize an address and classify it residential vs commercial (`POST /addressvalidation/v2/3`).
|
|
94
|
+
|
|
95
|
+
- Address line(s), city, state/province, postal code, country.
|
|
96
|
+
- Returns one item with `resolution` (`valid` / `ambiguous` / `none`), a `classification` (UnClassified / Commercial / Residential), and standardized `candidates[]`.
|
|
97
|
+
|
|
98
|
+
### Shipping → Get Rates
|
|
99
|
+
|
|
100
|
+
Quote published and negotiated rates with transit times for every eligible service (`POST /rating/v2409/Shoptimeintransit`).
|
|
101
|
+
|
|
102
|
+
- **Account Number** (required) — your ShipperNumber; also requests negotiated rates.
|
|
103
|
+
- Shipper / Ship To (and optional Ship From) addresses, package weight (+ unit) and optional dimensions (+ unit).
|
|
104
|
+
- **Customs Value** — required when origin and destination countries differ (international).
|
|
105
|
+
- Emits **one output item per service**, each with published + negotiated price, transit days, and any UPS alerts. If no negotiated rates are returned, a request-level alert is attached to the first item.
|
|
106
|
+
|
|
107
|
+
### Shipping → Create
|
|
108
|
+
|
|
109
|
+
Buy a shipment and get a printable label plus tracking number (`POST /shipments/v2409/ship`).
|
|
110
|
+
|
|
111
|
+
- **Account Number** (required), **Service Code**, Shipper / Ship To (and optional Ship From), package weight/dimensions, **Label Format** (GIF default; ZPL / EPL / SPL — no PDF label).
|
|
112
|
+
- **International** (origin ≠ destination country) additionally requires the customs fields: reason for export, currency, terms of shipment, sold-to party, and at least one commodity line.
|
|
113
|
+
- Returns the tracking number and account/published charges, plus the **label** as a binary attachment (`label`); international shipments also return the **commercial invoice** PDF (`customsInvoice`). Label/invoice image data is never embedded as a string in the JSON output.
|
|
114
|
+
|
|
115
|
+
Billing is to the shipper (transportation charges); international duties are billed to the receiver (DDU) in this version.
|
|
116
|
+
|
|
117
|
+
## Credentials
|
|
118
|
+
|
|
119
|
+
You authenticate with a UPS **Client ID** and **Client Secret** using OAuth2 client-credentials. n8n performs the token exchange and refreshes the token automatically — you never handle tokens yourself.
|
|
120
|
+
|
|
121
|
+
### Prerequisites
|
|
122
|
+
|
|
123
|
+
1. Create an application on the [UPS Developer Portal](https://developer.ups.com/).
|
|
124
|
+
2. Note its **Client ID** and **Client Secret**. A single UPS OAuth app entitles all four APIs used here (Track, Address Validation, Rating, Ship), so one credential covers every operation.
|
|
125
|
+
3. For Get Rates and Create you also need your UPS **account number** (ShipperNumber).
|
|
126
|
+
|
|
127
|
+
### One credential type
|
|
128
|
+
|
|
129
|
+
The node uses a single credential, **UPS OAuth2 API**, for all four operations:
|
|
130
|
+
|
|
131
|
+
| Credential type | Used by |
|
|
132
|
+
| --------------- | ------- |
|
|
133
|
+
| `upsOAuth2Api` | Track, Validate, Get Rates, Create |
|
|
134
|
+
|
|
135
|
+
### Set up a credential in n8n
|
|
136
|
+
|
|
137
|
+
1. Add a new **UPS OAuth2 API** credential.
|
|
138
|
+
2. Set **Environment** to **Sandbox (CIE)** while developing, or **Production** for real shipments. This single switch points both the OAuth token URL and every API request at the matching UPS host, so a request can never straddle sandbox and production.
|
|
139
|
+
3. Enter your **Client ID** and **Client Secret**.
|
|
140
|
+
4. Save — n8n runs the credential test (an authenticated Track probe) and shows a green confirmation when the keys are valid. A `401/403` means the Client ID, Secret, or Environment is wrong.
|
|
141
|
+
|
|
142
|
+
Grant type is OAuth2 **client credentials** (HTTP Basic, empty scope) — configured automatically; nothing to set by hand. Secrets live only in n8n's encrypted credential store; never hardcode them.
|
|
143
|
+
|
|
144
|
+
> **Sandbox vs production:** credentials default to **Sandbox (CIE)** on purpose, so a half-configured connection can't hit a live account. Switch to **Production** only when you are ready to create real, billable shipments.
|
|
145
|
+
|
|
146
|
+
### Sandbox vs production hosts
|
|
147
|
+
|
|
148
|
+
| | Sandbox (CIE) | Production |
|
|
149
|
+
| --- | --- | --- |
|
|
150
|
+
| Token URL | `https://wwwcie.ups.com/security/v1/oauth/token` | `https://onlinetools.ups.com/security/v1/oauth/token` |
|
|
151
|
+
| API base | `https://wwwcie.ups.com/api` | `https://onlinetools.ups.com/api` |
|
|
152
|
+
|
|
153
|
+
The Customer Integration Environment (CIE) is limited test data — for example, address validation returns street-level results for **US NY/CA** addresses only, and Track returns a canned `DELIVERED` response for any well-formed `1Z` number.
|
|
154
|
+
|
|
155
|
+
## Compatibility
|
|
156
|
+
|
|
157
|
+
- Requires n8n with `n8nNodesApiVersion: 1`.
|
|
158
|
+
- Built and tested against the UPS REST API (Track v1, Address Validation v2, Rating v2409, Ship v2409).
|
|
159
|
+
- The account number is never defaulted or hardcoded — it always comes from the node field, and your API keys live only in the credential.
|
|
160
|
+
|
|
161
|
+
## Security & dependencies
|
|
162
|
+
|
|
163
|
+
The published package ships only `dist/` with **zero runtime dependencies** (`n8n-workflow` is a peer, provided by your n8n instance). Any audit findings are confined to the build, test, and release tooling or the host-provided peer — none of them reach an installed node.
|
|
164
|
+
|
|
165
|
+
Every release is published to npm with a signed **[provenance](https://docs.npmjs.com/generating-provenance-statements) attestation** through GitHub Actions [OIDC trusted publishing](https://docs.npmjs.com/trusted-publishers): no long-lived npm token is stored in the repo, and anyone can cryptographically verify that a given version was built by this workflow from this exact commit (see the **Provenance** panel on the [npm page](https://www.npmjs.com/package/@nodrel-dev/n8n-nodes-ups#provenance)).
|
|
166
|
+
|
|
167
|
+
The package is also scanned with `npx @n8n/scan-community-package @nodrel-dev/n8n-nodes-ups` as part of the release process.
|
|
168
|
+
|
|
169
|
+
## AI-Agent tool usage
|
|
170
|
+
|
|
171
|
+
The node sets `usableAsTool: true`, so every operation is callable from the AI-Agent **tool** path as well as the normal node path. An AI Agent can call any operation directly (for example "track 1Z…", or "rate this shipment"). Test new workflows through both the normal node path and the tool path.
|
|
172
|
+
|
|
173
|
+
## Usage
|
|
174
|
+
|
|
175
|
+
### Get Rates and Create
|
|
176
|
+
|
|
177
|
+
Both operations share the same **Shipper**, **Ship From**, and **Ship To** address fields, so values carry over when you switch between them. Package dimensions (length/width/height) are optional and only sent to UPS when provided. Ship From is optional and defaults to the Shipper address.
|
|
178
|
+
|
|
179
|
+
### The label binary (Create)
|
|
180
|
+
|
|
181
|
+
Create returns the label as proper n8n **binary data** on the output property named `label` — not a base64 string buried in JSON. Under the hood, the node requests an inline base64 label, decodes it, and attaches it as binary so downstream nodes can print or save it directly. International shipments additionally return the UPS commercial invoice as a PDF binary on the property `customsInvoice`:
|
|
182
|
+
|
|
183
|
+
```mermaid
|
|
184
|
+
sequenceDiagram
|
|
185
|
+
participant WF as n8n workflow
|
|
186
|
+
participant Node as UPS node
|
|
187
|
+
participant Auth as OAuth2 (n8n-managed)
|
|
188
|
+
participant API as UPS Ship API
|
|
189
|
+
|
|
190
|
+
WF->>Node: Execute "Create"
|
|
191
|
+
Node->>Auth: Need access token
|
|
192
|
+
Auth-->>Node: Cached / refreshed token
|
|
193
|
+
Node->>Node: createPreSend assembles ShipmentRequest<br/>(+ InternationalForms if cross-border)
|
|
194
|
+
Node->>API: POST /shipments/v2409/ship (bearer token)
|
|
195
|
+
API-->>Node: JSON + base64 label (+ base64 invoice)
|
|
196
|
+
Node->>Node: createPostReceive decodes base64 →<br/>attach binary "label" (+ "customsInvoice"),<br/>surface charges
|
|
197
|
+
Node-->>WF: JSON (tracking #, charges)<br/>+ binary label (+ invoice)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Choose the format with **Label Format**:
|
|
201
|
+
|
|
202
|
+
| Label Format | MIME type | Typical use |
|
|
203
|
+
| --- | --- | --- |
|
|
204
|
+
| GIF | `image/gif` | Default; preview / office printers |
|
|
205
|
+
| ZPL | `text/plain` | Zebra thermal printers (4×6 stock) |
|
|
206
|
+
| EPL | `text/plain` | Eltron thermal printers (4×6 stock) |
|
|
207
|
+
| SPL | `text/plain` | SATO thermal printers (4×6 stock) |
|
|
208
|
+
|
|
209
|
+
The tracking number and charge details are passed through on the main JSON output. Wire the `label` (and `customsInvoice`) binary into **Write Binary File**, **Send Email** (as an attachment), or any node that consumes binary data.
|
|
210
|
+
|
|
211
|
+
### Errors and Continue On Fail
|
|
212
|
+
|
|
213
|
+
UPS error codes and messages are surfaced verbatim through n8n's error handling — classified as authentication, input, or transient — and the node honors **Continue On Fail**: failed items emit an `error` entry and the workflow keeps processing the rest. Non-fatal UPS alerts (for example "no negotiated rates returned") are surfaced as warnings without failing the item.
|
|
214
|
+
|
|
215
|
+
## Documentation
|
|
216
|
+
|
|
217
|
+
Deeper docs for contributors and integrators live in [`docs/`](docs/):
|
|
218
|
+
|
|
219
|
+
- [System Overview](docs/system-overview.md) — architecture, auth/environment model, request lifecycle (with diagrams).
|
|
220
|
+
- [Integration Specification](docs/integration-spec.md) — endpoints, request/response shapes, enums, and error handling for all four operations.
|
|
221
|
+
- [Data Model](docs/data-model.md) — the typed shapes the node assembles, and the node-parameter → UPS-field mapping.
|
|
222
|
+
- [Architecture Decision Records](docs/adr/) — why the key design choices were made.
|
|
223
|
+
- [n8n Community Node Gotchas](docs/n8n-gotchas.md) — hard-won build/release/verify traps.
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
npm install # install dev dependencies
|
|
229
|
+
npm test # run the pure-core unit tests (vitest)
|
|
230
|
+
npm run lint # n8n community-node lint (strict)
|
|
231
|
+
npm run build # compile to dist/
|
|
232
|
+
npm run dev # run locally inside n8n (Node.js >= 22.22)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Releases are driven by [release-please](https://github.com/googleapis/release-please): merge the auto-generated release PR on `main` and the workflow tags, publishes to npm with provenance, and scans. Never run a release or `npm publish` locally.
|
|
236
|
+
|
|
237
|
+
## Resources
|
|
238
|
+
|
|
239
|
+
- [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes)
|
|
240
|
+
- [UPS Developer Portal](https://developer.ups.com/)
|
|
241
|
+
- [UPS API catalog](https://developer.ups.com/api/reference)
|
|
242
|
+
|
|
243
|
+
## Version history
|
|
244
|
+
|
|
245
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full, per-release history (kept current automatically on each release).
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ICredentialTestRequest, ICredentialType, Icon, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class UpsOAuth2Api implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
extends: string[];
|
|
5
|
+
displayName: string;
|
|
6
|
+
icon: Icon;
|
|
7
|
+
documentationUrl: string;
|
|
8
|
+
properties: INodeProperties[];
|
|
9
|
+
test: ICredentialTestRequest;
|
|
10
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UpsOAuth2Api = void 0;
|
|
4
|
+
const TOKEN_URL = {
|
|
5
|
+
sandbox: 'https://wwwcie.ups.com/security/v1/oauth/token',
|
|
6
|
+
production: 'https://onlinetools.ups.com/security/v1/oauth/token',
|
|
7
|
+
};
|
|
8
|
+
const API_HOST = {
|
|
9
|
+
sandbox: 'https://wwwcie.ups.com',
|
|
10
|
+
production: 'https://onlinetools.ups.com',
|
|
11
|
+
};
|
|
12
|
+
class UpsOAuth2Api {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.name = 'upsOAuth2Api';
|
|
15
|
+
this.extends = ['oAuth2Api'];
|
|
16
|
+
this.displayName = 'UPS OAuth2 API';
|
|
17
|
+
this.icon = 'file:ups.svg';
|
|
18
|
+
this.documentationUrl = 'https://github.com/nodrel-dev/n8n-nodes-ups?tab=readme-ov-file#credentials';
|
|
19
|
+
this.properties = [
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Environment',
|
|
22
|
+
name: 'environment',
|
|
23
|
+
type: 'options',
|
|
24
|
+
options: [
|
|
25
|
+
{ name: 'Sandbox (CIE)', value: 'sandbox' },
|
|
26
|
+
{ name: 'Production', value: 'production' },
|
|
27
|
+
],
|
|
28
|
+
default: 'sandbox',
|
|
29
|
+
description: 'Which UPS environment to use. Sandbox is the Customer Integration Environment (CIE). Drives both the token URL and the API base URL.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
displayName: 'Grant Type',
|
|
33
|
+
name: 'grantType',
|
|
34
|
+
type: 'hidden',
|
|
35
|
+
default: 'clientCredentials',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
displayName: 'Access Token URL',
|
|
39
|
+
name: 'accessTokenUrl',
|
|
40
|
+
type: 'hidden',
|
|
41
|
+
default: `={{ $self["environment"] === "production" ? "${TOKEN_URL.production}" : "${TOKEN_URL.sandbox}" }}`,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
displayName: 'Auth URI Query Parameters',
|
|
45
|
+
name: 'authQueryParameters',
|
|
46
|
+
type: 'hidden',
|
|
47
|
+
default: '',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
displayName: 'Scope',
|
|
51
|
+
name: 'scope',
|
|
52
|
+
type: 'hidden',
|
|
53
|
+
default: '',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
displayName: 'Authentication',
|
|
57
|
+
name: 'authentication',
|
|
58
|
+
type: 'hidden',
|
|
59
|
+
default: 'header',
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
this.test = {
|
|
63
|
+
request: {
|
|
64
|
+
baseURL: `={{ $credentials.environment === "production" ? "${API_HOST.production}" : "${API_HOST.sandbox}" }}`,
|
|
65
|
+
url: '/api/track/v1/details/1Z00000000000000000',
|
|
66
|
+
method: 'GET',
|
|
67
|
+
headers: {
|
|
68
|
+
transId: 'n8n-nodes-ups-credtest',
|
|
69
|
+
transactionSrc: 'n8n-nodes-ups',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.UpsOAuth2Api = UpsOAuth2Api;
|
|
76
|
+
//# sourceMappingURL=UpsOAuth2Api.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpsOAuth2Api.credentials.js","sourceRoot":"","sources":["../../credentials/UpsOAuth2Api.credentials.ts"],"names":[],"mappings":";;;AASA,MAAM,SAAS,GAAG;IACjB,OAAO,EAAE,gDAAgD;IACzD,UAAU,EAAE,qDAAqD;CACjE,CAAC;AAGF,MAAM,QAAQ,GAAG;IAChB,OAAO,EAAE,wBAAwB;IACjC,UAAU,EAAE,6BAA6B;CACzC,CAAC;AAEF,MAAa,YAAY;IAAzB;QACC,SAAI,GAAG,cAAc,CAAC;QAEtB,YAAO,GAAG,CAAC,WAAW,CAAC,CAAC;QAExB,gBAAW,GAAG,gBAAgB,CAAC;QAE/B,SAAI,GAAS,cAAc,CAAC;QAE5B,qBAAgB,GAAG,4EAA4E,CAAC;QAEhG,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACR,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE;oBAC3C,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;iBAC3C;gBACD,OAAO,EAAE,SAAS;gBAClB,WAAW,EACV,sIAAsI;aACvI;YACD;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,mBAAmB;aAC5B;YACD;gBAGC,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,gDAAgD,SAAS,CAAC,UAAU,QAAQ,SAAS,CAAC,OAAO,MAAM;aAC5G;YACD;gBACC,WAAW,EAAE,2BAA2B;gBACxC,IAAI,EAAE,qBAAqB;gBAC3B,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBAEC,WAAW,EAAE,OAAO;gBACpB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBAGC,WAAW,EAAE,gBAAgB;gBAC7B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,QAAQ;aACjB;SACD,CAAC;QAWF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,oDAAoD,QAAQ,CAAC,UAAU,QAAQ,QAAQ,CAAC,OAAO,MAAM;gBAC9G,GAAG,EAAE,2CAA2C;gBAChD,MAAM,EAAE,KAAK;gBAKb,OAAO,EAAE;oBACR,OAAO,EAAE,wBAAwB;oBACjC,cAAc,EAAE,eAAe;iBAC/B;aACD;SACD,CAAC;IACH,CAAC;CAAA;AArFD,oCAqFC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#6f4e37" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
|
|
3
|
+
<polyline points="3.27 6.96 12 12.01 20.73 6.96"/>
|
|
4
|
+
<line x1="12" y1="22.08" x2="12" y2="12"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Ups = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const tracking_1 = require("./resources/tracking");
|
|
6
|
+
const address_1 = require("./resources/address");
|
|
7
|
+
const shipping_1 = require("./resources/shipping");
|
|
8
|
+
class Ups {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.description = {
|
|
11
|
+
displayName: 'UPS',
|
|
12
|
+
name: 'ups',
|
|
13
|
+
icon: { light: 'file:ups.svg', dark: 'file:ups.dark.svg' },
|
|
14
|
+
group: ['transform'],
|
|
15
|
+
version: 1,
|
|
16
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
17
|
+
description: 'Track shipments, validate addresses, rate, and create UPS shipments',
|
|
18
|
+
defaults: {
|
|
19
|
+
name: 'UPS',
|
|
20
|
+
},
|
|
21
|
+
usableAsTool: true,
|
|
22
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
23
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
24
|
+
credentials: [{ name: 'upsOAuth2Api', required: true }],
|
|
25
|
+
requestDefaults: {
|
|
26
|
+
baseURL: '={{ $credentials.environment === "production" ? "https://onlinetools.ups.com/api" : "https://wwwcie.ups.com/api" }}',
|
|
27
|
+
headers: {
|
|
28
|
+
Accept: 'application/json',
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
properties: [
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Resource',
|
|
35
|
+
name: 'resource',
|
|
36
|
+
type: 'options',
|
|
37
|
+
noDataExpression: true,
|
|
38
|
+
options: [
|
|
39
|
+
{ name: 'Address', value: 'address' },
|
|
40
|
+
{ name: 'Shipping', value: 'shipping' },
|
|
41
|
+
{ name: 'Tracking', value: 'tracking' },
|
|
42
|
+
],
|
|
43
|
+
default: 'tracking',
|
|
44
|
+
},
|
|
45
|
+
...tracking_1.trackingDescription,
|
|
46
|
+
...address_1.addressDescription,
|
|
47
|
+
...shipping_1.shippingDescription,
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.Ups = Ups;
|
|
53
|
+
//# sourceMappingURL=Ups.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ups.node.js","sourceRoot":"","sources":["../../../nodes/Ups/Ups.node.ts"],"names":[],"mappings":";;;AAAA,+CAA8F;AAC9F,mDAA2D;AAC3D,iDAAyD;AACzD,mDAA2D;AAE3D,MAAa,GAAG;IAAhB;QAMC,gBAAW,GAAyB;YACnC,WAAW,EAAE,KAAK;YAClB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,mBAAmB,EAAE;YAC1D,KAAK,EAAE,CAAC,WAAW,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,8DAA8D;YACxE,WAAW,EAAE,qEAAqE;YAClF,QAAQ,EAAE;gBACT,IAAI,EAAE,KAAK;aACX;YACD,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;YAClC,OAAO,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;YACnC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACvD,eAAe,EAAE;gBAIhB,OAAO,EACN,qHAAqH;gBACtH,OAAO,EAAE;oBACR,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,kBAAkB;iBAClC;aACD;YACD,UAAU,EAAE;gBACX;oBACC,WAAW,EAAE,UAAU;oBACvB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,SAAS;oBACf,gBAAgB,EAAE,IAAI;oBACtB,OAAO,EAAE;wBACR,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;wBACrC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;wBACvC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;qBACvC;oBACD,OAAO,EAAE,UAAU;iBACnB;gBACD,GAAG,8BAAmB;gBACtB,GAAG,4BAAkB;gBACrB,GAAG,8BAAmB;aACtB;SACD,CAAC;IACH,CAAC;CAAA;AAlDD,kBAkDC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "@nodrel-dev/n8n-nodes-ups.ups",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": ["Miscellaneous"],
|
|
6
|
+
"resources": {
|
|
7
|
+
"credentialDocumentation": [
|
|
8
|
+
{
|
|
9
|
+
"url": "https://github.com/nodrel-dev/n8n-nodes-ups?tab=readme-ov-file#credentials"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"primaryDocumentation": [
|
|
13
|
+
{
|
|
14
|
+
"url": "https://github.com/nodrel-dev/n8n-nodes-ups?tab=readme-ov-file"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Product } from './types';
|
|
2
|
+
export interface CommodityLineInput {
|
|
3
|
+
description: string;
|
|
4
|
+
quantity: number;
|
|
5
|
+
unitValue: number;
|
|
6
|
+
unitOfMeasure: string;
|
|
7
|
+
commodityCode?: string;
|
|
8
|
+
originCountry?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildCommodities(items: CommodityLineInput[]): Product[];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCommodities = buildCommodities;
|
|
4
|
+
function buildCommodities(items) {
|
|
5
|
+
return items.map((item) => {
|
|
6
|
+
const product = {
|
|
7
|
+
Description: item.description,
|
|
8
|
+
Unit: {
|
|
9
|
+
Number: String(item.quantity),
|
|
10
|
+
UnitOfMeasurement: { Code: item.unitOfMeasure },
|
|
11
|
+
Value: String(item.unitValue),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
if (item.commodityCode)
|
|
15
|
+
product.CommodityCode = item.commodityCode;
|
|
16
|
+
if (item.originCountry)
|
|
17
|
+
product.OriginCountryCode = item.originCountry;
|
|
18
|
+
return product;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=buildCommodities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildCommodities.js","sourceRoot":"","sources":["../../../../nodes/Ups/core/buildCommodities.ts"],"names":[],"mappings":";;AAeA,4CAcC;AAdD,SAAgB,gBAAgB,CAAC,KAA2B;IAC3D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,OAAO,GAAY;YACxB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,EAAE;gBACL,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAC7B,iBAAiB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE;gBAC/C,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;aAC7B;SACD,CAAC;QACF,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACnE,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC;QACvE,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { InternationalForms, Product } from './types';
|
|
2
|
+
export interface CustomsInput {
|
|
3
|
+
reasonForExport: string;
|
|
4
|
+
currency: string;
|
|
5
|
+
termsOfShipment?: string;
|
|
6
|
+
invoiceNumber?: string;
|
|
7
|
+
invoiceDate?: string;
|
|
8
|
+
soldTo: {
|
|
9
|
+
name: string;
|
|
10
|
+
addressLines: string[];
|
|
11
|
+
city: string;
|
|
12
|
+
stateProvinceCode?: string;
|
|
13
|
+
postalCode?: string;
|
|
14
|
+
countryCode: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function buildInternationalForms(customs: CustomsInput, commodities: Product[]): InternationalForms;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildInternationalForms = buildInternationalForms;
|
|
4
|
+
function buildInternationalForms(customs, commodities) {
|
|
5
|
+
var _a;
|
|
6
|
+
const forms = {
|
|
7
|
+
FormType: ['01'],
|
|
8
|
+
ReasonForExport: customs.reasonForExport,
|
|
9
|
+
CurrencyCode: customs.currency,
|
|
10
|
+
Contacts: {
|
|
11
|
+
SoldTo: {
|
|
12
|
+
Name: customs.soldTo.name,
|
|
13
|
+
Address: {
|
|
14
|
+
AddressLine: ((_a = customs.soldTo.addressLines) !== null && _a !== void 0 ? _a : []).filter((l) => l && l.trim().length > 0),
|
|
15
|
+
City: customs.soldTo.city,
|
|
16
|
+
CountryCode: customs.soldTo.countryCode,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
Product: commodities,
|
|
21
|
+
};
|
|
22
|
+
if (customs.soldTo.stateProvinceCode)
|
|
23
|
+
forms.Contacts.SoldTo.Address.StateProvinceCode = customs.soldTo.stateProvinceCode;
|
|
24
|
+
if (customs.soldTo.postalCode)
|
|
25
|
+
forms.Contacts.SoldTo.Address.PostalCode = customs.soldTo.postalCode;
|
|
26
|
+
if (customs.termsOfShipment)
|
|
27
|
+
forms.TermsOfShipment = customs.termsOfShipment;
|
|
28
|
+
if (customs.invoiceNumber)
|
|
29
|
+
forms.InvoiceNumber = customs.invoiceNumber;
|
|
30
|
+
if (customs.invoiceDate)
|
|
31
|
+
forms.InvoiceDate = customs.invoiceDate;
|
|
32
|
+
return forms;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=buildInternationalForms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildInternationalForms.js","sourceRoot":"","sources":["../../../../nodes/Ups/core/buildInternationalForms.ts"],"names":[],"mappings":";;AAsBA,0DA8BC;AA9BD,SAAgB,uBAAuB,CACtC,OAAqB,EACrB,WAAsB;;IAEtB,MAAM,KAAK,GAAuB;QACjC,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,YAAY,EAAE,OAAO,CAAC,QAAQ;QAC9B,QAAQ,EAAE;YACT,MAAM,EAAE;gBACP,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;gBACzB,OAAO,EAAE;oBACR,WAAW,EAAE,CAAC,MAAA,OAAO,CAAC,MAAM,CAAC,YAAY,mCAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;oBACxF,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;oBACzB,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW;iBACvC;aACD;SACD;QACD,OAAO,EAAE,WAAW;KACpB,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,CAAC,iBAAiB;QACnC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACpF,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU;QAC5B,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;IACtE,IAAI,OAAO,CAAC,eAAe;QAAE,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAC7E,IAAI,OAAO,CAAC,aAAa;QAAE,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IACvE,IAAI,OAAO,CAAC,WAAW;QAAE,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAEjE,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Money } from './types';
|
|
2
|
+
import { type UpsCharge } from './toMoney';
|
|
3
|
+
export interface ExtractedCharges {
|
|
4
|
+
published: Money | null;
|
|
5
|
+
negotiated: Money | null;
|
|
6
|
+
}
|
|
7
|
+
interface ShipChargeResponse {
|
|
8
|
+
ShipmentResponse?: {
|
|
9
|
+
ShipmentResults?: {
|
|
10
|
+
ShipmentCharges?: {
|
|
11
|
+
TotalCharges?: UpsCharge;
|
|
12
|
+
};
|
|
13
|
+
NegotiatedRateCharges?: {
|
|
14
|
+
TotalCharge?: UpsCharge;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare function extractCharges(response: ShipChargeResponse): ExtractedCharges;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractCharges = extractCharges;
|
|
4
|
+
const toMoney_1 = require("./toMoney");
|
|
5
|
+
function extractCharges(response) {
|
|
6
|
+
var _a, _b, _c;
|
|
7
|
+
const results = (_a = response.ShipmentResponse) === null || _a === void 0 ? void 0 : _a.ShipmentResults;
|
|
8
|
+
return {
|
|
9
|
+
published: (0, toMoney_1.toMoney)((_b = results === null || results === void 0 ? void 0 : results.ShipmentCharges) === null || _b === void 0 ? void 0 : _b.TotalCharges),
|
|
10
|
+
negotiated: (0, toMoney_1.toMoney)((_c = results === null || results === void 0 ? void 0 : results.NegotiatedRateCharges) === null || _c === void 0 ? void 0 : _c.TotalCharge),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=extractCharges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractCharges.js","sourceRoot":"","sources":["../../../../nodes/Ups/core/extractCharges.ts"],"names":[],"mappings":";;AAuBA,wCAMC;AA5BD,uCAAoD;AAsBpD,SAAgB,cAAc,CAAC,QAA4B;;IAC1D,MAAM,OAAO,GAAG,MAAA,QAAQ,CAAC,gBAAgB,0CAAE,eAAe,CAAC;IAC3D,OAAO;QACN,SAAS,EAAE,IAAA,iBAAO,EAAC,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,eAAe,0CAAE,YAAY,CAAC;QAC1D,UAAU,EAAE,IAAA,iBAAO,EAAC,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,qBAAqB,0CAAE,WAAW,CAAC;KAChE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface ExtractedForm {
|
|
2
|
+
base64: string;
|
|
3
|
+
mime: string;
|
|
4
|
+
filename: string;
|
|
5
|
+
}
|
|
6
|
+
interface RawForm {
|
|
7
|
+
Image?: {
|
|
8
|
+
GraphicImage?: string;
|
|
9
|
+
ImageFormat?: {
|
|
10
|
+
Code?: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface ShipResponse {
|
|
15
|
+
ShipmentResponse?: {
|
|
16
|
+
ShipmentResults?: {
|
|
17
|
+
ShipmentIdentificationNumber?: string;
|
|
18
|
+
Form?: RawForm[] | RawForm;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare function extractForms(response: ShipResponse): ExtractedForm[];
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractForms = extractForms;
|
|
4
|
+
function toArray(value) {
|
|
5
|
+
if (value === undefined || value === null)
|
|
6
|
+
return [];
|
|
7
|
+
return Array.isArray(value) ? value : [value];
|
|
8
|
+
}
|
|
9
|
+
function extractForms(response) {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const results = (_a = response.ShipmentResponse) === null || _a === void 0 ? void 0 : _a.ShipmentResults;
|
|
12
|
+
const shipmentId = (_b = results === null || results === void 0 ? void 0 : results.ShipmentIdentificationNumber) !== null && _b !== void 0 ? _b : 'shipment';
|
|
13
|
+
const forms = toArray(results === null || results === void 0 ? void 0 : results.Form);
|
|
14
|
+
return forms
|
|
15
|
+
.filter((form) => { var _a; return (_a = form.Image) === null || _a === void 0 ? void 0 : _a.GraphicImage; })
|
|
16
|
+
.map((form, index) => {
|
|
17
|
+
var _a;
|
|
18
|
+
return ({
|
|
19
|
+
base64: (_a = form.Image) === null || _a === void 0 ? void 0 : _a.GraphicImage,
|
|
20
|
+
mime: 'application/pdf',
|
|
21
|
+
filename: `customs-invoice-${shipmentId}${index > 0 ? `-${index + 1}` : ''}.pdf`,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=extractForms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractForms.js","sourceRoot":"","sources":["../../../../nodes/Ups/core/extractForms.ts"],"names":[],"mappings":";;AA4BA,oCAaC;AAlBD,SAAS,OAAO,CAAI,KAA0B;IAC7C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACrD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,SAAgB,YAAY,CAAC,QAAsB;;IAClD,MAAM,OAAO,GAAG,MAAA,QAAQ,CAAC,gBAAgB,0CAAE,eAAe,CAAC;IAC3D,MAAM,UAAU,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,4BAA4B,mCAAI,UAAU,CAAC;IACvE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC,CAAC;IAErC,OAAO,KAAK;SACV,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,WAAC,OAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,YAAY,CAAA,EAAA,CAAC;SAC1C,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;;QAAC,OAAA,CAAC;YACtB,MAAM,EAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,YAAsB;YAE1C,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,mBAAmB,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM;SAChF,CAAC,CAAA;KAAA,CAAC,CAAC;AACN,CAAC"}
|