@homeflare/distilled-grafana 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +85 -0
  3. package/dist/credentials.d.ts +42 -0
  4. package/dist/credentials.d.ts.map +1 -0
  5. package/dist/credentials.js +48 -0
  6. package/dist/credentials.js.map +1 -0
  7. package/dist/errors.d.ts +36 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +26 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/index.d.ts +24 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +24 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/pagination.d.ts +11 -0
  16. package/dist/pagination.d.ts.map +1 -0
  17. package/dist/pagination.js +11 -0
  18. package/dist/pagination.js.map +1 -0
  19. package/dist/protocol.d.ts +18 -0
  20. package/dist/protocol.d.ts.map +1 -0
  21. package/dist/protocol.js +58 -0
  22. package/dist/protocol.js.map +1 -0
  23. package/dist/retry.d.ts +32 -0
  24. package/dist/retry.d.ts.map +1 -0
  25. package/dist/retry.js +32 -0
  26. package/dist/retry.js.map +1 -0
  27. package/dist/services/grafana.d.ts +5677 -0
  28. package/dist/services/grafana.d.ts.map +1 -0
  29. package/dist/services/grafana.js +7069 -0
  30. package/dist/services/grafana.js.map +1 -0
  31. package/dist/services/index.d.ts +2 -0
  32. package/dist/services/index.d.ts.map +1 -0
  33. package/dist/services/index.js +3 -0
  34. package/dist/services/index.js.map +1 -0
  35. package/dist/traits.d.ts +11 -0
  36. package/dist/traits.d.ts.map +1 -0
  37. package/dist/traits.js +11 -0
  38. package/dist/traits.js.map +1 -0
  39. package/package.json +81 -0
  40. package/src/credentials.ts +72 -0
  41. package/src/errors.ts +50 -0
  42. package/src/index.ts +33 -0
  43. package/src/pagination.ts +10 -0
  44. package/src/protocol.ts +82 -0
  45. package/src/retry.ts +54 -0
  46. package/src/services/grafana.ts +16453 -0
  47. package/src/services/index.ts +2 -0
  48. package/src/traits.ts +44 -0
