@r8s/recipes 0.1.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 (65) hide show
  1. package/dist/app.d.ts +94 -0
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/app.js +120 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/auth/components.d.ts +163 -0
  6. package/dist/auth/components.d.ts.map +1 -0
  7. package/dist/auth/components.js +134 -0
  8. package/dist/auth/components.js.map +1 -0
  9. package/dist/auth/index.d.ts +2 -0
  10. package/dist/auth/index.d.ts.map +1 -0
  11. package/dist/auth/index.js +14 -0
  12. package/dist/auth/index.js.map +1 -0
  13. package/dist/auth.d.ts +92 -0
  14. package/dist/auth.d.ts.map +1 -0
  15. package/dist/auth.js +302 -0
  16. package/dist/auth.js.map +1 -0
  17. package/dist/backup.d.ts +45 -0
  18. package/dist/backup.d.ts.map +1 -0
  19. package/dist/backup.js +59 -0
  20. package/dist/backup.js.map +1 -0
  21. package/dist/cert-provider.d.ts +78 -0
  22. package/dist/cert-provider.d.ts.map +1 -0
  23. package/dist/cert-provider.js +71 -0
  24. package/dist/cert-provider.js.map +1 -0
  25. package/dist/database.d.ts +49 -0
  26. package/dist/database.d.ts.map +1 -0
  27. package/dist/database.js +212 -0
  28. package/dist/database.js.map +1 -0
  29. package/dist/dns-provider.d.ts +110 -0
  30. package/dist/dns-provider.d.ts.map +1 -0
  31. package/dist/dns-provider.js +121 -0
  32. package/dist/dns-provider.js.map +1 -0
  33. package/dist/endpoint-provider.d.ts +121 -0
  34. package/dist/endpoint-provider.d.ts.map +1 -0
  35. package/dist/endpoint-provider.js +79 -0
  36. package/dist/endpoint-provider.js.map +1 -0
  37. package/dist/endpoint.d.ts +43 -0
  38. package/dist/endpoint.d.ts.map +1 -0
  39. package/dist/endpoint.js +221 -0
  40. package/dist/endpoint.js.map +1 -0
  41. package/dist/index.d.ts +14 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +49 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/monitoring.d.ts +49 -0
  46. package/dist/monitoring.d.ts.map +1 -0
  47. package/dist/monitoring.js +128 -0
  48. package/dist/monitoring.js.map +1 -0
  49. package/dist/operators.d.ts +19 -0
  50. package/dist/operators.d.ts.map +1 -0
  51. package/dist/operators.js +30 -0
  52. package/dist/operators.js.map +1 -0
  53. package/dist/platform.d.ts +116 -0
  54. package/dist/platform.d.ts.map +1 -0
  55. package/dist/platform.js +121 -0
  56. package/dist/platform.js.map +1 -0
  57. package/dist/secret-provider.d.ts +119 -0
  58. package/dist/secret-provider.d.ts.map +1 -0
  59. package/dist/secret-provider.js +125 -0
  60. package/dist/secret-provider.js.map +1 -0
  61. package/dist/web-service.d.ts +87 -0
  62. package/dist/web-service.d.ts.map +1 -0
  63. package/dist/web-service.js +171 -0
  64. package/dist/web-service.js.map +1 -0
  65. package/package.json +48 -0
