@alchemy.run/axiom 2.0.0-beta.84 → 2.0.0-beta.86
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/lib/Annotation.d.ts.map +1 -1
- package/lib/Annotation.js +2 -2
- package/lib/Annotation.js.map +1 -1
- package/lib/ApiToken.d.ts +10 -0
- package/lib/ApiToken.d.ts.map +1 -1
- package/lib/ApiToken.js +10 -3
- package/lib/ApiToken.js.map +1 -1
- package/lib/AuthProvider.d.ts +1 -1
- package/lib/AuthProvider.d.ts.map +1 -1
- package/lib/AuthProvider.js.map +1 -1
- package/lib/Chart.d.ts.map +1 -1
- package/lib/Chart.js.map +1 -1
- package/lib/Contributions.d.ts +1 -1
- package/lib/Contributions.d.ts.map +1 -1
- package/lib/Contributions.js.map +1 -1
- package/lib/Credentials.d.ts +1 -1
- package/lib/Credentials.d.ts.map +1 -1
- package/lib/Credentials.js +7 -20
- package/lib/Credentials.js.map +1 -1
- package/lib/Dashboard.d.ts +24 -5
- package/lib/Dashboard.d.ts.map +1 -1
- package/lib/Dashboard.js +23 -10
- package/lib/Dashboard.js.map +1 -1
- package/lib/Dataset.d.ts +28 -1
- package/lib/Dataset.d.ts.map +1 -1
- package/lib/Dataset.js +24 -4
- package/lib/Dataset.js.map +1 -1
- package/lib/Monitor.d.ts +19 -1
- package/lib/Monitor.d.ts.map +1 -1
- package/lib/Monitor.js +15 -2
- package/lib/Monitor.js.map +1 -1
- package/lib/Notifier.d.ts +19 -1
- package/lib/Notifier.d.ts.map +1 -1
- package/lib/Notifier.js +15 -2
- package/lib/Notifier.js.map +1 -1
- package/lib/OtelHeaders.d.ts.map +1 -1
- package/lib/OtelHeaders.js.map +1 -1
- package/lib/Providers.d.ts +1 -1
- package/lib/Providers.d.ts.map +1 -1
- package/lib/Providers.js.map +1 -1
- package/lib/Telemetry.d.ts.map +1 -1
- package/lib/Telemetry.js.map +1 -1
- package/lib/View.d.ts +19 -1
- package/lib/View.d.ts.map +1 -1
- package/lib/View.js +15 -2
- package/lib/View.js.map +1 -1
- package/lib/VirtualField.d.ts +19 -1
- package/lib/VirtualField.d.ts.map +1 -1
- package/lib/VirtualField.js +15 -2
- package/lib/VirtualField.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +8 -8
- package/src/Annotation.ts +2 -2
- package/src/ApiToken.ts +13 -3
- package/src/Credentials.ts +7 -49
- package/src/Dashboard.ts +43 -15
- package/src/Dataset.ts +41 -7
- package/src/Monitor.ts +27 -3
- package/src/Notifier.ts +30 -3
- package/src/View.ts +30 -3
- package/src/VirtualField.ts +27 -3
package/src/Credentials.ts
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import { Credentials } from "@distilled.cloud/axiom/Credentials";
|
|
2
2
|
import { ConfigError } from "@distilled.cloud/core/errors";
|
|
3
|
-
import {
|
|
4
|
-
deferUntilFirstUse,
|
|
5
|
-
orDieCredentialsUnavailable,
|
|
6
|
-
resolveProviderConfig,
|
|
7
|
-
} from "alchemy/Auth/Resolve";
|
|
8
|
-
import * as Effect from "effect/Effect";
|
|
3
|
+
import { lazyCredentials } from "alchemy/Auth/Resolve";
|
|
9
4
|
import * as Layer from "effect/Layer";
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
AXIOM_AUTH_PROVIDER_NAME,
|
|
13
|
-
type AxiomAuthConfig,
|
|
14
|
-
type AxiomResolvedCredentials,
|
|
15
|
-
} from "./AuthProvider.ts";
|
|
5
|
+
import { AXIOM_AUTH_PROVIDER_NAME, type AxiomResolvedCredentials } from "./AuthProvider.ts";
|
|
16
6
|
|
|
17
7
|
export {
|
|
18
8
|
Credentials,
|
|
@@ -28,41 +18,9 @@ export {
|
|
|
28
18
|
export const fromAuthProvider = () =>
|
|
29
19
|
Layer.effect(
|
|
30
20
|
Credentials,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
).pipe(
|
|
37
|
-
Effect.flatMap(({ profileName, resolve }) =>
|
|
38
|
-
resolve.pipe(
|
|
39
|
-
Effect.map((creds) =>
|
|
40
|
-
Match.value(creds).pipe(
|
|
41
|
-
Match.when({ type: "apiToken" }, (c) => ({
|
|
42
|
-
apiKey: c.apiToken,
|
|
43
|
-
apiBaseUrl: c.apiBaseUrl,
|
|
44
|
-
orgId: c.orgId,
|
|
45
|
-
})),
|
|
46
|
-
Match.when({ type: "pat" }, (c) => ({
|
|
47
|
-
apiKey: c.apiToken,
|
|
48
|
-
apiBaseUrl: c.apiBaseUrl,
|
|
49
|
-
orgId: c.orgId,
|
|
50
|
-
})),
|
|
51
|
-
Match.exhaustive,
|
|
52
|
-
),
|
|
53
|
-
),
|
|
54
|
-
Effect.mapError((e) =>
|
|
55
|
-
ConfigError.make({
|
|
56
|
-
message: `Failed to resolve Axiom credentials from ${profileName === undefined ? "the CI environment" : `profile '${profileName}'`}: ${(e as { message?: string }).message ?? String(e)}`,
|
|
57
|
-
}),
|
|
58
|
-
),
|
|
59
|
-
),
|
|
60
|
-
),
|
|
61
|
-
deferUntilFirstUse,
|
|
62
|
-
);
|
|
63
|
-
return yield* resolve.pipe(
|
|
64
|
-
orDieCredentialsUnavailable(AXIOM_AUTH_PROVIDER_NAME),
|
|
65
|
-
Effect.cached,
|
|
66
|
-
);
|
|
67
|
-
}),
|
|
21
|
+
lazyCredentials<AxiomResolvedCredentials, ConfigError>()(AXIOM_AUTH_PROVIDER_NAME, (creds) => ({
|
|
22
|
+
apiKey: creds.apiToken,
|
|
23
|
+
apiBaseUrl: creds.apiBaseUrl,
|
|
24
|
+
orgId: creds.orgId,
|
|
25
|
+
})),
|
|
68
26
|
);
|
package/src/Dashboard.ts
CHANGED
|
@@ -14,17 +14,28 @@ export type Dashboard = Resource<
|
|
|
14
14
|
/** Stable Axiom dashboard `uid` (used as the path identifier). */
|
|
15
15
|
uid: string;
|
|
16
16
|
id: string;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
/** Axiom omits the audit fields on some dashboards. */
|
|
18
|
+
createdAt: string | undefined;
|
|
19
|
+
createdBy: string | undefined;
|
|
20
|
+
updatedAt: string | undefined;
|
|
21
|
+
updatedBy: string | undefined;
|
|
21
22
|
/** The full dashboard document as returned by Axiom. */
|
|
22
23
|
dashboard: Axiom.DashboardWriteResponse["dashboard"]["dashboard"];
|
|
23
24
|
},
|
|
24
25
|
never,
|
|
25
|
-
Providers
|
|
26
|
+
Providers,
|
|
27
|
+
DashboardLookup
|
|
26
28
|
>;
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Props for {@link Dashboard.lookup}: find a dashboard this stack
|
|
32
|
+
* doesn't manage by its id.
|
|
33
|
+
*/
|
|
34
|
+
export interface DashboardLookup {
|
|
35
|
+
/** Axiom dashboard id. */
|
|
36
|
+
uid: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
/**
|
|
29
40
|
* An Axiom dashboard — a named, layout-driven collection of charts. Each
|
|
30
41
|
* dashboard takes a full document (`charts` + `layout` array of grid cells +
|
|
@@ -114,6 +125,16 @@ export type Dashboard = Resource<
|
|
|
114
125
|
* });
|
|
115
126
|
* ```
|
|
116
127
|
*
|
|
128
|
+
* ### Looking up an existing dashboard
|
|
129
|
+
* `Dashboard.lookup` references a dashboard Alchemy doesn't manage (created in
|
|
130
|
+
* the Axiom console or by another stack). It is read during plan/deploy,
|
|
131
|
+
* never created, updated or deleted.
|
|
132
|
+
*
|
|
133
|
+
* **Example:** Reference an existing dashboard
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const ref = Axiom.Dashboard.lookup({ uid: "abc123" });
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
117
138
|
* @resource
|
|
118
139
|
* @product Dashboard
|
|
119
140
|
*/
|
|
@@ -132,19 +153,19 @@ export const DashboardProvider = () =>
|
|
|
132
153
|
const toAttrsFromCreate = (envelope: Axiom.DashboardWriteResponse) => ({
|
|
133
154
|
uid: envelope.dashboard.uid,
|
|
134
155
|
id: envelope.dashboard.id,
|
|
135
|
-
createdAt: envelope.dashboard.createdAt,
|
|
136
|
-
createdBy: envelope.dashboard.createdBy,
|
|
137
|
-
updatedAt: envelope.dashboard.updatedAt,
|
|
138
|
-
updatedBy: envelope.dashboard.updatedBy,
|
|
156
|
+
createdAt: envelope.dashboard.createdAt ?? undefined,
|
|
157
|
+
createdBy: envelope.dashboard.createdBy ?? undefined,
|
|
158
|
+
updatedAt: envelope.dashboard.updatedAt ?? undefined,
|
|
159
|
+
updatedBy: envelope.dashboard.updatedBy ?? undefined,
|
|
139
160
|
dashboard: envelope.dashboard.dashboard,
|
|
140
161
|
});
|
|
141
162
|
const toAttrsFromGet = (current: Axiom.DashboardResource) => ({
|
|
142
163
|
uid: current.uid,
|
|
143
164
|
id: current.id,
|
|
144
|
-
createdAt: current.createdAt,
|
|
145
|
-
createdBy: current.createdBy,
|
|
146
|
-
updatedAt: current.updatedAt,
|
|
147
|
-
updatedBy: current.updatedBy,
|
|
165
|
+
createdAt: current.createdAt ?? undefined,
|
|
166
|
+
createdBy: current.createdBy ?? undefined,
|
|
167
|
+
updatedAt: current.updatedAt ?? undefined,
|
|
168
|
+
updatedBy: current.updatedBy ?? undefined,
|
|
148
169
|
dashboard: current.dashboard,
|
|
149
170
|
});
|
|
150
171
|
|
|
@@ -157,7 +178,7 @@ export const DashboardProvider = () =>
|
|
|
157
178
|
// by re-creating.
|
|
158
179
|
const observed = output?.uid
|
|
159
180
|
? yield* get({ uid: output.uid }).pipe(
|
|
160
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
181
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
161
182
|
)
|
|
162
183
|
: undefined;
|
|
163
184
|
|
|
@@ -174,11 +195,18 @@ export const DashboardProvider = () =>
|
|
|
174
195
|
delete: Effect.fn(function* ({ output }) {
|
|
175
196
|
yield* del({ uid: output.uid }).pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
176
197
|
}),
|
|
198
|
+
lookup: Effect.fn(function* ({ uid }) {
|
|
199
|
+
return yield* get({ uid }).pipe(
|
|
200
|
+
Effect.map(toAttrsFromGet),
|
|
201
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
202
|
+
);
|
|
203
|
+
}),
|
|
204
|
+
|
|
177
205
|
read: Effect.fn(function* ({ output }) {
|
|
178
206
|
if (!output?.uid) return undefined;
|
|
179
207
|
return yield* get({ uid: output.uid }).pipe(
|
|
180
208
|
Effect.map(toAttrsFromGet),
|
|
181
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
209
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
182
210
|
);
|
|
183
211
|
}),
|
|
184
212
|
// Enumerate every dashboard visible to the caller. `GET /v2/dashboards`
|
package/src/Dataset.ts
CHANGED
|
@@ -6,10 +6,16 @@ import * as Provider from "alchemy/Provider";
|
|
|
6
6
|
import { Resource } from "alchemy/Resource";
|
|
7
7
|
import { Stack } from "alchemy/Stack";
|
|
8
8
|
import { Stage } from "alchemy/Stage";
|
|
9
|
+
import * as Data from "effect/Data";
|
|
9
10
|
import * as Effect from "effect/Effect";
|
|
10
11
|
import { otelDatasetHeader } from "./OtelHeaders.ts";
|
|
11
12
|
import type { Providers } from "./Providers.ts";
|
|
12
13
|
|
|
14
|
+
export class DatasetUnexpectedResponse extends Data.TaggedError("DatasetUnexpectedResponse")<{
|
|
15
|
+
readonly message: string;
|
|
16
|
+
readonly cause?: unknown;
|
|
17
|
+
}> {}
|
|
18
|
+
|
|
13
19
|
export type DatasetKind =
|
|
14
20
|
| "otel:metrics:v1"
|
|
15
21
|
| "otel:traces:v1"
|
|
@@ -82,9 +88,19 @@ export type Dataset = Resource<
|
|
|
82
88
|
otelHeaders: Record<string, string>;
|
|
83
89
|
},
|
|
84
90
|
never,
|
|
85
|
-
Providers
|
|
91
|
+
Providers,
|
|
92
|
+
DatasetLookup
|
|
86
93
|
>;
|
|
87
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Props for {@link Dataset.lookup}: find a dataset this stack
|
|
97
|
+
* doesn't manage by its name.
|
|
98
|
+
*/
|
|
99
|
+
export interface DatasetLookup {
|
|
100
|
+
/** Dataset name. */
|
|
101
|
+
name: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
88
104
|
/**
|
|
89
105
|
* An Axiom dataset — the top-level container that stores events, logs,
|
|
90
106
|
* traces, or metrics. Pick a `kind` up-front: it determines schema and how
|
|
@@ -132,6 +148,16 @@ export type Dataset = Resource<
|
|
|
132
148
|
* });
|
|
133
149
|
* ```
|
|
134
150
|
*
|
|
151
|
+
* ### Looking up an existing dataset
|
|
152
|
+
* `Dataset.lookup` references a dataset Alchemy doesn't manage (created in
|
|
153
|
+
* the Axiom console or by another stack). It is read during plan/deploy,
|
|
154
|
+
* never created, updated or deleted.
|
|
155
|
+
*
|
|
156
|
+
* **Example:** Ingest into an existing dataset
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const logs = Axiom.Dataset.lookup({ name: "logs" });
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
135
161
|
* @resource
|
|
136
162
|
* @product Dataset
|
|
137
163
|
*/
|
|
@@ -169,7 +195,7 @@ export const DatasetProvider = () =>
|
|
|
169
195
|
Provider.effect(
|
|
170
196
|
Dataset,
|
|
171
197
|
Effect.gen(function* () {
|
|
172
|
-
const
|
|
198
|
+
const credentials = yield* Credentials;
|
|
173
199
|
const create = yield* Axiom.createDataset;
|
|
174
200
|
const update = yield* Axiom.updateDataset;
|
|
175
201
|
const get = yield* Axiom.getDataset;
|
|
@@ -178,10 +204,11 @@ export const DatasetProvider = () =>
|
|
|
178
204
|
|
|
179
205
|
const toAttrs = Effect.fn(function* (dataset: Axiom.Dataset) {
|
|
180
206
|
if (!dataset.edgeDeployment || !dataset.edgeDeploymentUrl) {
|
|
181
|
-
return yield*
|
|
182
|
-
|
|
183
|
-
);
|
|
207
|
+
return yield* new DatasetUnexpectedResponse({
|
|
208
|
+
message: `Axiom dataset "${dataset.name}" is missing its edge deployment metadata`,
|
|
209
|
+
});
|
|
184
210
|
}
|
|
211
|
+
const { apiBaseUrl } = yield* credentials;
|
|
185
212
|
const apiRoot = apiBaseUrl.replace(/\/$/, "");
|
|
186
213
|
const otelRoot = dataset.edgeDeploymentUrl.replace(/\/$/, "");
|
|
187
214
|
return {
|
|
@@ -246,7 +273,7 @@ export const DatasetProvider = () =>
|
|
|
246
273
|
// here mutation is safe.
|
|
247
274
|
const datasetId = output?.id ?? news.name;
|
|
248
275
|
const observed = yield* get({ dataset_id: datasetId }).pipe(
|
|
249
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
276
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
250
277
|
);
|
|
251
278
|
|
|
252
279
|
// Ensure — POST creates the dataset. Tolerate Conflict/
|
|
@@ -303,13 +330,20 @@ export const DatasetProvider = () =>
|
|
|
303
330
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
304
331
|
);
|
|
305
332
|
}),
|
|
333
|
+
lookup: Effect.fn(function* ({ name }) {
|
|
334
|
+
const existing = yield* get({ dataset_id: name }).pipe(
|
|
335
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
336
|
+
);
|
|
337
|
+
return existing === undefined ? undefined : yield* toAttrs(existing);
|
|
338
|
+
}),
|
|
339
|
+
|
|
306
340
|
read: Effect.fn(function* ({ id, olds, output }) {
|
|
307
341
|
const stack = yield* Stack;
|
|
308
342
|
const stage = yield* Stage;
|
|
309
343
|
const datasetId = output?.id ?? olds?.name;
|
|
310
344
|
if (!datasetId) return undefined;
|
|
311
345
|
const existing = yield* get({ dataset_id: datasetId }).pipe(
|
|
312
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
346
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
313
347
|
);
|
|
314
348
|
if (!existing) return undefined;
|
|
315
349
|
const ownership = parseMarker(existing.description);
|
package/src/Monitor.ts
CHANGED
|
@@ -12,9 +12,19 @@ export type Monitor = Resource<
|
|
|
12
12
|
MonitorProps,
|
|
13
13
|
Axiom.CreateMonitorResponse,
|
|
14
14
|
never,
|
|
15
|
-
Providers
|
|
15
|
+
Providers,
|
|
16
|
+
MonitorLookup
|
|
16
17
|
>;
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Props for {@link Monitor.lookup}: find a monitor this stack
|
|
21
|
+
* doesn't manage by its id.
|
|
22
|
+
*/
|
|
23
|
+
export interface MonitorLookup {
|
|
24
|
+
/** Axiom monitor id. */
|
|
25
|
+
id: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* An Axiom monitor — a scheduled APL/MPL query that evaluates on a fixed
|
|
20
30
|
* cadence and fires alerts via {@link Notifier notifiers} when its
|
|
@@ -79,6 +89,16 @@ export type Monitor = Resource<
|
|
|
79
89
|
* });
|
|
80
90
|
* ```
|
|
81
91
|
*
|
|
92
|
+
* ### Looking up an existing monitor
|
|
93
|
+
* `Monitor.lookup` references a monitor Alchemy doesn't manage (created in
|
|
94
|
+
* the Axiom console or by another stack). It is read during plan/deploy,
|
|
95
|
+
* never created, updated or deleted.
|
|
96
|
+
*
|
|
97
|
+
* **Example:** Reference an existing monitor
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const ref = Axiom.Monitor.lookup({ id: "m_abc123" });
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
82
102
|
* @resource
|
|
83
103
|
* @product Monitor
|
|
84
104
|
*/
|
|
@@ -121,7 +141,7 @@ export const MonitorProvider = () =>
|
|
|
121
141
|
// re-creating.
|
|
122
142
|
const observed = output?.id
|
|
123
143
|
? yield* get({ id: output.id }).pipe(
|
|
124
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
144
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
125
145
|
)
|
|
126
146
|
: undefined;
|
|
127
147
|
|
|
@@ -137,10 +157,14 @@ export const MonitorProvider = () =>
|
|
|
137
157
|
delete: Effect.fn(function* ({ output }) {
|
|
138
158
|
yield* del({ id: output.id }).pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
139
159
|
}),
|
|
160
|
+
lookup: Effect.fn(function* ({ id }) {
|
|
161
|
+
return yield* get({ id }).pipe(Effect.catchTag("NotFound", () => Effect.undefined));
|
|
162
|
+
}),
|
|
163
|
+
|
|
140
164
|
read: Effect.fn(function* ({ output }) {
|
|
141
165
|
if (!output?.id) return undefined;
|
|
142
166
|
return yield* get({ id: output.id }).pipe(
|
|
143
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
167
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
144
168
|
);
|
|
145
169
|
}),
|
|
146
170
|
};
|
package/src/Notifier.ts
CHANGED
|
@@ -11,9 +11,19 @@ export type Notifier = Resource<
|
|
|
11
11
|
NotifierProps,
|
|
12
12
|
Axiom.CreateNotifierResponse & { id: string },
|
|
13
13
|
never,
|
|
14
|
-
Providers
|
|
14
|
+
Providers,
|
|
15
|
+
NotifierLookup
|
|
15
16
|
>;
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Props for {@link Notifier.lookup}: find a notifier this stack
|
|
20
|
+
* doesn't manage by its id.
|
|
21
|
+
*/
|
|
22
|
+
export interface NotifierLookup {
|
|
23
|
+
/** Axiom notifier id. */
|
|
24
|
+
id: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
/**
|
|
18
28
|
* An Axiom notifier — an alert destination (Slack, email, PagerDuty,
|
|
19
29
|
* Opsgenie, Discord, Microsoft Teams, generic webhook, or a fully custom
|
|
@@ -65,6 +75,16 @@ export type Notifier = Resource<
|
|
|
65
75
|
* });
|
|
66
76
|
* ```
|
|
67
77
|
*
|
|
78
|
+
* ### Looking up an existing notifier
|
|
79
|
+
* `Notifier.lookup` references a notifier Alchemy doesn't manage (created in
|
|
80
|
+
* the Axiom console or by another stack). It is read during plan/deploy,
|
|
81
|
+
* never created, updated or deleted.
|
|
82
|
+
*
|
|
83
|
+
* **Example:** Reference an existing notifier
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const ref = Axiom.Notifier.lookup({ id: "n_abc123" });
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
68
88
|
* @resource
|
|
69
89
|
* @product Monitor
|
|
70
90
|
*/
|
|
@@ -100,7 +120,7 @@ export const NotifierProvider = () =>
|
|
|
100
120
|
// by re-creating.
|
|
101
121
|
const observed = output?.id
|
|
102
122
|
? yield* get({ id: output.id }).pipe(
|
|
103
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
123
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
104
124
|
)
|
|
105
125
|
: undefined;
|
|
106
126
|
|
|
@@ -121,6 +141,13 @@ export const NotifierProvider = () =>
|
|
|
121
141
|
delete: Effect.fn(function* ({ output }) {
|
|
122
142
|
yield* del({ id: output.id }).pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
123
143
|
}),
|
|
144
|
+
lookup: Effect.fn(function* ({ id }) {
|
|
145
|
+
return yield* get({ id }).pipe(
|
|
146
|
+
Effect.map((current) => ({ ...current, id: current.id ?? id })),
|
|
147
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
148
|
+
);
|
|
149
|
+
}),
|
|
150
|
+
|
|
124
151
|
read: Effect.fn(function* ({ output }) {
|
|
125
152
|
if (!output?.id) return undefined;
|
|
126
153
|
return yield* get({ id: output.id }).pipe(
|
|
@@ -128,7 +155,7 @@ export const NotifierProvider = () =>
|
|
|
128
155
|
...current,
|
|
129
156
|
id: current.id ?? output.id,
|
|
130
157
|
})),
|
|
131
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
158
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
132
159
|
);
|
|
133
160
|
}),
|
|
134
161
|
};
|
package/src/View.ts
CHANGED
|
@@ -19,9 +19,19 @@ export type View = Resource<
|
|
|
19
19
|
id: string;
|
|
20
20
|
},
|
|
21
21
|
never,
|
|
22
|
-
Providers
|
|
22
|
+
Providers,
|
|
23
|
+
ViewLookup
|
|
23
24
|
>;
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Props for {@link View.lookup}: find a view this stack
|
|
28
|
+
* doesn't manage by its id.
|
|
29
|
+
*/
|
|
30
|
+
export interface ViewLookup {
|
|
31
|
+
/** Axiom view id. */
|
|
32
|
+
id: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
/**
|
|
26
36
|
* An Axiom saved view — a named, shareable APL query. Useful for building
|
|
27
37
|
* starter dashboards, providing canned "open in Axiom" links from your app,
|
|
@@ -60,6 +70,16 @@ export type View = Resource<
|
|
|
60
70
|
* });
|
|
61
71
|
* ```
|
|
62
72
|
*
|
|
73
|
+
* ### Looking up an existing view
|
|
74
|
+
* `View.lookup` references a view Alchemy doesn't manage (created in
|
|
75
|
+
* the Axiom console or by another stack). It is read during plan/deploy,
|
|
76
|
+
* never created, updated or deleted.
|
|
77
|
+
*
|
|
78
|
+
* **Example:** Reference an existing view
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const ref = Axiom.View.lookup({ id: "v_abc123" });
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
63
83
|
* @resource
|
|
64
84
|
* @product Dashboard
|
|
65
85
|
*/
|
|
@@ -101,7 +121,7 @@ export const ViewProvider = () =>
|
|
|
101
121
|
// current `news.name` always agree by the time we land here.
|
|
102
122
|
const viewId = output?.id ?? news.name;
|
|
103
123
|
const observed = yield* get({ id: viewId }).pipe(
|
|
104
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
124
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
105
125
|
);
|
|
106
126
|
|
|
107
127
|
// Ensure — POST creates the view under `news.name`.
|
|
@@ -118,11 +138,18 @@ export const ViewProvider = () =>
|
|
|
118
138
|
delete: Effect.fn(function* ({ output }) {
|
|
119
139
|
yield* del({ id: output.id }).pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
120
140
|
}),
|
|
141
|
+
lookup: Effect.fn(function* ({ id }) {
|
|
142
|
+
return yield* get({ id }).pipe(
|
|
143
|
+
Effect.map((current) => ({ ...current, id })),
|
|
144
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
145
|
+
);
|
|
146
|
+
}),
|
|
147
|
+
|
|
121
148
|
read: Effect.fn(function* ({ output }) {
|
|
122
149
|
if (!output?.id) return undefined;
|
|
123
150
|
return yield* get({ id: output.id }).pipe(
|
|
124
151
|
Effect.map((current) => ({ ...current, id: output.id })),
|
|
125
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
152
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
126
153
|
);
|
|
127
154
|
}),
|
|
128
155
|
};
|
package/src/VirtualField.ts
CHANGED
|
@@ -12,9 +12,19 @@ export type VirtualField = Resource<
|
|
|
12
12
|
VirtualFieldProps,
|
|
13
13
|
Axiom.CreateVirtualFieldResponse,
|
|
14
14
|
never,
|
|
15
|
-
Providers
|
|
15
|
+
Providers,
|
|
16
|
+
VirtualFieldLookup
|
|
16
17
|
>;
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Props for {@link VirtualField.lookup}: find a virtual field this stack
|
|
21
|
+
* doesn't manage by its id.
|
|
22
|
+
*/
|
|
23
|
+
export interface VirtualFieldLookup {
|
|
24
|
+
/** Axiom virtual field id. */
|
|
25
|
+
id: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* An Axiom virtual field — a saved APL expression that appears as a derived
|
|
20
30
|
* column on a dataset at query time. Use these to standardise common
|
|
@@ -47,6 +57,16 @@ export type VirtualField = Resource<
|
|
|
47
57
|
* });
|
|
48
58
|
* ```
|
|
49
59
|
*
|
|
60
|
+
* ### Looking up an existing virtual field
|
|
61
|
+
* `VirtualField.lookup` references a virtual field Alchemy doesn't manage (created in
|
|
62
|
+
* the Axiom console or by another stack). It is read during plan/deploy,
|
|
63
|
+
* never created, updated or deleted.
|
|
64
|
+
*
|
|
65
|
+
* **Example:** Reference an existing virtual field
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const ref = Axiom.VirtualField.lookup({ id: "vf_abc123" });
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
50
70
|
* @resource
|
|
51
71
|
* @product Dataset
|
|
52
72
|
*/
|
|
@@ -96,7 +116,7 @@ export const VirtualFieldProvider = () =>
|
|
|
96
116
|
// re-creating.
|
|
97
117
|
const observed = output?.id
|
|
98
118
|
? yield* get({ id: output.id }).pipe(
|
|
99
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
119
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
100
120
|
)
|
|
101
121
|
: undefined;
|
|
102
122
|
|
|
@@ -112,10 +132,14 @@ export const VirtualFieldProvider = () =>
|
|
|
112
132
|
delete: Effect.fn(function* ({ output }) {
|
|
113
133
|
yield* del({ id: output.id }).pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
114
134
|
}),
|
|
135
|
+
lookup: Effect.fn(function* ({ id }) {
|
|
136
|
+
return yield* get({ id }).pipe(Effect.catchTag("NotFound", () => Effect.undefined));
|
|
137
|
+
}),
|
|
138
|
+
|
|
115
139
|
read: Effect.fn(function* ({ output }) {
|
|
116
140
|
if (!output?.id) return undefined;
|
|
117
141
|
return yield* get({ id: output.id }).pipe(
|
|
118
|
-
Effect.catchTag("NotFound", () => Effect.
|
|
142
|
+
Effect.catchTag("NotFound", () => Effect.undefined),
|
|
119
143
|
);
|
|
120
144
|
}),
|
|
121
145
|
};
|