@@ -0,0 +1,2 @@
1
+ export * as grafana from "./grafana.ts";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ // AUTO-GENERATED by scripts/generate.ts. Do not edit.
2
+ export * as grafana from "./grafana.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Grafana SDK trait surface — hand-written.
3
+ *
4
+ * Re-exports the generic protocol traits from core (so generated operations
5
+ * import everything from one place). Grafana has no envelope of its own; the
6
+ * REST-protocol traits (SensitiveValue / RawResponse) come from
7
+ * `core/protocol-rest`.
8
+ */
9
+ export { Body, Header, Query, Label, Http, ResponseCode, HttpBody, FormDataFile, KeyDictionary, UnionCases, applyErrorMatchers, getErrorMatchers, type HttpTrait, type ErrorMatcher, bodySymbol, headerSymbol, querySymbol, labelSymbol, httpSymbol, responseCodeSymbol, httpBodySymbol, formDataFileSymbol, keyDictionarySymbol, unionCasesSymbol, errorMatchersSymbol, } from "@distilled.cloud/core/trait";
10
+ export { SensitiveValue, RawResponse, RawResponseRoot, sensitiveValueSymbol, rawResponseSymbol, rawResponseRootSymbol, } from "@distilled.cloud/core/protocol-rest";
11
+ //# sourceMappingURL=traits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traits.d.ts","sourceRoot":"","sources":["../src/traits.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,qCAAqC,CAAC"}
package/dist/traits.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Grafana SDK trait surface — hand-written.
3
+ *
4
+ * Re-exports the generic protocol traits from core (so generated operations
5
+ * import everything from one place). Grafana has no envelope of its own; the
6
+ * REST-protocol traits (SensitiveValue / RawResponse) come from
7
+ * `core/protocol-rest`.
8
+ */
9
+ export { Body, Header, Query, Label, Http, ResponseCode, HttpBody, FormDataFile, KeyDictionary, UnionCases, applyErrorMatchers, getErrorMatchers, bodySymbol, headerSymbol, querySymbol, labelSymbol, httpSymbol, responseCodeSymbol, httpBodySymbol, formDataFileSymbol, keyDictionarySymbol, unionCasesSymbol, errorMatchersSymbol, } from "@distilled.cloud/core/trait";
10
+ export { SensitiveValue, RawResponse, RawResponseRoot, sensitiveValueSymbol, rawResponseSymbol, rawResponseRootSymbol, } from "@distilled.cloud/core/protocol-rest";
11
+ //# sourceMappingURL=traits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traits.js","sourceRoot":"","sources":["../src/traits.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAGhB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,qCAAqC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@homeflare/distilled-grafana",
3
+ "version": "0.2.0",
4
+ "description": "Interim npm home for @distilled.cloud/grafana — see docs/distilled-interim.md. Not published upstream yet; the kit aliases @distilled.cloud/grafana onto this package until it is.",
5
+ "homepage": "https://github.com/taslabs-net/homeflare-kit/tree/main/packages/distilled-grafana#readme",
6
+ "bugs": "https://github.com/taslabs-net/homeflare-kit/issues",
7
+ "license": "Apache-2.0",
8
+ "author": "Timothy Schneider",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/taslabs-net/homeflare-kit.git",
12
+ "directory": "packages/distilled-grafana"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "src",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "type": "module",
21
+ "sideEffects": false,
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "bun": "./src/index.ts",
26
+ "worker": "./src/index.ts",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "./Credentials": {
30
+ "types": "./dist/credentials.d.ts",
31
+ "bun": "./src/credentials.ts",
32
+ "worker": "./src/credentials.ts",
33
+ "default": "./dist/credentials.js"
34
+ },
35
+ "./Errors": {
36
+ "types": "./dist/errors.d.ts",
37
+ "bun": "./src/errors.ts",
38
+ "worker": "./src/errors.ts",
39
+ "default": "./dist/errors.js"
40
+ },
41
+ "./Traits": {
42
+ "types": "./dist/traits.d.ts",
43
+ "bun": "./src/traits.ts",
44
+ "worker": "./src/traits.ts",
45
+ "default": "./dist/traits.js"
46
+ },
47
+ "./Pagination": {
48
+ "types": "./dist/pagination.d.ts",
49
+ "bun": "./src/pagination.ts",
50
+ "worker": "./src/pagination.ts",
51
+ "default": "./dist/pagination.js"
52
+ },
53
+ "./Protocol": {
54
+ "types": "./dist/protocol.d.ts",
55
+ "bun": "./src/protocol.ts",
56
+ "worker": "./src/protocol.ts",
57
+ "default": "./dist/protocol.js"
58
+ },
59
+ "./Retry": {
60
+ "types": "./dist/retry.d.ts",
61
+ "bun": "./src/retry.ts",
62
+ "worker": "./src/retry.ts",
63
+ "default": "./dist/retry.js"
64
+ },
65
+ "./*": {
66
+ "types": "./dist/services/*.d.ts",
67
+ "bun": "./src/services/*.ts",
68
+ "worker": "./src/services/*.ts",
69
+ "default": "./dist/services/*.js"
70
+ }
71
+ },
72
+ "publishConfig": {
73
+ "access": "public"
74
+ },
75
+ "dependencies": {
76
+ "@distilled.cloud/core": "1.0.0-rc.12"
77
+ },
78
+ "peerDependencies": {
79
+ "effect": "4.0.0-rc.115"
80
+ }
81
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Grafana credentials — hand-written.
3
+ *
4
+ * The `Credentials` service holds an *effect* that resolves the current
5
+ * credentials on every request (the protocol layer resolves it per request
6
+ * on the calling fiber).
7
+ *
8
+ * Grafana authenticates HTTP API requests with a service account token
9
+ * (`Authorization: Bearer <token>`). The optional `X-Grafana-Org-Id` header
10
+ * selects the organization the action applies to.
11
+ *
12
+ * The published OpenAPI document's server URL is `/api` and every path is
13
+ * relative to that prefix, so the protocol appends `/api` to the instance
14
+ * origin (`apiBaseUrl`).
15
+ */
16
+ import * as Context from "effect/Context";
17
+ import * as Effect from "effect/Effect";
18
+ import * as Layer from "effect/Layer";
19
+ import * as Redacted from "effect/Redacted";
20
+ import { ConfigError } from "@distilled.cloud/core/errors";
21
+
22
+ /** Grafana OSS default listen address (the instance origin, not `/api`). */
23
+ export const DEFAULT_API_BASE_URL = "http://localhost:3000";
24
+
25
+ export interface Config {
26
+ readonly token: Redacted.Redacted<string>;
27
+ readonly apiBaseUrl: string;
28
+ readonly orgId?: number | string;
29
+ }
30
+
31
+ export class Credentials extends Context.Service<
32
+ Credentials,
33
+ Effect.Effect<Config>
34
+ >()("GrafanaCredentials") {}
35
+
36
+ /** Layer from a plain service-account token + optional instance URL / org. */
37
+ export const fromApiKey = (config: {
38
+ readonly apiKey: string;
39
+ readonly apiBaseUrl?: string;
40
+ readonly orgId?: number | string;
41
+ }): Layer.Layer<Credentials> =>
42
+ Layer.succeed(
43
+ Credentials,
44
+ Effect.succeed({
45
+ token: Redacted.make(config.apiKey),
46
+ apiBaseUrl: config.apiBaseUrl ?? DEFAULT_API_BASE_URL,
47
+ orgId: config.orgId,
48
+ }),
49
+ );
50
+
51
+ /**
52
+ * Reads GRAFANA_TOKEN (required), GRAFANA_URL (optional instance origin),
53
+ * and GRAFANA_ORG_ID (optional).
54
+ */
55
+ export const CredentialsFromEnv: Layer.Layer<Credentials> = Layer.succeed(
56
+ Credentials,
57
+ Effect.gen(function* () {
58
+ const token = process.env.GRAFANA_TOKEN;
59
+
60
+ if (!token) {
61
+ return yield* new ConfigError({
62
+ message: "GRAFANA_TOKEN environment variable is required",
63
+ });
64
+ }
65
+
66
+ return {
67
+ token: Redacted.make(token),
68
+ apiBaseUrl: process.env.GRAFANA_URL ?? DEFAULT_API_BASE_URL,
69
+ orgId: process.env.GRAFANA_ORG_ID,
70
+ };
71
+ }).pipe(Effect.orDie),
72
+ );
package/src/errors.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Grafana-specific error types.
3
+ *
4
+ * Re-exports the common HTTP errors from core and adds the Grafana fallback
5
+ * errors. Note the generated service module additionally defines its own
6
+ * per-status matcher classes (BadRequest/NotFound/…) for the statuses each
7
+ * operation declares — those share `_tag`s with the core classes here, so
8
+ * `catchTag` works against either.
9
+ */
10
+ export {
11
+ BadGateway,
12
+ BadRequest,
13
+ Conflict,
14
+ ConfigError,
15
+ Forbidden,
16
+ GatewayTimeout,
17
+ InternalServerError,
18
+ Locked,
19
+ NotFound,
20
+ ServiceUnavailable,
21
+ TooManyRequests,
22
+ Unauthorized,
23
+ UnprocessableEntity,
24
+ HTTP_STATUS_MAP,
25
+ DEFAULT_ERRORS,
26
+ API_ERRORS,
27
+ } from "@distilled.cloud/core/errors";
28
+ export type { DefaultErrors } from "@distilled.cloud/core/errors";
29
+
30
+ import * as Schema from "effect/Schema";
31
+ import * as Category from "@distilled.cloud/core/category";
32
+
33
+ /** Unknown Grafana error — returned when nothing else matches the failure. */
34
+ export class UnknownGrafanaError extends Schema.TaggedError<UnknownGrafanaError>()(
35
+ "UnknownGrafanaError",
36
+ {
37
+ code: Schema.optional(Schema.String),
38
+ message: Schema.optional(Schema.String),
39
+ body: Schema.Unknown,
40
+ },
41
+ ).pipe(Category.withServerError) {}
42
+
43
+ /** Schema parse error wrapper. */
44
+ export class GrafanaParseError extends Schema.TaggedError<GrafanaParseError>()(
45
+ "GrafanaParseError",
46
+ {
47
+ body: Schema.Unknown,
48
+ cause: Schema.Unknown,
49
+ },
50
+ ).pipe(Category.withParseError) {}
package/src/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @distilled.cloud/grafana — Grafana HTTP API SDK for Effect.
3
+ *
4
+ * `./services` is generated by `scripts/generate.ts` from the Smithy model
5
+ * in `.generated-specs` (written by `scripts/convert.ts` from the OpenAPI
6
+ * spec). Everything else in this folder is hand-written.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import * as Grafana from "@distilled.cloud/grafana";
11
+ *
12
+ * const datasources = yield* Grafana.Services.grafana.getDataSources({});
13
+ * ```
14
+ */
15
+ export * from "./credentials.ts";
16
+ export * from "./errors.ts";
17
+ export * as T from "./traits.ts";
18
+ export {
19
+ GrafanaProtocol,
20
+ type GrafanaOpError,
21
+ type GrafanaOpContext,
22
+ } from "./protocol.ts";
23
+ export { paginateCursor } from "./pagination.ts";
24
+ export * as Retry from "./retry.ts";
25
+ export * as Services from "./services/index.ts";
26
+ export * from "./services/grafana.ts";
27
+ export {
28
+ BadRequest,
29
+ Conflict,
30
+ Forbidden,
31
+ NotFound,
32
+ UnprocessableEntity,
33
+ } from "./services/grafana.ts";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Grafana pagination — hand-written.
3
+ *
4
+ * Grafana list endpoints mix `page`/`limit`/`perpage` query parameters and
5
+ * rarely return an in-body next-page token; generated operations that do
6
+ * not stamp `smithy.api#paginated` leave those fields as plain inputs.
7
+ * {@link paginateCursor} is re-exported for callers that want to drive a
8
+ * cursor loop themselves.
9
+ */
10
+ export { paginateCursor } from "@distilled.cloud/core/pagination";
@@ -0,0 +1,82 @@
1
+ /**
2
+ * GrafanaProtocol — hand-written.
3
+ *
4
+ * Grafana speaks bearer-authenticated JSON REST (no response envelope),
5
+ * so the whole protocol is one `makeRestProtocol` call from
6
+ * `core/protocol-rest`:
7
+ *
8
+ * request: credentials → `Authorization: Bearer <token>` + optional
9
+ * `X-Grafana-Org-Id`, resolved from the calling fiber on every
10
+ * request. Paths in the spec are relative to `/api`, so the
11
+ * instance origin is joined with that prefix.
12
+ *
13
+ * response: 2xx JSON is the payload (sensitive members delivered as
14
+ * `Redacted`); non-2xx `{ message?, status? }` bodies map to the
15
+ * operation's typed error classes by status, then the shared
16
+ * HTTP-status classes, then {@link UnknownGrafanaError}.
17
+ */
18
+ import * as Effect from "effect/Effect";
19
+ import type * as Layer from "effect/Layer";
20
+ import * as Redacted from "effect/Redacted";
21
+ import type * as HttpClient from "effect/unstable/http/HttpClient";
22
+ import type * as HttpClientError from "effect/unstable/http/HttpClientError";
23
+ import type * as API from "@distilled.cloud/core/api";
24
+ import { makeRestProtocol } from "@distilled.cloud/core/protocol-rest";
25
+ import type { API_ERRORS, ConfigError } from "@distilled.cloud/core/errors";
26
+ import { Credentials, type Config } from "./credentials.ts";
27
+ import { UnknownGrafanaError } from "./errors.ts";
28
+
29
+ /**
30
+ * Error channel shared by every generated Grafana operation. Generated
31
+ * service files annotate operations with `API.OperationMethod<I, O,
32
+ * GrafanaOpError, GrafanaOpContext>` explicitly so the compiler never infers
33
+ * these back out of the schema generics.
34
+ */
35
+ export type GrafanaOpError =
36
+ | InstanceType<(typeof API_ERRORS)[number]>
37
+ | UnknownGrafanaError
38
+ | ConfigError
39
+ | HttpClientError.HttpClientError;
40
+
41
+ /** Context (requirements) shared by every generated Grafana operation. */
42
+ export type GrafanaOpContext = Credentials | HttpClient.HttpClient;
43
+
44
+ /** Join the instance origin with `/api` unless the caller already included it. */
45
+ const apiBaseUrl = (origin: string): string => {
46
+ const trimmed = origin.replace(/\/+$/, "");
47
+ return trimmed.endsWith("/api") ? trimmed : `${trimmed}/api`;
48
+ };
49
+
50
+ export const GrafanaProtocol: Layer.Layer<API.Protocol> =
51
+ makeRestProtocol<Config>({
52
+ // The Credentials service holds an effect — resolving it here (per
53
+ // request, on the calling fiber) picks up context-provided credentials.
54
+ credentials: Effect.gen(function* () {
55
+ const resolve = yield* Credentials;
56
+ return yield* resolve;
57
+ }),
58
+ baseUrl: (creds) => apiBaseUrl(creds.apiBaseUrl),
59
+ headers: (creds) => {
60
+ const headers: Record<string, string> = {
61
+ Authorization: `Bearer ${Redacted.value(creds.token)}`,
62
+ Accept: "application/json",
63
+ };
64
+ if (creds.orgId !== undefined) {
65
+ headers["X-Grafana-Org-Id"] = String(creds.orgId);
66
+ }
67
+ return headers;
68
+ },
69
+ // Grafana's error body is `{ message?: string, status?: string }` — the
70
+ // factory's default lenient envelope covers it.
71
+ unknownError: ({ code, message, body }) =>
72
+ new UnknownGrafanaError({
73
+ code:
74
+ typeof code === "string"
75
+ ? code
76
+ : code !== undefined
77
+ ? String(code)
78
+ : undefined,
79
+ message,
80
+ body,
81
+ }),
82
+ });
package/src/retry.ts ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Grafana retry configuration.
3
+ *
4
+ * Defines the per-SDK `Retry` Context.Service tag that generated operations
5
+ * wire into `API.make`. Callers can install a blanket retry policy at the
6
+ * layer level and have every Grafana API call below it pick it up:
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import * as Grafana from "@distilled.cloud/grafana";
11
+ *
12
+ * myEffect.pipe(Grafana.Retry.transient);
13
+ * Effect.provide(myEffect, Layer.succeed(Grafana.Retry.Retry, customPolicy));
14
+ * ```
15
+ */
16
+ import * as Context from "effect/Context";
17
+ import * as Effect from "effect/Effect";
18
+ import * as Layer from "effect/Layer";
19
+ import {
20
+ type Policy,
21
+ throttlingFactory,
22
+ transientFactory,
23
+ } from "@distilled.cloud/core/retry";
24
+
25
+ export {
26
+ type Options,
27
+ type Factory,
28
+ type Policy,
29
+ makeDefault,
30
+ jittered,
31
+ capped,
32
+ throttlingOptions,
33
+ transientOptions,
34
+ throttlingFactory,
35
+ transientFactory,
36
+ } from "@distilled.cloud/core/retry";
37
+
38
+ /** Context tag for configuring retry behavior of Grafana API calls. */
39
+ export class Retry extends Context.Service<Retry, Policy>()("GrafanaRetry") {}
40
+
41
+ /** Provides a custom retry policy to every Grafana API call below it. */
42
+ export const policy = (optionsOrFactory: Policy) =>
43
+ Effect.provide(Layer.succeed(Retry, optionsOrFactory));
44
+
45
+ /** Disables all automatic retries. */
46
+ export const none = Effect.provide(
47
+ Layer.succeed(Retry, { while: () => false }),
48
+ );
49
+
50
+ /** Apply the throttling retry policy (retries throttling errors indefinitely). */
51
+ export const throttling = policy(throttlingFactory);
52
+
53
+ /** Apply the transient retry policy (retries all transient errors indefinitely). */
54
+ export const transient = policy(transientFactory);