zuplo 6.69.0 → 6.69.2
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/docs/articles/environment-variables.mdx +166 -13
- package/docs/articles/monetization/meters.mdx +5 -5
- package/docs/articles/monetization/quickstart.md +25 -18
- package/docs/articles/monetization/stripe-integration.md +6 -4
- package/docs/articles/tunnel-setup.mdx +20 -0
- package/docs/cli/whoami.mdx +25 -0
- package/package.json +4 -4
|
@@ -64,11 +64,26 @@ variable named `MY_VAR` can't be set on say the **Production** environments.
|
|
|
64
64
|
|
|
65
65
|
## Reserved Environment Variables
|
|
66
66
|
|
|
67
|
-
Environment variables can't start with `
|
|
67
|
+
Environment variables can't start with `ZUPLO_` or `__ZUPLO`. The same
|
|
68
|
+
restriction applies to names beginning with `ZUDOKU_`.
|
|
69
|
+
|
|
70
|
+
If you need a variable that's exposed to the
|
|
71
|
+
[Developer Portal](../dev-portal/introduction.mdx) build, prefix it with
|
|
72
|
+
`ZUPLO_PUBLIC_` (or `ZUDOKU_PUBLIC_`). Public-prefixed variables are bundled
|
|
73
|
+
into the portal's static output and **must not contain secrets**, as they're
|
|
74
|
+
visible to anyone who loads the page.
|
|
68
75
|
|
|
69
76
|
## Using Environment Variables
|
|
70
77
|
|
|
71
|
-
Environment variables can be used in several places
|
|
78
|
+
Environment variables can be used in several places in your Zuplo project. Each
|
|
79
|
+
location has its own syntax:
|
|
80
|
+
|
|
81
|
+
| Location | Syntax | Resolved |
|
|
82
|
+
| ----------------------------------------------------- | ---------------------- | --------------------- |
|
|
83
|
+
| Custom code (handlers, policies, hooks) | `environment.VAR_NAME` | Runtime |
|
|
84
|
+
| Configuration files (`policies.json`, OpenAPI routes) | `$env(VAR_NAME)` | Build time |
|
|
85
|
+
| URL Rewrite, URL Forward, and WebSocket handlers | `${env.VAR_NAME}` | Runtime (per request) |
|
|
86
|
+
| Developer Portal config (`zudoku.config.ts`) | `process.env.VAR_NAME` | Portal build time |
|
|
72
87
|
|
|
73
88
|
### In Code
|
|
74
89
|
|
|
@@ -77,13 +92,44 @@ See the
|
|
|
77
92
|
[Environment Variables API Reference](../programmable-api/environment.mdx) for
|
|
78
93
|
detailed usage examples and patterns.
|
|
79
94
|
|
|
95
|
+
```ts
|
|
96
|
+
import { environment } from "@zuplo/runtime";
|
|
97
|
+
|
|
98
|
+
const apiKey = environment.API_KEY; // string | undefined
|
|
99
|
+
```
|
|
100
|
+
|
|
80
101
|
### In Configuration Files
|
|
81
102
|
|
|
82
|
-
Inside
|
|
83
|
-
the
|
|
103
|
+
Inside policy options, route handler options, and CORS policy options,
|
|
104
|
+
environment variables can be referenced with the `$env(VAR_NAME)` pattern.
|
|
105
|
+
Substitutions happen at build time — the build replaces each `$env()` expression
|
|
106
|
+
with a reference to the runtime `environment` object before the project is
|
|
107
|
+
deployed.
|
|
108
|
+
|
|
109
|
+
#### Where `$env()` is allowed
|
|
110
|
+
|
|
111
|
+
- `config/policies.json` — any property under `policies[].handler.options`,
|
|
112
|
+
including nested objects and array elements
|
|
113
|
+
- `config/policies.json` — any direct property of a `corsPolicies[]` entry, such
|
|
114
|
+
as `allowedOrigins`, `allowedHeaders`, `allowedMethods`, `exposeHeaders`, and
|
|
115
|
+
`maxAge`
|
|
116
|
+
- `config/routes.oas.json` (and other OpenAPI route files) — any property under
|
|
117
|
+
a route's `x-zuplo-route.handler.options`, including nested objects and array
|
|
118
|
+
elements
|
|
119
|
+
|
|
120
|
+
`$env()` is **not** allowed in other locations such as policy `name`,
|
|
121
|
+
`policyType`, `module`, route paths, or top-level OpenAPI fields. Using it
|
|
122
|
+
elsewhere produces a build error:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
An $env() statement is not expected at this location.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Standalone substitution
|
|
84
129
|
|
|
85
|
-
|
|
86
|
-
|
|
130
|
+
When the value is _only_ an `$env()` expression, the variable's value is
|
|
131
|
+
inserted directly. The runtime type matches the type of the environment variable
|
|
132
|
+
(always a string when set, `undefined` when not).
|
|
87
133
|
|
|
88
134
|
```json
|
|
89
135
|
{
|
|
@@ -93,23 +139,130 @@ on a policy option.
|
|
|
93
139
|
"export": "default",
|
|
94
140
|
"module": "$import(./modules/YOUR_MODULE)",
|
|
95
141
|
"options": {
|
|
96
|
-
"
|
|
142
|
+
"apiKey": "$env(BACKEND_API_KEY)",
|
|
97
143
|
"config2": true
|
|
98
144
|
}
|
|
99
145
|
}
|
|
100
146
|
}
|
|
101
147
|
```
|
|
102
148
|
|
|
103
|
-
|
|
149
|
+
#### String interpolation
|
|
150
|
+
|
|
151
|
+
You can mix `$env()` with literal text to compose a value. The build wraps the
|
|
152
|
+
result in a JavaScript template literal that's evaluated at runtime, so each
|
|
153
|
+
request gets the current value of the variable.
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"options": {
|
|
158
|
+
"endpoint": "https://$env(API_HOST)/v1",
|
|
159
|
+
"userAgent": "MyGateway/$env(APP_VERSION) ($env(ENVIRONMENT_NAME))"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
:::note
|
|
165
|
+
|
|
166
|
+
If the variable isn't set, the interpolated portion resolves to an empty string.
|
|
167
|
+
For example, with `API_HOST` unset, `"https://$env(API_HOST)/v1"` becomes
|
|
168
|
+
`"https:///v1"`. Use a standalone `$env()` (no surrounding text) if you need to
|
|
169
|
+
detect an unset variable in your handler or policy code.
|
|
170
|
+
|
|
171
|
+
:::
|
|
172
|
+
|
|
173
|
+
#### In arrays
|
|
174
|
+
|
|
175
|
+
`$env()` works inside string array elements, including mixed arrays where some
|
|
176
|
+
elements are static and others are interpolated:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"options": {
|
|
181
|
+
"allowedKeys": ["$env(PRIMARY_KEY)", "$env(SECONDARY_KEY)"],
|
|
182
|
+
"tags": ["public", "$env(REGION)", "tier-$env(SERVICE_TIER)"]
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### In nested objects
|
|
188
|
+
|
|
189
|
+
`$env()` works at any depth within a handler or policy `options` object:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"options": {
|
|
194
|
+
"database": {
|
|
195
|
+
"host": "$env(DB_HOST)",
|
|
196
|
+
"credentials": {
|
|
197
|
+
"username": "$env(DB_USER)",
|
|
198
|
+
"password": "$env(DB_PASSWORD)"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### Variable name rules
|
|
206
|
+
|
|
207
|
+
The name inside `$env(...)` is matched literally up to the first closing
|
|
208
|
+
parenthesis. Use only letters, digits, and underscores in the name — matching
|
|
209
|
+
what the [Zuplo Portal](#environment-variable-editor) accepts when you create
|
|
210
|
+
the variable.
|
|
211
|
+
|
|
212
|
+
### Rewrite, Forwarding, and WebSocket Handlers
|
|
213
|
+
|
|
214
|
+
The URL Rewrite handler's `rewritePattern`, the URL Forward handler's `baseUrl`,
|
|
215
|
+
and the WebSocket handler's `rewritePattern` use a different syntax. These
|
|
216
|
+
options are evaluated as JavaScript template literals at request time, so you
|
|
217
|
+
reference variables with `${env.VAR_NAME}`:
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"handler": {
|
|
222
|
+
"export": "urlForwardHandler",
|
|
223
|
+
"module": "$import(@zuplo/runtime)",
|
|
224
|
+
"options": {
|
|
225
|
+
"baseUrl": "https://${env.BACKEND_HOST}"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Because `rewritePattern` and `baseUrl` run as code, they also have access to the
|
|
232
|
+
request, URL parts, route params, and query string. See the
|
|
233
|
+
[URL Rewrite Handler](../handlers/url-rewrite.mdx) docs for the full list of
|
|
234
|
+
available variables.
|
|
104
235
|
|
|
105
|
-
|
|
106
|
-
URL Forward handler, variables are substituted using JavaScript style string
|
|
107
|
-
interpolation.
|
|
236
|
+
:::caution
|
|
108
237
|
|
|
109
|
-
|
|
110
|
-
|
|
238
|
+
Using `$env(VAR_NAME)` inside `rewritePattern` or `baseUrl` is the most common
|
|
239
|
+
mistake. The build will warn you when it detects this, but the value will be
|
|
240
|
+
passed through to the handler as a literal string and the rewrite will fail at
|
|
241
|
+
runtime. Always use `${env.VAR_NAME}` in these two options.
|
|
242
|
+
|
|
243
|
+
:::
|
|
244
|
+
|
|
245
|
+
### In the Developer Portal
|
|
246
|
+
|
|
247
|
+
The Developer Portal's `zudoku.config.ts` runs in Node-like build tooling and
|
|
248
|
+
uses `process.env` rather than `$env()`:
|
|
249
|
+
|
|
250
|
+
```ts title="zudoku.config.ts"
|
|
251
|
+
const config: ZudokuConfig = {
|
|
252
|
+
authentication: {
|
|
253
|
+
type: "auth0",
|
|
254
|
+
domain: process.env.ZUPLO_PUBLIC_AUTH0_DOMAIN,
|
|
255
|
+
clientId: process.env.ZUPLO_PUBLIC_AUTH0_CLIENT_ID,
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export default config;
|
|
111
260
|
```
|
|
112
261
|
|
|
262
|
+
Only variables prefixed with `ZUPLO_PUBLIC_` (or `ZUDOKU_PUBLIC_`) are available
|
|
263
|
+
in the portal build, and their values are embedded into the client-side bundle.
|
|
264
|
+
Don't use this prefix for any value that should remain private.
|
|
265
|
+
|
|
113
266
|
## System Environment Variables
|
|
114
267
|
|
|
115
268
|
The following variables are automatically set by the system and are available to
|
|
@@ -35,9 +35,9 @@ Track the total number of API requests:
|
|
|
35
35
|
|
|
36
36
|
```json
|
|
37
37
|
{
|
|
38
|
-
"slug": "
|
|
38
|
+
"slug": "api_requests",
|
|
39
39
|
"name": "API Requests",
|
|
40
|
-
"eventType": "
|
|
40
|
+
"eventType": "api_requests",
|
|
41
41
|
"aggregation": "SUM",
|
|
42
42
|
"valueProperty": "$.total"
|
|
43
43
|
}
|
|
@@ -50,7 +50,7 @@ Each event contains the `subscription` ID linking it to a subscription and a
|
|
|
50
50
|
{
|
|
51
51
|
"id": "5c10fade-1c9e-4d6c-8275-c52c36731d3c",
|
|
52
52
|
"specversion": "1.0",
|
|
53
|
-
"type": "
|
|
53
|
+
"type": "api_requests",
|
|
54
54
|
"source": "monetization-policy",
|
|
55
55
|
"subject": "customer-id",
|
|
56
56
|
"subscription": "01KNVXHQG356VA7T7W0V9N21GH",
|
|
@@ -142,9 +142,9 @@ curl \
|
|
|
142
142
|
--header "Content-Type: application/json" \
|
|
143
143
|
--data @- << EOF
|
|
144
144
|
{
|
|
145
|
-
"slug": "
|
|
145
|
+
"slug": "api_requests",
|
|
146
146
|
"name": "API Requests",
|
|
147
|
-
"eventType": "
|
|
147
|
+
"eventType": "api_requests",
|
|
148
148
|
"aggregation": "SUM",
|
|
149
149
|
"valueProperty": "$.total"
|
|
150
150
|
}
|
|
@@ -84,7 +84,8 @@ Add the monetization plugin to your Developer Portal configuration.
|
|
|
84
84
|
## Step 3: Configure the Monetization Service
|
|
85
85
|
|
|
86
86
|
1. Navigate to the **Services** tab in your project.
|
|
87
|
-
2. Select the environment you want to configure
|
|
87
|
+
2. Select the environment you want to configure. We will use **Working Copy**
|
|
88
|
+
for this quickstart.
|
|
88
89
|
3. Click **Configure** on the **Monetization Service** card.
|
|
89
90
|
|
|
90
91
|
## Step 4: Create a meter
|
|
@@ -93,11 +94,11 @@ Meters track what you want to measure — API calls, tokens processed, data
|
|
|
93
94
|
transferred, etc.
|
|
94
95
|
|
|
95
96
|
1. In the Monetization Service, click the **Meters** tab.
|
|
96
|
-
2. Click **Add Meter** and select **
|
|
97
|
-
3.
|
|
98
|
-
- **Name**: `Requests`
|
|
99
|
-
- **Event**: `
|
|
100
|
-
- **Description**: `API
|
|
97
|
+
2. Click **Add Meter** and select **API Requests** from the template list.
|
|
98
|
+
3. Verify the pre-filled meter details:
|
|
99
|
+
- **Name**: `API Requests`
|
|
100
|
+
- **Event**: `api_requests` — the type of event this meter listens for.
|
|
101
|
+
- **Description**: `Counts all incoming API requests`
|
|
101
102
|
- **Aggregation**: `SUM` — how values are combined (other options include
|
|
102
103
|
`COUNT`, `MAX`, etc.).
|
|
103
104
|
- **Value Property**: `$.total` — a JSONPath expression that extracts the
|
|
@@ -115,15 +116,18 @@ Feature** for each of the following:
|
|
|
115
116
|
|
|
116
117
|
| Name | Key | Linked Meter | Purpose |
|
|
117
118
|
| ---------------- | ------------------ | ------------ | ----------------------------- |
|
|
118
|
-
| API Requests | `
|
|
119
|
+
| API Requests | `api_requests` | API Requests | Usage-based (linked to meter) |
|
|
119
120
|
| Monthly Fee | `monthly_fee` | — | Flat-rate billing |
|
|
120
121
|
| Metadata Support | `metadata_support` | — | Boolean on/off feature |
|
|
121
122
|
|
|
122
123
|
:::tip{title="Key Naming Conventions"}
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
The meter key, the feature key, and the key in the monetization policy's
|
|
126
|
+
`meters` configuration must all match. For example, the API Requests meter key
|
|
127
|
+
is `api_requests`, the feature key must also be `api_requests`, and the policy
|
|
128
|
+
must use `"meters": { "api_requests": 1 }`.
|
|
129
|
+
|
|
130
|
+
See [Naming Consistency](./meters.mdx#naming-consistency) for the full rule.
|
|
127
131
|
|
|
128
132
|
:::
|
|
129
133
|
|
|
@@ -243,10 +247,13 @@ charges.
|
|
|
243
247
|
|
|
244
248
|
:::warning
|
|
245
249
|
|
|
246
|
-
Always use your Stripe **test** key (`sk_test_...`)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
+
Always use your Stripe **test** key (`sk_test_...`) in the **Working Copy**
|
|
251
|
+
environment while following this guide. Stripe test keys run in a sandbox
|
|
252
|
+
environment where you can safely test subscriptions and payments without
|
|
253
|
+
processing real transactions. When you're ready for production, configure the
|
|
254
|
+
**Production** environment with a live key (`sk_live_...`). Do not replace a
|
|
255
|
+
test key with a live key in the same environment — use one key type per
|
|
256
|
+
environment.
|
|
250
257
|
|
|
251
258
|
:::
|
|
252
259
|
|
|
@@ -265,9 +272,9 @@ directory.
|
|
|
265
272
|
|
|
266
273
|

|
|
267
274
|
|
|
268
|
-
3. In the **Meters** configuration field,
|
|
269
|
-
|
|
270
|
-
|
|
275
|
+
3. In the **Meters** configuration field, set the key to `api_requests` with a
|
|
276
|
+
value of `1` to match the meter you created in _Step 4_. This field maps the
|
|
277
|
+
meter slug to the number of units each request consumes.
|
|
271
278
|
|
|
272
279
|
```json
|
|
273
280
|
{
|
|
@@ -276,7 +283,7 @@ directory.
|
|
|
276
283
|
"options": {
|
|
277
284
|
"cacheTtlSeconds": 60,
|
|
278
285
|
"meters": {
|
|
279
|
-
"
|
|
286
|
+
"api_requests": 1
|
|
280
287
|
}
|
|
281
288
|
}
|
|
282
289
|
}
|
|
@@ -54,13 +54,15 @@ Connect with a Stripe **test** key (`sk_test_...`) first to validate your
|
|
|
54
54
|
configuration end-to-end. Test mode uses Stripe's test card numbers (e.g.,
|
|
55
55
|
`4242 4242 4242 4242`) and never charges real money.
|
|
56
56
|
|
|
57
|
-
When you're ready to go live,
|
|
57
|
+
When you're ready to go live, configure a separate Zuplo environment (e.g.,
|
|
58
|
+
**Production**) with your live key (`sk_live_...`).
|
|
58
59
|
|
|
59
60
|
:::caution
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
Use one Stripe key type per Zuplo environment — do not replace a test key with a
|
|
63
|
+
live key in the same environment. Test mode and live mode are separate
|
|
64
|
+
environments in Stripe. Products, customers, and subscriptions created in test
|
|
65
|
+
mode don't transfer to live mode and vice versa.
|
|
64
66
|
|
|
65
67
|
:::
|
|
66
68
|
|
|
@@ -22,6 +22,26 @@ A tunnel is a way to expose your _internal services_ to the Zuplo gateway
|
|
|
22
22
|
without exposing it to the public internet. Your Zuplo Gateway accesses those
|
|
23
23
|
services through the `service://` protocol.
|
|
24
24
|
|
|
25
|
+
## Create the tunnel
|
|
26
|
+
|
|
27
|
+
Before you deploy the tunnel container, create the tunnel in Zuplo using the
|
|
28
|
+
CLI. This gives you the tunnel record in your account and the token that you
|
|
29
|
+
will later provide to the container as `TUNNEL_TOKEN`.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
zuplo tunnel create --tunnel-name <your-tunnel-name>
|
|
33
|
+
zuplo tunnel list
|
|
34
|
+
zuplo tunnel describe --tunnel-id <your-tunnel-id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Use these commands as follows:
|
|
38
|
+
|
|
39
|
+
1. Run `zuplo tunnel create` to create the tunnel.
|
|
40
|
+
1. Run `zuplo tunnel list` to see the tunnels in your account and identify the
|
|
41
|
+
tunnel ID if you need it.
|
|
42
|
+
1. Run `zuplo tunnel describe` with the tunnel ID to retrieve the tunnel details
|
|
43
|
+
and copy the token value you will use for `TUNNEL_TOKEN`.
|
|
44
|
+
|
|
25
45
|
The easiest way to deploy your tunnel is using a Docker container. The three
|
|
26
46
|
basic requirements for deploying a secure tunnel with Docker are:
|
|
27
47
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Zuplo CLI: Whoami"
|
|
3
|
+
sidebar_label: whoami
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<CliCommand
|
|
7
|
+
command="whoami"
|
|
8
|
+
description="Displays the currently authenticated user"
|
|
9
|
+
examples={[
|
|
10
|
+
[
|
|
11
|
+
"$0 whoami",
|
|
12
|
+
"Display the currently authenticated user"
|
|
13
|
+
]
|
|
14
|
+
]}
|
|
15
|
+
usage="$0 whoami [options]"
|
|
16
|
+
>
|
|
17
|
+
|
|
18
|
+
</CliCommand>
|
|
19
|
+
|
|
20
|
+
## Global options
|
|
21
|
+
|
|
22
|
+
The following global options are available for all commands:
|
|
23
|
+
|
|
24
|
+
- [`--help`](./global-options.mdx#help)
|
|
25
|
+
- [`--api-key`](./global-options.mdx#api-key)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zuplo",
|
|
3
|
-
"version": "6.69.
|
|
3
|
+
"version": "6.69.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The programmable API Gateway",
|
|
6
6
|
"author": "Zuplo, Inc.",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"zuplo": "zuplo.js"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@zuplo/cli": "6.69.
|
|
23
|
-
"@zuplo/core": "6.69.
|
|
24
|
-
"@zuplo/runtime": "6.69.
|
|
22
|
+
"@zuplo/cli": "6.69.2",
|
|
23
|
+
"@zuplo/core": "6.69.2",
|
|
24
|
+
"@zuplo/runtime": "6.69.2",
|
|
25
25
|
"@zuplo/test": "1.4.0"
|
|
26
26
|
}
|
|
27
27
|
}
|