@@ -0,0 +1,116 @@
1
+ import type { Operator } from '@r8s/k8s-types';
2
+ import { type SecretProviderValue } from './secret-provider';
3
+ import { type DnsProviderValue } from './dns-provider';
4
+ export type RoutingMode = 'ingress' | 'gateway';
5
+ export interface PlatformProps {
6
+ /**
7
+ * Routing implementation for the cluster.
8
+ * - 'ingress': nginx Ingress (default)
9
+ * - 'gateway': Envoy Gateway (Gateway API)
10
+ */
11
+ routing?: RoutingMode;
12
+ /** Gateway class name (only used when routing='gateway', default: 'eg') */
13
+ gatewayClassName?: string;
14
+ /** Default namespace for all child resources */
15
+ namespace?: string;
16
+ /** Default labels applied to all child resources */
17
+ labels?: Record<string, string>;
18
+ /** Shared operators for all child resources */
19
+ operators?: Operator[];
20
+ /**
21
+ * Secrets backend for all child resources. When set, Database and other
22
+ * recipes generate credentials through this backend instead of requiring
23
+ * plaintext passwords.
24
+ *
25
+ * - 'openbao': OpenBao Vault Secrets Operator (default when omitted)
26
+ * - 'vault': HashiCorp Vault Secrets Operator
27
+ * - 'sealed-secrets': Bitnami Sealed Secrets
28
+ * - 'kubernetes': plain Kubernetes Secrets (CNPG-managed, no plaintext)
29
+ *
30
+ * Use a string for simple cases, or a component for advanced config:
31
+ * `secrets={<OpenBao mount="secret" path="infra" />}`
32
+ */
33
+ secrets?: SecretProviderValue;
34
+ /**
35
+ * DNS configuration for all child endpoints. When set, Endpoint/App
36
+ * automatically create DNS records via ExternalDNS.
37
+ *
38
+ * Use a string for simple cases, or a component for advanced config:
39
+ * `dns={<ExternalDns server="ns1.example.com" tsig={{...}} />}`
40
+ */
41
+ dns?: DnsProviderValue;
42
+ /** Child components that inherit the cluster-level configuration this Platform sets */
43
+ children?: unknown;
44
+ }
45
+ /**
46
+ * Platform — cluster-level configuration wrapper.
47
+ *
48
+ * @title Platform
49
+ * @category Cluster Configuration
50
+ *
51
+ * Sets routing mode, namespace, labels, and shared operators for all
52
+ * child components. Use this once at the top of your manifest instead
53
+ * of manually wiring context providers.
54
+ *
55
+ * For finer control, use the individual providers directly:
56
+ * - `<SecretProvider>` for secrets backend
57
+ * - `<DnsProvider>` for DNS configuration
58
+ * - `<EndpointProvider>` for routing
59
+ *
60
+ * @example
61
+ * import { Platform, App } from '@r8s/recipes'
62
+ *
63
+ * export default (
64
+ * <Platform routing="gateway" namespace="production">
65
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
66
+ * <App name="web" image="myapp/web:v1" host="app.example.com" />
67
+ * </Platform>
68
+ * )
69
+ *
70
+ * @example
71
+ * import { Platform, App } from '@r8s/recipes'
72
+ *
73
+ * export default (
74
+ * <Platform namespace="production">
75
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
76
+ * </Platform>
77
+ * )
78
+ *
79
+ * @example
80
+ * import { Platform, App, Database, cnpgOperator } from '@r8s/recipes'
81
+ * import { operators } from '@r8s/crds'
82
+ *
83
+ * export default (
84
+ * <Platform
85
+ * routing="gateway"
86
+ * namespace="production"
87
+ * operators={[cnpgOperator(), operators['cert-manager']()]}
88
+ * >
89
+ * <Database name="app-db" storage="10Gi" />
90
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
91
+ * </Platform>
92
+ * )
93
+ *
94
+ * @example
95
+ * // Full hierarchy with DNS and secrets
96
+ * import { Platform, App } from '@r8s/recipes'
97
+ *
98
+ * export default (
99
+ * <Platform
100
+ * namespace="production"
101
+ * secrets={{ backend: 'openbao', mount: 'secret', path: 'infra' }}
102
+ * dns={{
103
+ * provider: 'external-dns',
104
+ * settings: {
105
+ * server: 'ns1.example.com',
106
+ * zone: 'example.com',
107
+ * tsig: { path: 'dns/tsig', key: 'secret' },
108
+ * },
109
+ * }}
110
+ * >
111
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
112
+ * </Platform>
113
+ * )
114
+ */
115
+ export declare function Platform(props: PlatformProps): unknown;
116
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAOnE,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,CAAA;AAE/C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;IACtB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,gBAAgB,CAAA;IACtB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,WA4D5C"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Platform = Platform;
4
+ const core_1 = require("@r8s/core");
5
+ const defaults_1 = require("@r8s/core/defaults");
6
+ const secret_provider_1 = require("./secret-provider");
7
+ const dns_provider_1 = require("./dns-provider");
8
+ const endpoint_provider_1 = require("./endpoint-provider");
9
+ /**
10
+ * Platform — cluster-level configuration wrapper.
11
+ *
12
+ * @title Platform
13
+ * @category Cluster Configuration
14
+ *
15
+ * Sets routing mode, namespace, labels, and shared operators for all
16
+ * child components. Use this once at the top of your manifest instead
17
+ * of manually wiring context providers.
18
+ *
19
+ * For finer control, use the individual providers directly:
20
+ * - `<SecretProvider>` for secrets backend
21
+ * - `<DnsProvider>` for DNS configuration
22
+ * - `<EndpointProvider>` for routing
23
+ *
24
+ * @example
25
+ * import { Platform, App } from '@r8s/recipes'
26
+ *
27
+ * export default (
28
+ * <Platform routing="gateway" namespace="production">
29
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
30
+ * <App name="web" image="myapp/web:v1" host="app.example.com" />
31
+ * </Platform>
32
+ * )
33
+ *
34
+ * @example
35
+ * import { Platform, App } from '@r8s/recipes'
36
+ *
37
+ * export default (
38
+ * <Platform namespace="production">
39
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
40
+ * </Platform>
41
+ * )
42
+ *
43
+ * @example
44
+ * import { Platform, App, Database, cnpgOperator } from '@r8s/recipes'
45
+ * import { operators } from '@r8s/crds'
46
+ *
47
+ * export default (
48
+ * <Platform
49
+ * routing="gateway"
50
+ * namespace="production"
51
+ * operators={[cnpgOperator(), operators['cert-manager']()]}
52
+ * >
53
+ * <Database name="app-db" storage="10Gi" />
54
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
55
+ * </Platform>
56
+ * )
57
+ *
58
+ * @example
59
+ * // Full hierarchy with DNS and secrets
60
+ * import { Platform, App } from '@r8s/recipes'
61
+ *
62
+ * export default (
63
+ * <Platform
64
+ * namespace="production"
65
+ * secrets={{ backend: 'openbao', mount: 'secret', path: 'infra' }}
66
+ * dns={{
67
+ * provider: 'external-dns',
68
+ * settings: {
69
+ * server: 'ns1.example.com',
70
+ * zone: 'example.com',
71
+ * tsig: { path: 'dns/tsig', key: 'secret' },
72
+ * },
73
+ * }}
74
+ * >
75
+ * <App name="api" image="myapp/api:v1" host="api.example.com" />
76
+ * </Platform>
77
+ * )
78
+ */
79
+ function Platform(props) {
80
+ const { routing = 'ingress', gatewayClassName = 'eg', namespace, labels, operators, secrets, dns, children, } = props;
81
+ let result = children;
82
+ // Materialize the Namespace resource so rendered output is self-contained.
83
+ // Without this, every resource references a namespace that may not exist.
84
+ if (namespace) {
85
+ result = (0, core_1.jsx)(core_1.Fragment, {
86
+ children: [
87
+ (0, core_1.jsx)('Namespace', {
88
+ apiVersion: 'v1',
89
+ kind: 'Namespace',
90
+ metadata: { name: namespace },
91
+ }),
92
+ result,
93
+ ],
94
+ });
95
+ }
96
+ // Apply DNS context via DnsProvider (inside SecretProvider so it can access secrets)
97
+ if (dns) {
98
+ result = (0, core_1.jsx)(dns_provider_1.DnsProvider, { provider: dns, children: result });
99
+ }
100
+ // Apply secrets context via SecretProvider (outside DnsProvider)
101
+ if (secrets) {
102
+ result = (0, core_1.jsx)(secret_provider_1.SecretProvider, { provider: secrets, children: result });
103
+ }
104
+ // Apply routing context via EndpointProvider
105
+ const endpointProvider = routing === 'gateway' ? { provider: 'envoy-gateway', settings: { gatewayClassName } } : 'nginx';
106
+ result = (0, core_1.jsx)(endpoint_provider_1.EndpointProvider, { provider: endpointProvider, children: result });
107
+ // Apply operators context
108
+ if (operators && operators.length > 0) {
109
+ result = (0, core_1.jsx)(defaults_1.OperatorContext.Provider, { value: operators, children: result });
110
+ }
111
+ // Apply labels context
112
+ if (labels) {
113
+ result = (0, core_1.jsx)(defaults_1.Labels.Provider, { value: labels, children: result });
114
+ }
115
+ // Apply namespace context
116
+ if (namespace) {
117
+ result = (0, core_1.jsx)(defaults_1.Namespace.Provider, { value: namespace, children: result });
118
+ }
119
+ return result;
120
+ }
121
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.tsx"],"names":[],"mappings":";;AAmIA,4BA4DC;AA/LD,oCAAqD;AACrD,iDAO2B;AAE3B,uDAA4E;AAC5E,iDAAmE;AACnE,2DAI4B;AA6C5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,SAAgB,QAAQ,CAAC,KAAoB;IAC3C,MAAM,EACJ,OAAO,GAAG,SAAS,EACnB,gBAAgB,GAAG,IAAI,EACvB,SAAS,EACT,MAAM,EACN,SAAS,EACT,OAAO,EACP,GAAG,EACH,QAAQ,GACT,GAAG,KAAK,CAAA;IAET,IAAI,MAAM,GAAY,QAAQ,CAAA;IAE9B,2EAA2E;IAC3E,0EAA0E;IAC1E,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,IAAA,UAAG,EAAC,eAAQ,EAAE;YACrB,QAAQ,EAAE;gBACR,IAAA,UAAG,EAAC,WAAW,EAAE;oBACf,UAAU,EAAE,IAAI;oBAChB,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;iBAC9B,CAAC;gBACF,MAAM;aACP;SACF,CAAC,CAAA;IACJ,CAAC;IAED,qFAAqF;IACrF,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,GAAG,IAAA,UAAG,EAAC,0BAAW,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,iEAAiE;IACjE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,GAAG,IAAA,UAAG,EAAC,gCAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC;IAED,6CAA6C;IAC7C,MAAM,gBAAgB,GACpB,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;IACjG,MAAM,GAAG,IAAA,UAAG,EAAC,oCAAgB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IAEhF,0BAA0B;IAC1B,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,GAAG,IAAA,UAAG,EAAC,0BAAe,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IAChF,CAAC;IAED,uBAAuB;IACvB,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,IAAA,UAAG,EAAC,iBAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IACpE,CAAC;IAED,0BAA0B;IAC1B,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,IAAA,UAAG,EAAC,oBAAS,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;IAC1E,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { type SecretProvider as SecretProviderConfig } from '@r8s/core/defaults';
2
+ /**
3
+ * OpenBao configuration component.
4
+ *
5
+ * Use as a value in SecretProvider when you need custom configuration:
6
+ * ```tsx
7
+ * <SecretProvider provider={<OpenBao mount="secret" path="infra" authRef="custom" />}>
8
+ * ```
9
+ */
10
+ export interface OpenBaoProps {
11
+ /** OpenBao mount path (default: 'secret') */
12
+ mount?: string;
13
+ /** Base path for all secrets (e.g., 'infra' → 'infra/app/db') */
14
+ path?: string;
15
+ /** Auth reference (OpenBaoAuth name) */
16
+ authRef?: string;
17
+ }
18
+ export declare function OpenBao(props: OpenBaoProps): SecretProviderConfig;
19
+ /**
20
+ * Vault configuration component.
21
+ */
22
+ export interface VaultProps {
23
+ /** Vault mount path (default: 'secret') */
24
+ mount?: string;
25
+ /** Base path for all secrets */
26
+ path?: string;
27
+ /** Auth reference (VaultAuth name) */
28
+ authRef?: string;
29
+ }
30
+ export declare function Vault(props: VaultProps): SecretProviderConfig;
31
+ /**
32
+ * SealedSecrets configuration component.
33
+ */
34
+ export interface SealedSecretsProps {
35
+ /** Namespace where sealed-secrets controller runs (default: 'kube-system') */
36
+ namespace?: string;
37
+ }
38
+ export declare function SealedSecrets(props: SealedSecretsProps): SecretProviderConfig;
39
+ /**
40
+ * ManualSecrets configuration component (plain Kubernetes Secrets, CNPG-managed).
41
+ *
42
+ * Use for simple deployments or development. CNPG creates and manages
43
+ * bootstrap secrets automatically. No external secrets backend required.
44
+ */
45
+ export interface ManualSecretsProps {
46
+ }
47
+ export declare function ManualSecrets(props: ManualSecretsProps): SecretProviderConfig;
48
+ /** Union of all secret provider configurations */
49
+ export type SecretProviderValue = 'openbao' | 'vault' | 'sealed-secrets' | 'manual-secrets' | SecretProviderConfig;
50
+ export interface SecretProviderProps {
51
+ /**
52
+ * Secrets backend — string for simple cases, component for advanced config.
53
+ *
54
+ * @example
55
+ * import { SecretProvider, Database } from '@r8s/recipes'
56
+ *
57
+ * export default (
58
+ * <SecretProvider provider="openbao">
59
+ * <Database name="app-db" />
60
+ * </SecretProvider>
61
+ * )
62
+ *
63
+ * @example
64
+ * import { SecretProvider, OpenBao, Database } from '@r8s/recipes'
65
+ *
66
+ * export default (
67
+ * <SecretProvider provider={<OpenBao mount="secret" path="infra" authRef="custom" />}>
68
+ * <Database name="app-db" />
69
+ * </SecretProvider>
70
+ * )
71
+ */
72
+ provider: SecretProviderValue;
73
+ /** Child components */
74
+ children?: unknown;
75
+ }
76
+ /**
77
+ * SecretProvider — cluster-level secrets backend.
78
+ *
79
+ * All Database, Auth, and other secret-consuming children use this backend.
80
+ * Automatically declares the required operator (VSO for vault/openbao).
81
+ *
82
+ * @example
83
+ * import { SecretProvider, Database } from '@r8s/recipes'
84
+ *
85
+ * export default (
86
+ * <SecretProvider provider="openbao">
87
+ * <Database name="app-db" />
88
+ * </SecretProvider>
89
+ * )
90
+ *
91
+ * @example
92
+ * import { SecretProvider, OpenBao, Database } from '@r8s/recipes'
93
+ *
94
+ * export default (
95
+ * <SecretProvider provider={<OpenBao mount="secret" path="infra" authRef="custom-auth" />}>
96
+ * <Database name="app-db" />
97
+ * </SecretProvider>
98
+ * )
99
+ *
100
+ * @example
101
+ * import { SecretProvider, Vault, Database } from '@r8s/recipes'
102
+ *
103
+ * export default (
104
+ * <SecretProvider provider={<Vault mount="kv" path="apps" />}>
105
+ * <Database name="app-db" />
106
+ * </SecretProvider>
107
+ * )
108
+ *
109
+ * @example
110
+ * import { SecretProvider, Database } from '@r8s/recipes'
111
+ *
112
+ * export default (
113
+ * <SecretProvider provider="sealed-secrets">
114
+ * <Database name="app-db" password="supersecret" />
115
+ * </SecretProvider>
116
+ * )
117
+ */
118
+ export declare function SecretProvider(props: SecretProviderProps): import("@r8s/core").r8sElement;
119
+ //# sourceMappingURL=secret-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-provider.d.ts","sourceRoot":"","sources":["../src/secret-provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,cAAc,IAAI,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAI/F;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,oBAAoB,CAOjE;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAO7D;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,oBAAoB,CAI7E;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;CAAG;AAEtC,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,oBAAoB,CAI7E;AAED,kDAAkD;AAClD,MAAM,MAAM,mBAAmB,GAC7B,SAAS,GAAG,OAAO,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,oBAAoB,CAAA;AAElF,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,kCA0CxD"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenBao = OpenBao;
4
+ exports.Vault = Vault;
5
+ exports.SealedSecrets = SealedSecrets;
6
+ exports.ManualSecrets = ManualSecrets;
7
+ exports.SecretProvider = SecretProvider;
8
+ const core_1 = require("@r8s/core");
9
+ const defaults_1 = require("@r8s/core/defaults");
10
+ const defaults_2 = require("@r8s/core/defaults");
11
+ const crds_1 = require("@r8s/crds");
12
+ function OpenBao(props) {
13
+ return {
14
+ backend: 'openbao',
15
+ mount: props.mount,
16
+ path: props.path,
17
+ authRef: props.authRef,
18
+ };
19
+ }
20
+ function Vault(props) {
21
+ return {
22
+ backend: 'vault',
23
+ mount: props.mount,
24
+ path: props.path,
25
+ authRef: props.authRef,
26
+ };
27
+ }
28
+ function SealedSecrets(props) {
29
+ return {
30
+ backend: 'sealed-secrets',
31
+ };
32
+ }
33
+ function ManualSecrets(props) {
34
+ return {
35
+ backend: 'manual-secrets',
36
+ };
37
+ }
38
+ /**
39
+ * SecretProvider — cluster-level secrets backend.
40
+ *
41
+ * All Database, Auth, and other secret-consuming children use this backend.
42
+ * Automatically declares the required operator (VSO for vault/openbao).
43
+ *
44
+ * @example
45
+ * import { SecretProvider, Database } from '@r8s/recipes'
46
+ *
47
+ * export default (
48
+ * <SecretProvider provider="openbao">
49
+ * <Database name="app-db" />
50
+ * </SecretProvider>
51
+ * )
52
+ *
53
+ * @example
54
+ * import { SecretProvider, OpenBao, Database } from '@r8s/recipes'
55
+ *
56
+ * export default (
57
+ * <SecretProvider provider={<OpenBao mount="secret" path="infra" authRef="custom-auth" />}>
58
+ * <Database name="app-db" />
59
+ * </SecretProvider>
60
+ * )
61
+ *
62
+ * @example
63
+ * import { SecretProvider, Vault, Database } from '@r8s/recipes'
64
+ *
65
+ * export default (
66
+ * <SecretProvider provider={<Vault mount="kv" path="apps" />}>
67
+ * <Database name="app-db" />
68
+ * </SecretProvider>
69
+ * )
70
+ *
71
+ * @example
72
+ * import { SecretProvider, Database } from '@r8s/recipes'
73
+ *
74
+ * export default (
75
+ * <SecretProvider provider="sealed-secrets">
76
+ * <Database name="app-db" password="supersecret" />
77
+ * </SecretProvider>
78
+ * )
79
+ */
80
+ function SecretProvider(props) {
81
+ const { provider, children } = props;
82
+ const sharedOperators = (0, core_1.useContext)(defaults_2.OperatorContext);
83
+ // Resolve provider config
84
+ let config;
85
+ if (typeof provider === 'string') {
86
+ config = { backend: provider };
87
+ }
88
+ else if ('backend' in provider) {
89
+ config = provider;
90
+ }
91
+ else if (provider && typeof provider === 'object' && 'type' in provider) {
92
+ // r8s JSX element — call the component with its props
93
+ const component = provider.type;
94
+ if (component === OpenBao) {
95
+ config = OpenBao(provider.props);
96
+ }
97
+ else if (component === Vault) {
98
+ config = Vault(provider.props);
99
+ }
100
+ else if (component === SealedSecrets) {
101
+ config = SealedSecrets(provider.props);
102
+ }
103
+ else if (component === ManualSecrets) {
104
+ config = ManualSecrets(provider.props);
105
+ }
106
+ else {
107
+ throw new Error(`Unknown secret provider component: ${component.name || component}`);
108
+ }
109
+ }
110
+ else {
111
+ throw new Error(`Invalid secret provider: ${JSON.stringify(provider)}`);
112
+ }
113
+ const resources = [];
114
+ // Declare VSO for vault/openbao
115
+ if (config.backend === 'vault' || config.backend === 'openbao') {
116
+ const hasVSO = sharedOperators.some((op) => op.name === 'vault-secrets-operator');
117
+ if (!hasVSO) {
118
+ resources.push((0, core_1.declareOperator)(crds_1.operators['vault-secrets-operator']()));
119
+ }
120
+ }
121
+ return (0, core_1.jsx)(core_1.Fragment, {
122
+ children: [...resources, (0, core_1.jsx)(defaults_1.SecretContext.Provider, { value: config, children })],
123
+ });
124
+ }
125
+ //# sourceMappingURL=secret-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-provider.js","sourceRoot":"","sources":["../src/secret-provider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { EnvVar } from '@r8s/k8s-types';
2
+ export interface SecretRef {
3
+ /** Name of the Kubernetes Secret containing this value */
4
+ secret: string;
5
+ /** Key within the secret (defaults to env var name) */
6
+ key?: string;
7
+ }
8
+ export interface VaultSecretRef {
9
+ /** Vault KV mount path */
10
+ mount: string;
11
+ /** Secret path in Vault */
12
+ path: string;
13
+ /** Key within the Vault secret (defaults to env var name) */
14
+ key?: string;
15
+ /** VaultAuth reference name (defaults to 'default') */
16
+ vaultAuthRef?: string;
17
+ }
18
+ export interface WebServiceProps {
19
+ /** Resource name */
20
+ name: string;
21
+ /** Kubernetes namespace (defaults to 'default') */
22
+ namespace?: string;
23
+ /** Container image (e.g., 'myapp/api:v1.2.3') */
24
+ image: string;
25
+ /** Container port the app listens on (defaults to 3000) */
26
+ port?: number;
27
+ /** Number of pod replicas (defaults to 2) */
28
+ replicas?: number;
29
+ /** Plain environment variables (non-sensitive) */
30
+ env?: Record<string, string>;
31
+ /** Secrets from Kubernetes Secrets — safe by default */
32
+ secrets?: Record<string, SecretRef | string>;
33
+ /** Secrets from Vault — creates VaultStaticSecret objects */
34
+ vault?: Record<string, VaultSecretRef>;
35
+ /** Raw env vars for advanced use cases */
36
+ rawEnv?: EnvVar[];
37
+ /** CPU and memory requests/limits for the app container */
38
+ resources?: {
39
+ requests?: {
40
+ cpu?: string;
41
+ memory?: string;
42
+ };
43
+ limits?: {
44
+ cpu?: string;
45
+ memory?: string;
46
+ };
47
+ };
48
+ }
49
+ /**
50
+ * Simple web service (backend or frontend).
51
+ *
52
+ * @title Web Service
53
+ * @category Workloads
54
+ *
55
+ * Creates a Deployment + Service with health checks.
56
+ *
57
+ * @example
58
+ * import { WebService } from '@r8s/recipes'
59
+ *
60
+ * export default <WebService name="api" image="myapp/api:v1" port={3000} env={{ LOG_LEVEL: 'info' }} />
61
+ *
62
+ * @example
63
+ * import { WebService } from '@r8s/recipes'
64
+ *
65
+ * export default (
66
+ * <WebService
67
+ * name="api"
68
+ * image="myapp/api:v1"
69
+ * env={{ LOG_LEVEL: 'info' }}
70
+ * secrets={{ DATABASE_URL: 'app-secrets', API_KEY: 'app-secrets' }}
71
+ * />
72
+ * )
73
+ *
74
+ * @example
75
+ * import { WebService } from '@r8s/recipes'
76
+ *
77
+ * export default (
78
+ * <WebService
79
+ * name="api"
80
+ * image="myapp/api:v1"
81
+ * env={{ LOG_LEVEL: 'info' }}
82
+ * vault={{ DATABASE_URL: { mount: 'kv', path: 'db/credentials' } }}
83
+ * />
84
+ * )
85
+ */
86
+ export declare function WebService(props: WebServiceProps): import("@r8s/core").r8sElement[];
87
+ //# sourceMappingURL=web-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-service.d.ts","sourceRoot":"","sources":["../src/web-service.tsx"],"names":[],"mappings":"AACA,OAAO,EAAuB,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAI5D,MAAM,WAAW,SAAS;IACxB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC,CAAA;IAC5C,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACtC,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QAC5C,MAAM,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAC3C,CAAA;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,oCA8JhD"}