@di-framework/cloudfoundry 5.2.3

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.
@@ -0,0 +1,179 @@
1
+ const POSTGRES_PATTERNS = ['postgres', 'postgresql', 'elephantsql', 'crunchy'];
2
+ const MYSQL_PATTERNS = ['mysql', 'cleardb', 'mariadb'];
3
+ const SQLITE_PATTERNS = ['sqlite', 'sqlite3'];
4
+ function matchesAny(str, patterns) {
5
+ const lower = str.toLowerCase();
6
+ return patterns.some((p) => lower.includes(p));
7
+ }
8
+ function detectDialectFromScheme(scheme) {
9
+ const s = scheme.toLowerCase().replace(':', '');
10
+ if (s === 'postgres' || s === 'postgresql')
11
+ return 'postgres';
12
+ if (s === 'mysql')
13
+ return 'mysql';
14
+ if (s === 'mariadb')
15
+ return 'mariadb';
16
+ if (s === 'sqlite' || s === 'sqlite3')
17
+ return 'sqlite';
18
+ return null;
19
+ }
20
+ export class RelationalServiceInfoCreator {
21
+ accept(serviceData) {
22
+ const label = serviceData.label || '';
23
+ const tags = (serviceData.tags || []).map((t) => String(t).toLowerCase());
24
+ const creds = (serviceData.credentials || {});
25
+ // 1. Label match
26
+ if (matchesAny(label, POSTGRES_PATTERNS) ||
27
+ matchesAny(label, MYSQL_PATTERNS) ||
28
+ matchesAny(label, SQLITE_PATTERNS)) {
29
+ return true;
30
+ }
31
+ // 2. Tag match
32
+ if (tags.some((t) => POSTGRES_PATTERNS.some((p) => t.includes(p)) ||
33
+ MYSQL_PATTERNS.some((p) => t.includes(p)) ||
34
+ SQLITE_PATTERNS.some((p) => t.includes(p)) ||
35
+ t === 'relational' ||
36
+ t === 'rdbms')) {
37
+ return true;
38
+ }
39
+ // 3. Credentials URI / JDBC / scheme inspection
40
+ const uriCandidate = String(creds.uri ?? creds.url ?? creds.jdbcUrl ?? '');
41
+ if (uriCandidate.startsWith('postgres://') || uriCandidate.startsWith('postgresql://')) {
42
+ return true;
43
+ }
44
+ if (uriCandidate.startsWith('mysql://') || uriCandidate.startsWith('mariadb://')) {
45
+ return true;
46
+ }
47
+ if (uriCandidate.startsWith('sqlite://') || uriCandidate.startsWith('sqlite:')) {
48
+ return true;
49
+ }
50
+ if (uriCandidate.startsWith('jdbc:postgresql:') || uriCandidate.startsWith('jdbc:mysql:')) {
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+ createServiceInfo(serviceData) {
56
+ const creds = (serviceData.credentials || {});
57
+ const tags = (serviceData.tags || []).map(String);
58
+ const label = serviceData.label || '';
59
+ let rawUri = String(creds.uri ?? creds.url ?? '');
60
+ const jdbcUrlCandidate = creds.jdbcUrl ? String(creds.jdbcUrl) : undefined;
61
+ let dialect = 'postgres';
62
+ if (matchesAny(label, SQLITE_PATTERNS) || tags.some((t) => matchesAny(t, SQLITE_PATTERNS))) {
63
+ dialect = 'sqlite';
64
+ }
65
+ else if (matchesAny(label, MYSQL_PATTERNS) ||
66
+ tags.some((t) => matchesAny(t, MYSQL_PATTERNS))) {
67
+ dialect = matchesAny(label, ['mariadb']) || tags.includes('mariadb') ? 'mariadb' : 'mysql';
68
+ }
69
+ let host = String(creds.host ?? creds.hostname ?? 'localhost');
70
+ let port = typeof creds.port === 'number' ? creds.port : 5432;
71
+ if (typeof creds.port === 'string' && creds.port.trim().length > 0) {
72
+ const p = parseInt(creds.port, 10);
73
+ if (!Number.isNaN(p))
74
+ port = p;
75
+ }
76
+ let database = String(creationalDbName(creds));
77
+ let username = (creds.username ?? creds.user) ? String(creds.username ?? creds.user) : undefined;
78
+ let password = (creds.password ?? creds.pass) ? String(creds.password ?? creds.pass) : undefined;
79
+ let ssl = typeof creds.ssl === 'boolean' ? creds.ssl : undefined;
80
+ if (rawUri.startsWith('jdbc:')) {
81
+ // e.g. jdbc:postgresql://host:port/database
82
+ const normalized = rawUri.replace(/^jdbc:/, '');
83
+ try {
84
+ const parsed = new URL(normalized);
85
+ const schemeDialect = detectDialectFromScheme(parsed.protocol);
86
+ if (schemeDialect)
87
+ dialect = schemeDialect;
88
+ if (parsed.hostname)
89
+ host = parsed.hostname;
90
+ if (parsed.port)
91
+ port = parseInt(parsed.port, 10);
92
+ if (parsed.pathname && parsed.pathname.length > 1) {
93
+ database = decodeURIComponent(parsed.pathname.slice(1));
94
+ }
95
+ if (parsed.username)
96
+ username = decodeURIComponent(parsed.username);
97
+ if (parsed.password)
98
+ password = decodeURIComponent(parsed.password);
99
+ if (parsed.searchParams.has('ssl') || parsed.searchParams.has('sslmode')) {
100
+ ssl =
101
+ parsed.searchParams.get('ssl') === 'true' ||
102
+ parsed.searchParams.get('sslmode') === 'require';
103
+ }
104
+ }
105
+ catch {
106
+ // preserve original
107
+ }
108
+ }
109
+ else if (rawUri.length > 0) {
110
+ try {
111
+ const parsed = new URL(rawUri);
112
+ const schemeDialect = detectDialectFromScheme(parsed.protocol);
113
+ if (schemeDialect)
114
+ dialect = schemeDialect;
115
+ if (parsed.hostname)
116
+ host = parsed.hostname;
117
+ if (parsed.port)
118
+ port = parseInt(parsed.port, 10);
119
+ if (parsed.pathname && parsed.pathname.length > 1) {
120
+ database = decodeURIComponent(parsed.pathname.slice(1));
121
+ }
122
+ if (parsed.username)
123
+ username = decodeURIComponent(parsed.username);
124
+ if (parsed.password)
125
+ password = decodeURIComponent(parsed.password);
126
+ if (parsed.searchParams.has('ssl') || parsed.searchParams.has('sslmode')) {
127
+ ssl =
128
+ parsed.searchParams.get('ssl') === 'true' ||
129
+ parsed.searchParams.get('sslmode') === 'require';
130
+ }
131
+ }
132
+ catch {
133
+ // ignore url parse error
134
+ }
135
+ }
136
+ if (!rawUri || rawUri.startsWith('jdbc:')) {
137
+ const scheme = dialect === 'postgres' ? 'postgres' : dialect;
138
+ const auth = username ? (password ? `${username}:${password}@` : `${username}@`) : '';
139
+ rawUri = `${scheme}://${auth}${host}:${port}/${database}`;
140
+ }
141
+ const defaultPorts = {
142
+ postgres: 5432,
143
+ mysql: 3306,
144
+ mariadb: 3306,
145
+ sqlite: 0,
146
+ };
147
+ if (!port || (port === 5432 && dialect === 'mysql')) {
148
+ port = defaultPorts[dialect];
149
+ }
150
+ const jdbcUrl = jdbcUrlCandidate ??
151
+ `jdbc:${dialect === 'postgres' ? 'postgresql' : dialect}://${host}:${port}/${database}`;
152
+ return {
153
+ id: serviceData.name,
154
+ name: serviceData.name,
155
+ label: serviceData.label,
156
+ ...(serviceData.plan ? { plan: serviceData.plan } : {}),
157
+ tags,
158
+ credentials: Object.freeze({ ...creds }),
159
+ dialect,
160
+ host,
161
+ port,
162
+ database,
163
+ ...(username !== undefined ? { username } : {}),
164
+ ...(password !== undefined ? { password } : {}),
165
+ uri: rawUri,
166
+ jdbcUrl,
167
+ ...(ssl !== undefined ? { ssl } : {}),
168
+ };
169
+ }
170
+ }
171
+ function creationalDbName(creds) {
172
+ if (creds.database)
173
+ return String(creds.database);
174
+ if (creds.name)
175
+ return String(creds.name);
176
+ if (creds.db)
177
+ return String(creds.db);
178
+ return 'defaultdb';
179
+ }
@@ -0,0 +1,6 @@
1
+ import type { CloudFoundryServiceInfoCreator } from '../spi/creator.js';
2
+ import type { RawVcapServiceData, UserProvidedServiceInfo } from '../types.js';
3
+ export declare class UserProvidedServiceInfoCreator implements CloudFoundryServiceInfoCreator<UserProvidedServiceInfo> {
4
+ accept(serviceData: RawVcapServiceData): boolean;
5
+ createServiceInfo(serviceData: RawVcapServiceData): UserProvidedServiceInfo;
6
+ }
@@ -0,0 +1,36 @@
1
+ export class UserProvidedServiceInfoCreator {
2
+ accept(serviceData) {
3
+ const label = (serviceData.label || '').toLowerCase();
4
+ return label === 'user-provided' || label.length === 0 || !label;
5
+ }
6
+ createServiceInfo(serviceData) {
7
+ const creds = (serviceData.credentials || {});
8
+ const tags = (serviceData.tags || []).map(String);
9
+ const uri = (creds.uri ?? creds.url) ? String(creds.uri ?? creds.url) : undefined;
10
+ const host = (creds.host ?? creds.hostname) ? String(creds.host ?? creds.hostname) : undefined;
11
+ let port;
12
+ if (typeof creds.port === 'number') {
13
+ port = creds.port;
14
+ }
15
+ else if (typeof creds.port === 'string' && creds.port.trim().length > 0) {
16
+ const p = parseInt(creds.port, 10);
17
+ if (!Number.isNaN(p))
18
+ port = p;
19
+ }
20
+ const username = (creds.username ?? creds.user) ? String(creds.username ?? creds.user) : undefined;
21
+ const password = (creds.password ?? creds.pass) ? String(creds.password ?? creds.pass) : undefined;
22
+ return {
23
+ id: serviceData.name,
24
+ name: serviceData.name,
25
+ label: serviceData.label || 'user-provided',
26
+ ...(serviceData.plan ? { plan: serviceData.plan } : {}),
27
+ tags,
28
+ credentials: Object.freeze({ ...creds }),
29
+ ...(uri !== undefined ? { uri } : {}),
30
+ ...(host !== undefined ? { host } : {}),
31
+ ...(port !== undefined ? { port } : {}),
32
+ ...(username !== undefined ? { username } : {}),
33
+ ...(password !== undefined ? { password } : {}),
34
+ };
35
+ }
36
+ }
@@ -0,0 +1,34 @@
1
+ import type { CloudFoundryServiceOptions, EnableCloudFoundryConnectorsOptions, ServiceFilter } from './types.js';
2
+ /**
3
+ * Parameter or Property decorator that injects a bound Cloud Foundry service.
4
+ *
5
+ * @param serviceNameOrFilter Name, label, pattern, or filter object for the service.
6
+ * @param options Fallback environment keys, required flag, or default value.
7
+ *
8
+ * @example Property injection
9
+ * @Container()
10
+ * class DatabaseRepository {
11
+ * @CloudFoundryService('my-postgres')
12
+ * private dbService!: RelationalServiceInfo;
13
+ * }
14
+ *
15
+ * @example Constructor injection
16
+ * @Container()
17
+ * class CacheClient {
18
+ * constructor(
19
+ * @CloudFoundryService('my-redis') private redis: RedisServiceInfo
20
+ * ) {}
21
+ * }
22
+ */
23
+ export declare function CloudFoundryService(serviceNameOrFilter?: string | RegExp | ServiceFilter, options?: CloudFoundryServiceOptions): (targetClass: any, propertyKey?: string | symbol, parameterIndex?: number) => void;
24
+ /**
25
+ * Injects Cloud Foundry application metadata (VCAP_APPLICATION).
26
+ */
27
+ export declare function VcapApplication(options?: {
28
+ required?: boolean;
29
+ container?: unknown;
30
+ }): (targetClass: any, propertyKey?: string | symbol, parameterIndex?: number) => void;
31
+ /**
32
+ * Class decorator that enables Cloud Foundry connector auto-configuration on the DI container.
33
+ */
34
+ export declare function EnableCloudFoundryConnectors(options?: EnableCloudFoundryConnectorsOptions): <T extends new (...args: any[]) => any>(ctor: T) => T;
@@ -0,0 +1,202 @@
1
+ import { defineMetadata, getOwnMetadata, useContainer } from '@di-framework/core/container';
2
+ import { bindCloudFoundryConnectors, CF_APPLICATION_TOKEN } from './bindings.js';
3
+ import { getDefaultEnvironment } from './environment.js';
4
+ const INJECT_METADATA_KEY = 'di:inject';
5
+ /**
6
+ * Parameter or Property decorator that injects a bound Cloud Foundry service.
7
+ *
8
+ * @param serviceNameOrFilter Name, label, pattern, or filter object for the service.
9
+ * @param options Fallback environment keys, required flag, or default value.
10
+ *
11
+ * @example Property injection
12
+ * @Container()
13
+ * class DatabaseRepository {
14
+ * @CloudFoundryService('my-postgres')
15
+ * private dbService!: RelationalServiceInfo;
16
+ * }
17
+ *
18
+ * @example Constructor injection
19
+ * @Container()
20
+ * class CacheClient {
21
+ * constructor(
22
+ * @CloudFoundryService('my-redis') private redis: RedisServiceInfo
23
+ * ) {}
24
+ * }
25
+ */
26
+ export function CloudFoundryService(serviceNameOrFilter, options = {}) {
27
+ return (
28
+ // biome-ignore lint/suspicious/noExplicitAny: decorator target
29
+ targetClass, propertyKey, parameterIndex) => {
30
+ const token = deriveServiceToken(serviceNameOrFilter);
31
+ // Property injection
32
+ if (propertyKey !== undefined && parameterIndex === undefined) {
33
+ const metadata = getOwnMetadata(INJECT_METADATA_KEY, targetClass) || {};
34
+ metadata[propertyKey] = token;
35
+ defineMetadata(INJECT_METADATA_KEY, metadata, targetClass);
36
+ if (targetClass.constructor && targetClass.constructor !== Object) {
37
+ const ctorMetadata = getOwnMetadata(INJECT_METADATA_KEY, targetClass.constructor) || {};
38
+ ctorMetadata[propertyKey] = token;
39
+ defineMetadata(INJECT_METADATA_KEY, ctorMetadata, targetClass.constructor);
40
+ }
41
+ // Define property getter fallback in case accessed without DI resolution
42
+ let cachedValue;
43
+ Object.defineProperty(targetClass, propertyKey, {
44
+ configurable: true,
45
+ enumerable: true,
46
+ get() {
47
+ if (cachedValue !== undefined)
48
+ return cachedValue;
49
+ // Attempt container resolution first
50
+ const container = options.container ?? useContainer();
51
+ if (container && typeof container.resolve === 'function') {
52
+ try {
53
+ const res = container.resolve(token);
54
+ if (res !== undefined && res !== null) {
55
+ cachedValue = res;
56
+ return cachedValue;
57
+ }
58
+ }
59
+ catch {
60
+ // fall through to environment lookup
61
+ }
62
+ }
63
+ // Fallback to CloudFoundryEnvironment lookup
64
+ const env = getDefaultEnvironment();
65
+ let service = null;
66
+ if (typeof serviceNameOrFilter === 'string') {
67
+ service = env.getServiceInfo(serviceNameOrFilter);
68
+ }
69
+ else if (serviceNameOrFilter) {
70
+ service = env.getServiceInfo(serviceNameOrFilter);
71
+ }
72
+ else {
73
+ const all = env.getServiceInfos();
74
+ service = all[0] ?? null;
75
+ }
76
+ if (service) {
77
+ cachedValue = service;
78
+ return cachedValue;
79
+ }
80
+ if (options.fallbackEnv) {
81
+ const keys = Array.isArray(options.fallbackEnv)
82
+ ? options.fallbackEnv
83
+ : [options.fallbackEnv];
84
+ for (const key of keys) {
85
+ const val = process.env[key];
86
+ if (val) {
87
+ cachedValue = {
88
+ uri: val,
89
+ name: key,
90
+ label: 'fallback',
91
+ tags: [],
92
+ credentials: { uri: val },
93
+ };
94
+ return cachedValue;
95
+ }
96
+ }
97
+ }
98
+ if (options.defaultValue !== undefined) {
99
+ return options.defaultValue;
100
+ }
101
+ if (options.required !== false) {
102
+ throw new Error(`Cloud Foundry service '${String(serviceNameOrFilter ?? 'default')}' not found and no fallback available`);
103
+ }
104
+ return undefined;
105
+ },
106
+ set(value) {
107
+ cachedValue = value;
108
+ },
109
+ });
110
+ }
111
+ // Constructor parameter injection
112
+ else if (parameterIndex !== undefined) {
113
+ const metadata = getOwnMetadata(INJECT_METADATA_KEY, targetClass) || {};
114
+ metadata[`param_${parameterIndex}`] = token;
115
+ defineMetadata(INJECT_METADATA_KEY, metadata, targetClass);
116
+ }
117
+ };
118
+ }
119
+ /**
120
+ * Injects Cloud Foundry application metadata (VCAP_APPLICATION).
121
+ */
122
+ export function VcapApplication(options = {}) {
123
+ return (
124
+ // biome-ignore lint/suspicious/noExplicitAny: decorator target
125
+ targetClass, propertyKey, parameterIndex) => {
126
+ const token = CF_APPLICATION_TOKEN;
127
+ if (propertyKey !== undefined && parameterIndex === undefined) {
128
+ const metadata = getOwnMetadata(INJECT_METADATA_KEY, targetClass) || {};
129
+ metadata[propertyKey] = token;
130
+ defineMetadata(INJECT_METADATA_KEY, metadata, targetClass);
131
+ if (targetClass.constructor && targetClass.constructor !== Object) {
132
+ const ctorMetadata = getOwnMetadata(INJECT_METADATA_KEY, targetClass.constructor) || {};
133
+ ctorMetadata[propertyKey] = token;
134
+ defineMetadata(INJECT_METADATA_KEY, ctorMetadata, targetClass.constructor);
135
+ }
136
+ let cachedAppInfo;
137
+ Object.defineProperty(targetClass, propertyKey, {
138
+ configurable: true,
139
+ enumerable: true,
140
+ get() {
141
+ if (cachedAppInfo !== undefined)
142
+ return cachedAppInfo;
143
+ const container = options.container ?? useContainer();
144
+ if (container && typeof container.resolve === 'function') {
145
+ try {
146
+ const res = container.resolve(token);
147
+ if (res !== undefined && res !== null) {
148
+ cachedAppInfo = res;
149
+ return cachedAppInfo;
150
+ }
151
+ }
152
+ catch {
153
+ // fallback
154
+ }
155
+ }
156
+ const info = getDefaultEnvironment().getApplicationInfo();
157
+ if (!info && options.required === true) {
158
+ throw new Error('Cloud Foundry application info (VCAP_APPLICATION) is required but not present');
159
+ }
160
+ cachedAppInfo = info;
161
+ return cachedAppInfo;
162
+ },
163
+ set(value) {
164
+ cachedAppInfo = value;
165
+ },
166
+ });
167
+ }
168
+ else if (parameterIndex !== undefined) {
169
+ const metadata = getOwnMetadata(INJECT_METADATA_KEY, targetClass) || {};
170
+ metadata[`param_${parameterIndex}`] = token;
171
+ defineMetadata(INJECT_METADATA_KEY, metadata, targetClass);
172
+ }
173
+ };
174
+ }
175
+ /**
176
+ * Class decorator that enables Cloud Foundry connector auto-configuration on the DI container.
177
+ */
178
+ export function EnableCloudFoundryConnectors(options = {}) {
179
+ // biome-ignore lint/suspicious/noExplicitAny: class constructor
180
+ return (ctor) => {
181
+ bindCloudFoundryConnectors(options.container, options);
182
+ return ctor;
183
+ };
184
+ }
185
+ function deriveServiceToken(serviceNameOrFilter) {
186
+ if (typeof serviceNameOrFilter === 'string') {
187
+ return `cf:service:${serviceNameOrFilter}`;
188
+ }
189
+ if (serviceNameOrFilter &&
190
+ typeof serviceNameOrFilter === 'object' &&
191
+ 'name' in serviceNameOrFilter &&
192
+ typeof serviceNameOrFilter.name === 'string') {
193
+ return `cf:service:${serviceNameOrFilter.name}`;
194
+ }
195
+ if (serviceNameOrFilter &&
196
+ typeof serviceNameOrFilter === 'object' &&
197
+ 'label' in serviceNameOrFilter &&
198
+ typeof serviceNameOrFilter.label === 'string') {
199
+ return `cf:service:${serviceNameOrFilter.label}`;
200
+ }
201
+ return 'cf:service:default';
202
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Utility class for detecting Cloud Foundry runtime environments.
3
+ */
4
+ export declare class CloudFoundryDetector {
5
+ /**
6
+ * Returns true if running within a Cloud Foundry runtime environment
7
+ * (determined by presence of VCAP_APPLICATION or VCAP_SERVICES).
8
+ */
9
+ static isCloudFoundry(env?: Record<string, string | undefined>): boolean;
10
+ /**
11
+ * Retrieves raw VCAP_APPLICATION JSON string from environment.
12
+ */
13
+ static getApplicationJson(env?: Record<string, string | undefined>): string | undefined;
14
+ /**
15
+ * Retrieves raw VCAP_SERVICES JSON string from environment.
16
+ */
17
+ static getServicesJson(env?: Record<string, string | undefined>): string | undefined;
18
+ }
19
+ /**
20
+ * Convenient standalone check for Cloud Foundry runtime.
21
+ */
22
+ export declare function isCloudFoundry(env?: Record<string, string | undefined>): boolean;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Utility class for detecting Cloud Foundry runtime environments.
3
+ */
4
+ export class CloudFoundryDetector {
5
+ /**
6
+ * Returns true if running within a Cloud Foundry runtime environment
7
+ * (determined by presence of VCAP_APPLICATION or VCAP_SERVICES).
8
+ */
9
+ static isCloudFoundry(env = process.env) {
10
+ const vcapApp = env.VCAP_APPLICATION;
11
+ const vcapServices = env.VCAP_SERVICES;
12
+ return Boolean((typeof vcapApp === 'string' && vcapApp.trim().length > 0) ||
13
+ (typeof vcapServices === 'string' && vcapServices.trim().length > 0));
14
+ }
15
+ /**
16
+ * Retrieves raw VCAP_APPLICATION JSON string from environment.
17
+ */
18
+ static getApplicationJson(env = process.env) {
19
+ const val = env.VCAP_APPLICATION;
20
+ return typeof val === 'string' && val.trim().length > 0 ? val.trim() : undefined;
21
+ }
22
+ /**
23
+ * Retrieves raw VCAP_SERVICES JSON string from environment.
24
+ */
25
+ static getServicesJson(env = process.env) {
26
+ const val = env.VCAP_SERVICES;
27
+ return typeof val === 'string' && val.trim().length > 0 ? val.trim() : undefined;
28
+ }
29
+ }
30
+ /**
31
+ * Convenient standalone check for Cloud Foundry runtime.
32
+ */
33
+ export function isCloudFoundry(env = process.env) {
34
+ return CloudFoundryDetector.isCloudFoundry(env);
35
+ }
@@ -0,0 +1,62 @@
1
+ import { type ServiceInfoCreatorRegistry } from './spi/registry.js';
2
+ import type { AmqpServiceInfo, BlobStorageServiceInfo, CloudFoundryApplicationInfo, CloudFoundryServiceInfo, LocalFallbackOptions, RedisServiceInfo, RelationalServiceInfo, ServiceFilter, UserProvidedServiceInfo } from './types.js';
3
+ export interface CloudFoundryEnvironmentOptions {
4
+ /** Custom environment dictionary (defaults to process.env) */
5
+ env?: Record<string, string | undefined>;
6
+ /** Custom service info creator registry */
7
+ registry?: ServiceInfoCreatorRegistry;
8
+ /** Options or boolean for local fallback */
9
+ localFallback?: boolean | LocalFallbackOptions;
10
+ }
11
+ export declare class CloudFoundryEnvironment {
12
+ private readonly env;
13
+ private readonly registry;
14
+ private readonly localFallbackOptions;
15
+ private appInfo;
16
+ private services;
17
+ constructor(options?: CloudFoundryEnvironmentOptions);
18
+ /**
19
+ * Returns true if running within a Cloud Foundry runtime.
20
+ */
21
+ isCloudFoundry(): boolean;
22
+ /**
23
+ * Returns parsed CloudFoundryApplicationInfo or null if not running in CF.
24
+ */
25
+ getApplicationInfo(): CloudFoundryApplicationInfo | null;
26
+ /**
27
+ * Retrieves all discovered Cloud Foundry services, applying optional filtering.
28
+ */
29
+ getServiceInfos<T extends CloudFoundryServiceInfo = CloudFoundryServiceInfo>(filter?: ServiceFilter | string | RegExp): readonly T[];
30
+ /**
31
+ * Retrieves a single service by name, filter, or returns the first matching service.
32
+ */
33
+ getServiceInfo<T extends CloudFoundryServiceInfo = CloudFoundryServiceInfo>(serviceNameOrFilter?: string | RegExp | ServiceFilter): T | null;
34
+ /**
35
+ * Retrieves relational database service info (PostgreSQL, MySQL, MariaDB, SQLite).
36
+ */
37
+ getRelationalServiceInfo(filter?: string | RegExp | ServiceFilter): RelationalServiceInfo | null;
38
+ /**
39
+ * Retrieves Redis service info.
40
+ */
41
+ getRedisServiceInfo(filter?: string | RegExp | ServiceFilter): RedisServiceInfo | null;
42
+ /**
43
+ * Retrieves AMQP / RabbitMQ service info.
44
+ */
45
+ getAmqpServiceInfo(filter?: string | RegExp | ServiceFilter): AmqpServiceInfo | null;
46
+ /**
47
+ * Retrieves Blob Storage / S3 service info.
48
+ */
49
+ getBlobStorageServiceInfo(filter?: string | RegExp | ServiceFilter): BlobStorageServiceInfo | null;
50
+ /**
51
+ * Retrieves User-Provided service info.
52
+ */
53
+ getUserProvidedServiceInfo(filter?: string | RegExp | ServiceFilter): UserProvidedServiceInfo | null;
54
+ /**
55
+ * Retrieves raw credentials map for a service.
56
+ */
57
+ getServiceCredentials<T = Record<string, unknown>>(serviceName: string): T | null;
58
+ private ensureServicesLoaded;
59
+ private buildLocalFallbackServices;
60
+ }
61
+ export declare function getDefaultEnvironment(): CloudFoundryEnvironment;
62
+ export declare function resetDefaultEnvironment(): void;