@wildo-ai/platform-config-lib 1.0.1
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/dist/esm/bootstrap/application-backend-env.contracts.d.ts +2 -0
- package/dist/esm/bootstrap/application-backend-env.contracts.d.ts.map +1 -0
- package/dist/esm/bootstrap/application-backend-env.contracts.js +2 -0
- package/dist/esm/bootstrap/application-backend-env.contracts.js.map +1 -0
- package/dist/esm/bootstrap/bootstrap-planner.d.ts +20 -0
- package/dist/esm/bootstrap/bootstrap-planner.d.ts.map +1 -0
- package/dist/esm/bootstrap/bootstrap-planner.js +26 -0
- package/dist/esm/bootstrap/bootstrap-planner.js.map +1 -0
- package/dist/esm/bootstrap/bootstrap.contracts.d.ts +120 -0
- package/dist/esm/bootstrap/bootstrap.contracts.d.ts.map +1 -0
- package/dist/esm/bootstrap/bootstrap.contracts.js +117 -0
- package/dist/esm/bootstrap/bootstrap.contracts.js.map +1 -0
- package/dist/esm/bootstrap/bootstrap.schemas.d.ts +485 -0
- package/dist/esm/bootstrap/bootstrap.schemas.d.ts.map +1 -0
- package/dist/esm/bootstrap/bootstrap.schemas.js +130 -0
- package/dist/esm/bootstrap/bootstrap.schemas.js.map +1 -0
- package/dist/esm/bootstrap/platform-runtime-env.contracts.d.ts +78 -0
- package/dist/esm/bootstrap/platform-runtime-env.contracts.d.ts.map +1 -0
- package/dist/esm/bootstrap/platform-runtime-env.contracts.js +98 -0
- package/dist/esm/bootstrap/platform-runtime-env.contracts.js.map +1 -0
- package/dist/esm/bootstrap/runtime-topology.contracts.d.ts +17 -0
- package/dist/esm/bootstrap/runtime-topology.contracts.d.ts.map +1 -0
- package/dist/esm/bootstrap/runtime-topology.contracts.js +60 -0
- package/dist/esm/bootstrap/runtime-topology.contracts.js.map +1 -0
- package/dist/esm/credentials/credential-generator.service.d.ts +11 -0
- package/dist/esm/credentials/credential-generator.service.d.ts.map +1 -0
- package/dist/esm/credentials/credential-generator.service.js +31 -0
- package/dist/esm/credentials/credential-generator.service.js.map +1 -0
- package/dist/esm/credentials/credentials-provisioner.service.d.ts +190 -0
- package/dist/esm/credentials/credentials-provisioner.service.d.ts.map +1 -0
- package/dist/esm/credentials/credentials-provisioner.service.js +278 -0
- package/dist/esm/credentials/credentials-provisioner.service.js.map +1 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/infra-managers/infra-manager.models.d.ts +146 -0
- package/dist/esm/infra-managers/infra-manager.models.d.ts.map +1 -0
- package/dist/esm/infra-managers/infra-manager.models.js +2 -0
- package/dist/esm/infra-managers/infra-manager.models.js.map +1 -0
- package/dist/esm/infra-managers/mongo-atlas-manager.service.d.ts +64 -0
- package/dist/esm/infra-managers/mongo-atlas-manager.service.d.ts.map +1 -0
- package/dist/esm/infra-managers/mongo-atlas-manager.service.js +307 -0
- package/dist/esm/infra-managers/mongo-atlas-manager.service.js.map +1 -0
- package/dist/esm/infra-managers/postgresql-manager.service.d.ts +115 -0
- package/dist/esm/infra-managers/postgresql-manager.service.d.ts.map +1 -0
- package/dist/esm/infra-managers/postgresql-manager.service.js +403 -0
- package/dist/esm/infra-managers/postgresql-manager.service.js.map +1 -0
- package/dist/esm/infra-managers/rabbitmq-manager.service.d.ts +64 -0
- package/dist/esm/infra-managers/rabbitmq-manager.service.d.ts.map +1 -0
- package/dist/esm/infra-managers/rabbitmq-manager.service.js +288 -0
- package/dist/esm/infra-managers/rabbitmq-manager.service.js.map +1 -0
- package/dist/esm/infra-managers/redis-manager.service.d.ts +78 -0
- package/dist/esm/infra-managers/redis-manager.service.d.ts.map +1 -0
- package/dist/esm/infra-managers/redis-manager.service.js +326 -0
- package/dist/esm/infra-managers/redis-manager.service.js.map +1 -0
- package/dist/esm/project-config/define-framework-config.d.ts +36 -0
- package/dist/esm/project-config/define-framework-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-framework-config.js +30 -0
- package/dist/esm/project-config/define-framework-config.js.map +1 -0
- package/dist/esm/project-config/define-infra-config.d.ts +128 -0
- package/dist/esm/project-config/define-infra-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-infra-config.js +87 -0
- package/dist/esm/project-config/define-infra-config.js.map +1 -0
- package/dist/esm/project-config/define-minion-config.d.ts +41 -0
- package/dist/esm/project-config/define-minion-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-minion-config.js +24 -0
- package/dist/esm/project-config/define-minion-config.js.map +1 -0
- package/dist/esm/project-config/define-platform-config.d.ts +65 -0
- package/dist/esm/project-config/define-platform-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-platform-config.js +22 -0
- package/dist/esm/project-config/define-platform-config.js.map +1 -0
- package/dist/esm/project-config/define-platform-env-config.d.ts +41 -0
- package/dist/esm/project-config/define-platform-env-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-platform-env-config.js +45 -0
- package/dist/esm/project-config/define-platform-env-config.js.map +1 -0
- package/dist/esm/project-config/define-project-config.d.ts +38 -0
- package/dist/esm/project-config/define-project-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-project-config.js +57 -0
- package/dist/esm/project-config/define-project-config.js.map +1 -0
- package/dist/esm/project-config/define-saas-config.d.ts +252 -0
- package/dist/esm/project-config/define-saas-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-saas-config.js +137 -0
- package/dist/esm/project-config/define-saas-config.js.map +1 -0
- package/dist/esm/project-config/define-sharing-policy.d.ts +35 -0
- package/dist/esm/project-config/define-sharing-policy.d.ts.map +1 -0
- package/dist/esm/project-config/define-sharing-policy.js +30 -0
- package/dist/esm/project-config/define-sharing-policy.js.map +1 -0
- package/dist/esm/project-config/define-worker-config.d.ts +42 -0
- package/dist/esm/project-config/define-worker-config.d.ts.map +1 -0
- package/dist/esm/project-config/define-worker-config.js +24 -0
- package/dist/esm/project-config/define-worker-config.js.map +1 -0
- package/dist/esm/project-config/index.d.ts +22 -0
- package/dist/esm/project-config/index.d.ts.map +1 -0
- package/dist/esm/project-config/index.js +22 -0
- package/dist/esm/project-config/index.js.map +1 -0
- package/dist/esm/project-config/loader.d.ts +42 -0
- package/dist/esm/project-config/loader.d.ts.map +1 -0
- package/dist/esm/project-config/loader.js +164 -0
- package/dist/esm/project-config/loader.js.map +1 -0
- package/dist/esm/project-config/shared/application-modules.schemas.d.ts +10 -0
- package/dist/esm/project-config/shared/application-modules.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/application-modules.schemas.js +6 -0
- package/dist/esm/project-config/shared/application-modules.schemas.js.map +1 -0
- package/dist/esm/project-config/shared/application-modules.utils.d.ts +6 -0
- package/dist/esm/project-config/shared/application-modules.utils.d.ts.map +1 -0
- package/dist/esm/project-config/shared/application-modules.utils.js +26 -0
- package/dist/esm/project-config/shared/application-modules.utils.js.map +1 -0
- package/dist/esm/project-config/shared/backing-services.schemas.d.ts +68 -0
- package/dist/esm/project-config/shared/backing-services.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/backing-services.schemas.js +49 -0
- package/dist/esm/project-config/shared/backing-services.schemas.js.map +1 -0
- package/dist/esm/project-config/shared/data-services.schemas.d.ts +33 -0
- package/dist/esm/project-config/shared/data-services.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/data-services.schemas.js +47 -0
- package/dist/esm/project-config/shared/data-services.schemas.js.map +1 -0
- package/dist/esm/project-config/shared/env-example-defaults.d.ts +27 -0
- package/dist/esm/project-config/shared/env-example-defaults.d.ts.map +1 -0
- package/dist/esm/project-config/shared/env-example-defaults.js +30 -0
- package/dist/esm/project-config/shared/env-example-defaults.js.map +1 -0
- package/dist/esm/project-config/shared/environment.schemas.d.ts +106 -0
- package/dist/esm/project-config/shared/environment.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/environment.schemas.js +111 -0
- package/dist/esm/project-config/shared/environment.schemas.js.map +1 -0
- package/dist/esm/project-config/shared/infrastructure-defaults.schemas.d.ts +42 -0
- package/dist/esm/project-config/shared/infrastructure-defaults.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/infrastructure-defaults.schemas.js +42 -0
- package/dist/esm/project-config/shared/infrastructure-defaults.schemas.js.map +1 -0
- package/dist/esm/project-config/shared/k8s-utils.d.ts +36 -0
- package/dist/esm/project-config/shared/k8s-utils.d.ts.map +1 -0
- package/dist/esm/project-config/shared/k8s-utils.js +50 -0
- package/dist/esm/project-config/shared/k8s-utils.js.map +1 -0
- package/dist/esm/project-config/shared/platform-services.schemas.d.ts +30 -0
- package/dist/esm/project-config/shared/platform-services.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/platform-services.schemas.js +27 -0
- package/dist/esm/project-config/shared/platform-services.schemas.js.map +1 -0
- package/dist/esm/project-config/shared/service-definitions.schemas.d.ts +42 -0
- package/dist/esm/project-config/shared/service-definitions.schemas.d.ts.map +1 -0
- package/dist/esm/project-config/shared/service-definitions.schemas.js +29 -0
- package/dist/esm/project-config/shared/service-definitions.schemas.js.map +1 -0
- package/dist/esm/project-config/sharing-policy-validation.d.ts +40 -0
- package/dist/esm/project-config/sharing-policy-validation.d.ts.map +1 -0
- package/dist/esm/project-config/sharing-policy-validation.js +143 -0
- package/dist/esm/project-config/sharing-policy-validation.js.map +1 -0
- package/dist/esm/release/framework-release.constants.d.ts +3 -0
- package/dist/esm/release/framework-release.constants.d.ts.map +1 -0
- package/dist/esm/release/framework-release.constants.js +3 -0
- package/dist/esm/release/framework-release.constants.js.map +1 -0
- package/dist/esm/runtime-bridge/platform-runtime-bridge.contracts.d.ts +23 -0
- package/dist/esm/runtime-bridge/platform-runtime-bridge.contracts.d.ts.map +1 -0
- package/dist/esm/runtime-bridge/platform-runtime-bridge.contracts.js +13 -0
- package/dist/esm/runtime-bridge/platform-runtime-bridge.contracts.js.map +1 -0
- package/dist/esm/schemas/framework-info.schemas.d.ts +8 -0
- package/dist/esm/schemas/framework-info.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/framework-info.schemas.js +8 -0
- package/dist/esm/schemas/framework-info.schemas.js.map +1 -0
- package/dist/esm/schemas/framework-secrets.schemas.d.ts +22 -0
- package/dist/esm/schemas/framework-secrets.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/framework-secrets.schemas.js +14 -0
- package/dist/esm/schemas/framework-secrets.schemas.js.map +1 -0
- package/dist/esm/schemas/platform-application-config.schemas.d.ts +20 -0
- package/dist/esm/schemas/platform-application-config.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/platform-application-config.schemas.js +19 -0
- package/dist/esm/schemas/platform-application-config.schemas.js.map +1 -0
- package/dist/esm/schemas/platform-application-secrets.schemas.d.ts +54 -0
- package/dist/esm/schemas/platform-application-secrets.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/platform-application-secrets.schemas.js +67 -0
- package/dist/esm/schemas/platform-application-secrets.schemas.js.map +1 -0
- package/dist/esm/schemas/platform-config.schemas.d.ts +66 -0
- package/dist/esm/schemas/platform-config.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/platform-config.schemas.js +28 -0
- package/dist/esm/schemas/platform-config.schemas.js.map +1 -0
- package/dist/esm/workspace-scope/index.d.ts +3 -0
- package/dist/esm/workspace-scope/index.d.ts.map +1 -0
- package/dist/esm/workspace-scope/index.js +3 -0
- package/dist/esm/workspace-scope/index.js.map +1 -0
- package/dist/esm/workspace-scope/workspace-scope-detector.d.ts +15 -0
- package/dist/esm/workspace-scope/workspace-scope-detector.d.ts.map +1 -0
- package/dist/esm/workspace-scope/workspace-scope-detector.js +87 -0
- package/dist/esm/workspace-scope/workspace-scope-detector.js.map +1 -0
- package/dist/esm/workspace-scope/workspace-scope.schemas.d.ts +118 -0
- package/dist/esm/workspace-scope/workspace-scope.schemas.d.ts.map +1 -0
- package/dist/esm/workspace-scope/workspace-scope.schemas.js +157 -0
- package/dist/esm/workspace-scope/workspace-scope.schemas.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +52 -0
- package/src/bootstrap/application-backend-env.contracts.ts +17 -0
- package/src/bootstrap/bootstrap-planner.ts +46 -0
- package/src/bootstrap/bootstrap.contracts.ts +251 -0
- package/src/bootstrap/bootstrap.schemas.ts +164 -0
- package/src/bootstrap/platform-runtime-env.contracts.ts +99 -0
- package/src/bootstrap/runtime-topology.contracts.ts +102 -0
- package/src/credentials/credential-generator.service.ts +39 -0
- package/src/index.ts +16 -0
- package/src/project-config/__tests__/application-modules.utils.test.ts +53 -0
- package/src/project-config/__tests__/define-framework-config.test.ts +43 -0
- package/src/project-config/__tests__/define-saas-config.test.ts +210 -0
- package/src/project-config/__tests__/loader.test.ts +100 -0
- package/src/project-config/define-framework-config.ts +44 -0
- package/src/project-config/define-infra-config.ts +168 -0
- package/src/project-config/define-minion-config.ts +27 -0
- package/src/project-config/define-platform-config.ts +28 -0
- package/src/project-config/define-platform-env-config.ts +59 -0
- package/src/project-config/define-project-config.ts +63 -0
- package/src/project-config/define-saas-config.ts +171 -0
- package/src/project-config/define-sharing-policy.ts +36 -0
- package/src/project-config/define-worker-config.ts +27 -0
- package/src/project-config/index.ts +23 -0
- package/src/project-config/loader.ts +220 -0
- package/src/project-config/shared/application-modules.schemas.ts +12 -0
- package/src/project-config/shared/application-modules.utils.ts +65 -0
- package/src/project-config/shared/backing-services.schemas.ts +59 -0
- package/src/project-config/shared/data-services.schemas.ts +58 -0
- package/src/project-config/shared/env-example-defaults.ts +50 -0
- package/src/project-config/shared/environment.schemas.ts +136 -0
- package/src/project-config/shared/infrastructure-defaults.schemas.ts +47 -0
- package/src/project-config/shared/k8s-utils.ts +56 -0
- package/src/project-config/shared/platform-services.schemas.ts +33 -0
- package/src/project-config/shared/service-definitions.schemas.ts +38 -0
- package/src/project-config/sharing-policy-validation.ts +159 -0
- package/src/release/framework-release.constants.ts +2 -0
- package/src/schemas/__tests__/platform-config.schemas.test.ts +90 -0
- package/src/schemas/framework-info.schemas.ts +13 -0
- package/src/schemas/framework-secrets.schemas.ts +19 -0
- package/src/schemas/platform-application-config.schemas.ts +25 -0
- package/src/schemas/platform-application-secrets.schemas.ts +78 -0
- package/src/schemas/platform-config.schemas.ts +45 -0
- package/src/workspace-scope/index.ts +2 -0
- package/src/workspace-scope/workspace-scope-detector.ts +98 -0
- package/src/workspace-scope/workspace-scope.schemas.ts +224 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { WildoSaasConfig } from './define-saas-config';
|
|
2
|
+
import type { WildoSharingPolicy } from './define-sharing-policy';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Severity levels for sharing policy validation findings.
|
|
6
|
+
*/
|
|
7
|
+
export enum SharingPolicyValidationSeverity {
|
|
8
|
+
ERROR = 'ERROR',
|
|
9
|
+
WARNING = 'WARNING',
|
|
10
|
+
INFO = 'INFO',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface SharingPolicyValidationFinding {
|
|
14
|
+
severity: SharingPolicyValidationSeverity;
|
|
15
|
+
code: string;
|
|
16
|
+
message: string;
|
|
17
|
+
providerRef?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Extract all provider refs declared in a SaaS config's capabilities.
|
|
22
|
+
* Returns a deduplicated set of provider reference strings.
|
|
23
|
+
*/
|
|
24
|
+
export function extractCapabilityProviders(saasConfig: WildoSaasConfig): Set<string> {
|
|
25
|
+
const providers = new Set<string>();
|
|
26
|
+
if (!saasConfig.capabilities) return providers;
|
|
27
|
+
|
|
28
|
+
for (const binding of Object.values(saasConfig.capabilities)) {
|
|
29
|
+
if (!binding || !binding.enabled) continue;
|
|
30
|
+
if (binding.provider) providers.add(binding.provider);
|
|
31
|
+
if (binding.providers) {
|
|
32
|
+
for (const p of binding.providers) providers.add(p);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return providers;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Extract all provider refs declared in a sharing policy's secrets.providers section.
|
|
40
|
+
* Returns the defaults array merged with all perApp include arrays (deduplicated).
|
|
41
|
+
*/
|
|
42
|
+
export function extractSharingPolicyProviders(sharingPolicy: WildoSharingPolicy): Set<string> {
|
|
43
|
+
const providers = new Set<string>();
|
|
44
|
+
const providerRule = sharingPolicy.secrets?.['providers'];
|
|
45
|
+
if (!providerRule) return providers;
|
|
46
|
+
|
|
47
|
+
const rule = providerRule as { defaults?: string[]; perApp?: Record<string, { include?: string[]; exclude?: string[] }> };
|
|
48
|
+
if (rule.defaults) {
|
|
49
|
+
for (const p of rule.defaults) providers.add(p);
|
|
50
|
+
}
|
|
51
|
+
if (rule.perApp) {
|
|
52
|
+
for (const appRule of Object.values(rule.perApp)) {
|
|
53
|
+
if (appRule.include) {
|
|
54
|
+
for (const p of appRule.include) providers.add(p);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return providers;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Cross-validate a sharing policy against a SaaS config's capabilities.
|
|
63
|
+
* Checks that all providers declared in capabilities are covered by the sharing policy,
|
|
64
|
+
* and reports providers in the sharing policy that aren't used by any capability.
|
|
65
|
+
*
|
|
66
|
+
* @param saasConfig - The loaded SaaS application config
|
|
67
|
+
* @param sharingPolicy - The loaded per-env sharing policy
|
|
68
|
+
* @param knownProviderRefs - Optional set of valid provider refs (e.g., from AllProviders_Map).
|
|
69
|
+
* If provided, validates that all referenced providers actually exist in the catalog.
|
|
70
|
+
* @param availableSecretProviderRefs - Optional set of provider refs that have secrets
|
|
71
|
+
* configured in secrets.json. If provided, warns about missing secrets.
|
|
72
|
+
*/
|
|
73
|
+
export function validateSharingPolicy(
|
|
74
|
+
saasConfig: WildoSaasConfig,
|
|
75
|
+
sharingPolicy: WildoSharingPolicy,
|
|
76
|
+
knownProviderRefs?: Set<string>,
|
|
77
|
+
availableSecretProviderRefs?: Set<string>,
|
|
78
|
+
): SharingPolicyValidationFinding[] {
|
|
79
|
+
const findings: SharingPolicyValidationFinding[] = [];
|
|
80
|
+
|
|
81
|
+
const capabilityProviders = extractCapabilityProviders(saasConfig);
|
|
82
|
+
const sharingPolicyProviders = extractSharingPolicyProviders(sharingPolicy);
|
|
83
|
+
|
|
84
|
+
for (const providerRef of capabilityProviders) {
|
|
85
|
+
if (!sharingPolicyProviders.has(providerRef)) {
|
|
86
|
+
findings.push({
|
|
87
|
+
severity: SharingPolicyValidationSeverity.ERROR,
|
|
88
|
+
code: 'CAPABILITY_PROVIDER_NOT_IN_SHARING_POLICY',
|
|
89
|
+
message: `Provider "${providerRef}" is declared in capabilities but not covered by the sharing policy`,
|
|
90
|
+
providerRef,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const providerRef of sharingPolicyProviders) {
|
|
96
|
+
if (!capabilityProviders.has(providerRef)) {
|
|
97
|
+
findings.push({
|
|
98
|
+
severity: SharingPolicyValidationSeverity.WARNING,
|
|
99
|
+
code: 'SHARING_POLICY_PROVIDER_NOT_IN_CAPABILITIES',
|
|
100
|
+
message: `Provider "${providerRef}" is in the sharing policy but not used by any capability`,
|
|
101
|
+
providerRef,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (knownProviderRefs) {
|
|
107
|
+
const allReferencedProviders = new Set([...capabilityProviders, ...sharingPolicyProviders]);
|
|
108
|
+
for (const providerRef of allReferencedProviders) {
|
|
109
|
+
if (!knownProviderRefs.has(providerRef)) {
|
|
110
|
+
findings.push({
|
|
111
|
+
severity: SharingPolicyValidationSeverity.ERROR,
|
|
112
|
+
code: 'UNKNOWN_PROVIDER_REF',
|
|
113
|
+
message: `Provider "${providerRef}" is not in the external-connectors catalog (AllProviders_Map)`,
|
|
114
|
+
providerRef,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (availableSecretProviderRefs) {
|
|
121
|
+
for (const providerRef of sharingPolicyProviders) {
|
|
122
|
+
if (!availableSecretProviderRefs.has(providerRef)) {
|
|
123
|
+
findings.push({
|
|
124
|
+
severity: SharingPolicyValidationSeverity.WARNING,
|
|
125
|
+
code: 'PROVIDER_SECRET_MISSING',
|
|
126
|
+
message: `Provider "${providerRef}" is declared in the sharing policy but has no API key in secrets.json`,
|
|
127
|
+
providerRef,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Validate that servicesRestrictions providers are subsets of the parent capability providers
|
|
134
|
+
if (saasConfig.capabilities) {
|
|
135
|
+
for (const [capKey, binding] of Object.entries(saasConfig.capabilities)) {
|
|
136
|
+
if (!binding?.enabled || !binding.servicesRestrictions) continue;
|
|
137
|
+
const parentProviders = new Set<string>();
|
|
138
|
+
if (binding.provider) parentProviders.add(binding.provider);
|
|
139
|
+
if (binding.providers) {
|
|
140
|
+
for (const p of binding.providers) parentProviders.add(p);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
for (const [serviceName, restrictedProviders] of Object.entries(binding.servicesRestrictions)) {
|
|
144
|
+
for (const rp of restrictedProviders) {
|
|
145
|
+
if (!parentProviders.has(rp)) {
|
|
146
|
+
findings.push({
|
|
147
|
+
severity: SharingPolicyValidationSeverity.INFO,
|
|
148
|
+
code: 'SERVICE_RESTRICTION_NOT_IN_PARENT',
|
|
149
|
+
message: `servicesRestrictions for "${serviceName}" in capability "${capKey}" references provider "${rp}" which is not in the parent providers list`,
|
|
150
|
+
providerRef: rp,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return findings;
|
|
159
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import '@wildo-ai/zod-decorators';
|
|
3
|
+
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
AppsManagerConfig_Schema,
|
|
8
|
+
AppsManagerSecrets_Schema,
|
|
9
|
+
} from '../platform-config.schemas';
|
|
10
|
+
|
|
11
|
+
describe('AppsManagerConfig_Schema', () => {
|
|
12
|
+
it('extends the platform application config with runtime platform service URLs', () => {
|
|
13
|
+
const parsed = AppsManagerConfig_Schema.parse({
|
|
14
|
+
platformApplicationId: 'app-123',
|
|
15
|
+
jwtPublicKeys: {
|
|
16
|
+
primary: 'public-key',
|
|
17
|
+
},
|
|
18
|
+
customConfig: {
|
|
19
|
+
featureFlag: true,
|
|
20
|
+
},
|
|
21
|
+
platformServices: {
|
|
22
|
+
appsManager: 'https://apps-manager.wildo.ai',
|
|
23
|
+
fileGenerator: 'https://file-generator.wildo.ai',
|
|
24
|
+
crontabsBatchesManager: 'https://crontabs-manager.wildo.ai',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(parsed.platformApplicationId).toBe('app-123');
|
|
29
|
+
expect(parsed.jwtPublicKeys.primary).toBe('public-key');
|
|
30
|
+
expect(parsed.platformServices.fileGenerator).toBe('https://file-generator.wildo.ai');
|
|
31
|
+
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('requires the managed platform service URL set', () => {
|
|
35
|
+
const result = AppsManagerConfig_Schema.safeParse({
|
|
36
|
+
platformApplicationId: 'app-123',
|
|
37
|
+
jwtPublicKeys: {
|
|
38
|
+
primary: 'public-key',
|
|
39
|
+
},
|
|
40
|
+
platformServices: {
|
|
41
|
+
appsManager: 'https://apps-manager.wildo.ai',
|
|
42
|
+
crontabsBatchesManager: 'https://crontabs-manager.wildo.ai',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(result.success).toBe(false);
|
|
47
|
+
expect(result.error?.issues.some((issue) => issue.path.join('.') === 'platformServices.fileGenerator')).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('AppsManagerSecrets_Schema', () => {
|
|
52
|
+
it('requires a mongo connection URL while keeping Atlas credentials optional', () => {
|
|
53
|
+
const parsed = AppsManagerSecrets_Schema.parse({
|
|
54
|
+
platformApplicationId: 'app-123',
|
|
55
|
+
jwt: {
|
|
56
|
+
privateKey: {
|
|
57
|
+
primary: 'private-key',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
mongo: {
|
|
61
|
+
connectUrl: 'https://mongo.example.com',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(parsed.mongo.connectUrl).toBe('https://mongo.example.com');
|
|
66
|
+
expect(parsed.mongo.atlas).toBeUndefined();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('rejects empty Atlas credentials when Atlas config is provided', () => {
|
|
70
|
+
const result = AppsManagerSecrets_Schema.safeParse({
|
|
71
|
+
platformApplicationId: 'app-123',
|
|
72
|
+
jwt: {
|
|
73
|
+
privateKey: {
|
|
74
|
+
primary: 'private-key',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
mongo: {
|
|
78
|
+
connectUrl: 'https://mongo.example.com',
|
|
79
|
+
atlas: {
|
|
80
|
+
publicKey: '',
|
|
81
|
+
privateKey: '',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(result.success).toBe(false);
|
|
87
|
+
expect(result.error?.issues.some((issue) => issue.path.join('.') === 'mongo.atlas.publicKey')).toBe(true);
|
|
88
|
+
expect(result.error?.issues.some((issue) => issue.path.join('.') === 'mongo.atlas.privateKey')).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
const SemverSchema = z.string().regex(
|
|
4
|
+
/^\d+\.\d+\.\d+$/,
|
|
5
|
+
'must be a simple semver string in the form x.y.z',
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
export const WildoFrameworkInfoSchema = z.object({
|
|
9
|
+
name: z.string().min(1).default('wildo-ai'),
|
|
10
|
+
version: SemverSchema,
|
|
11
|
+
minCliVersion: SemverSchema,
|
|
12
|
+
});
|
|
13
|
+
export type WildoFrameworkInfo = z.infer<typeof WildoFrameworkInfoSchema>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
export const WildoFrameworkPublishNpmSecretsSchema = z.object({
|
|
4
|
+
publishToken: z.string().min(1),
|
|
5
|
+
});
|
|
6
|
+
export type WildoFrameworkPublishNpmSecrets = z.infer<typeof WildoFrameworkPublishNpmSecretsSchema>;
|
|
7
|
+
|
|
8
|
+
export const WildoFrameworkPublishDockerSecretsSchema = z.object({
|
|
9
|
+
publishUsername: z.string().min(1).optional(),
|
|
10
|
+
publishToken: z.string().min(1),
|
|
11
|
+
});
|
|
12
|
+
export type WildoFrameworkPublishDockerSecrets = z.infer<typeof WildoFrameworkPublishDockerSecretsSchema>;
|
|
13
|
+
|
|
14
|
+
export const WildoFrameworkSecretsSchema = z.object({
|
|
15
|
+
providers: z.record(z.string(), z.string().min(1)).optional().default({}),
|
|
16
|
+
docker: WildoFrameworkPublishDockerSecretsSchema.optional(),
|
|
17
|
+
npm: WildoFrameworkPublishNpmSecretsSchema.optional(),
|
|
18
|
+
});
|
|
19
|
+
export type WildoFrameworkSecrets = z.infer<typeof WildoFrameworkSecretsSchema>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Platform Application Config Schema
|
|
5
|
+
*
|
|
6
|
+
* Stored in MongoDB, fetched by platform services via
|
|
7
|
+
* GET /platform-services-to-manager/config-secrets.
|
|
8
|
+
*
|
|
9
|
+
* After T4, platform service URLs and infrastructure addresses are sourced from
|
|
10
|
+
* each service's env vars (generated by CLI). This schema only contains data
|
|
11
|
+
* that apps-manager manages dynamically:
|
|
12
|
+
* - jwtPublicKeys: rotatable public keys for inter-service JWT verification
|
|
13
|
+
* - customConfig: service-specific key-value configuration
|
|
14
|
+
*/
|
|
15
|
+
export const Platform_Application_Config_Schema = z.object({
|
|
16
|
+
platformApplicationId: z.string().isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),
|
|
17
|
+
|
|
18
|
+
jwtPublicKeys: z.record(z.string(), z.string().min(1)),
|
|
19
|
+
|
|
20
|
+
customConfig: z.record(z.string(), z.unknown()).optional(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type Platform_Application_Config = z.infer<typeof Platform_Application_Config_Schema>;
|
|
24
|
+
|
|
25
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Platform Application Secrets Schema
|
|
5
|
+
*
|
|
6
|
+
* This schema defines all secrets for platform microservices.
|
|
7
|
+
* These secrets are stored in MongoDB and fetched by platform services via the
|
|
8
|
+
* GET /platform-services-to-manager/config-secrets endpoint.
|
|
9
|
+
*
|
|
10
|
+
* Structure:
|
|
11
|
+
* - primarySecret: The primary authentication secret for the service
|
|
12
|
+
* - jwt: Private/public keys for JWT signing/verification
|
|
13
|
+
* - redis: Redis ACL credentials
|
|
14
|
+
* - rabbitmq: RabbitMQ user credentials
|
|
15
|
+
* - mongo: MongoDB connection credentials (optional, for services that need direct DB access)
|
|
16
|
+
* - storage: S3/MinIO credentials (optional, for services that need storage access)
|
|
17
|
+
*/
|
|
18
|
+
export const Platform_Application_Secrets_Schema = z.object({
|
|
19
|
+
platformApplicationId: z.string().isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),
|
|
20
|
+
|
|
21
|
+
// Primary authentication secret for inter-service auth
|
|
22
|
+
primarySecret: z.string().min(1).optional(),
|
|
23
|
+
|
|
24
|
+
// JWT private/public keys for signing/verification
|
|
25
|
+
jwt: z.object({
|
|
26
|
+
privateKey: z.record(z.string(), z.string().min(1).optional()),
|
|
27
|
+
publicKey: z.record(z.string(), z.string().min(1).optional()).optional(),
|
|
28
|
+
}),
|
|
29
|
+
|
|
30
|
+
// Redis ACL credentials
|
|
31
|
+
redis: z.object({
|
|
32
|
+
username: z.string().min(1),
|
|
33
|
+
password: z.string().min(1),
|
|
34
|
+
}).optional(),
|
|
35
|
+
|
|
36
|
+
// RabbitMQ user credentials
|
|
37
|
+
rabbitmq: z.object({
|
|
38
|
+
username: z.string().min(1),
|
|
39
|
+
password: z.string().min(1),
|
|
40
|
+
vhost: z.string().default('/'),
|
|
41
|
+
}).optional(),
|
|
42
|
+
|
|
43
|
+
// MongoDB credentials (for services that need direct DB access)
|
|
44
|
+
mongo: z.object({
|
|
45
|
+
username: z.string().min(1).optional(),
|
|
46
|
+
password: z.string().min(1).optional(),
|
|
47
|
+
databaseName: z.string().min(1).optional(),
|
|
48
|
+
// Full connection URL (alternative to username/password)
|
|
49
|
+
connectUrl: z.string().min(1).optional(),
|
|
50
|
+
}).optional(),
|
|
51
|
+
|
|
52
|
+
// PostgreSQL credentials (for services that need PostgreSQL access)
|
|
53
|
+
postgresql: z.object({
|
|
54
|
+
/** PostgreSQL host */
|
|
55
|
+
host: z.string().min(1).optional(),
|
|
56
|
+
/** PostgreSQL port (default: 5432) */
|
|
57
|
+
port: z.number().int().default(5432),
|
|
58
|
+
/** Database username */
|
|
59
|
+
username: z.string().min(1).optional(),
|
|
60
|
+
/** Database password */
|
|
61
|
+
password: z.string().min(1).optional(),
|
|
62
|
+
/** Database name */
|
|
63
|
+
databaseName: z.string().min(1).optional(),
|
|
64
|
+
/** Full connection URL (alternative to individual fields) */
|
|
65
|
+
connectUrl: z.string().min(1).optional(),
|
|
66
|
+
}).optional(),
|
|
67
|
+
|
|
68
|
+
// S3/MinIO storage credentials (for services that need storage access)
|
|
69
|
+
storage: z.object({
|
|
70
|
+
accessKey: z.string().min(1),
|
|
71
|
+
secretKey: z.string().min(1),
|
|
72
|
+
bucket: z.string().min(1).optional(),
|
|
73
|
+
}).optional(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export type Platform_Application_Secrets = z.infer<typeof Platform_Application_Secrets_Schema>;
|
|
77
|
+
|
|
78
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Platform_Application_Config_Schema } from "./platform-application-config.schemas";
|
|
3
|
+
import { Platform_Application_Secrets_Schema } from "./platform-application-secrets.schemas";
|
|
4
|
+
|
|
5
|
+
export const AppsManagerStaticConfigurationSchema = z.object({
|
|
6
|
+
githubActionMetaUrl: z.url().optional(),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type AppsManagerStaticConfig = z.infer<typeof AppsManagerStaticConfigurationSchema>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Apps-manager runtime config: base Platform_Application_Config + platformServices from env.
|
|
13
|
+
* Apps-manager is the only service that stores/manages jwtPublicKeys in MongoDB;
|
|
14
|
+
* all other platform services get them via the fetch endpoint.
|
|
15
|
+
*/
|
|
16
|
+
export const AppsManagerConfig_Schema = Platform_Application_Config_Schema.extend({
|
|
17
|
+
platformServices: z.object({
|
|
18
|
+
appsManager: z.url(),
|
|
19
|
+
fileGenerator: z.url(),
|
|
20
|
+
crontabsBatchesManager: z.url(),
|
|
21
|
+
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const AppsManagerSecrets_Schema = Platform_Application_Secrets_Schema.extend({
|
|
26
|
+
mongo: z.object({
|
|
27
|
+
atlas: z.object({
|
|
28
|
+
publicKey: z.string().min(1),
|
|
29
|
+
privateKey: z.string().min(1),
|
|
30
|
+
}).optional(),
|
|
31
|
+
connectUrl: z.url(),
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export type AppsManagerConfig = z.infer<typeof AppsManagerConfig_Schema>;
|
|
36
|
+
export type AppsManagerSecrets = z.infer<typeof AppsManagerSecrets_Schema>;
|
|
37
|
+
|
|
38
|
+
export type AppsManagerAtlasRuntimeConfig = {
|
|
39
|
+
baseUrl: string;
|
|
40
|
+
projectId: string;
|
|
41
|
+
publicKey: string;
|
|
42
|
+
privateKey: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'fs';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import {
|
|
4
|
+
WorkspaceScope,
|
|
5
|
+
WORKSPACE_CONFIG_NAMES,
|
|
6
|
+
resolveGlobalPreferencesPath,
|
|
7
|
+
} from './workspace-scope.schemas';
|
|
8
|
+
import type { WorkspaceScopeResult } from './workspace-scope.schemas';
|
|
9
|
+
|
|
10
|
+
const MAX_WALK_UP_LEVELS = 20;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Resolves the workspace scope from a given working directory.
|
|
14
|
+
*
|
|
15
|
+
* Performs a single upward traversal from `cwd`, checking for config file
|
|
16
|
+
* anchors at each directory level. All found anchors are recorded — the
|
|
17
|
+
* most specific one determines the final scope.
|
|
18
|
+
*
|
|
19
|
+
* After the walk-up, checks for `~/.wildo` to determine global context.
|
|
20
|
+
*
|
|
21
|
+
* @param cwd - Starting directory (defaults to `process.cwd()`)
|
|
22
|
+
* @returns Fully resolved scope result with all discovered paths
|
|
23
|
+
*/
|
|
24
|
+
export function resolveWorkspaceScope(cwd: string = process.cwd()): WorkspaceScopeResult {
|
|
25
|
+
const result: WorkspaceScopeResult = {
|
|
26
|
+
scope: WorkspaceScope.UNINITIALIZED,
|
|
27
|
+
saasConfigPath: null,
|
|
28
|
+
saasRoot: null,
|
|
29
|
+
projectConfigPath: null,
|
|
30
|
+
projectRoot: null,
|
|
31
|
+
frameworkRoot: null,
|
|
32
|
+
globalPreferencesPath: null,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let dir = resolve(cwd);
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < MAX_WALK_UP_LEVELS; i++) {
|
|
38
|
+
if (!result.saasConfigPath) {
|
|
39
|
+
const saasCandidate = join(dir, WORKSPACE_CONFIG_NAMES.SAAS);
|
|
40
|
+
if (existsSync(saasCandidate)) {
|
|
41
|
+
result.saasConfigPath = saasCandidate;
|
|
42
|
+
result.saasRoot = dir;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!result.projectConfigPath) {
|
|
47
|
+
const projectCandidate = join(dir, WORKSPACE_CONFIG_NAMES.PROJECT);
|
|
48
|
+
if (existsSync(projectCandidate)) {
|
|
49
|
+
result.projectConfigPath = projectCandidate;
|
|
50
|
+
result.projectRoot = dir;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!result.frameworkRoot) {
|
|
55
|
+
const frameworkCandidate = join(dir, WORKSPACE_CONFIG_NAMES.FRAMEWORK_DIR);
|
|
56
|
+
if (existsSync(frameworkCandidate) && isDirectory(frameworkCandidate)) {
|
|
57
|
+
result.frameworkRoot = dir;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (result.saasConfigPath && result.projectConfigPath && result.frameworkRoot) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const parent = resolve(dir, '..');
|
|
66
|
+
if (parent === dir) break;
|
|
67
|
+
dir = parent;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const globalPreferencesPath = resolveGlobalPreferencesPath();
|
|
71
|
+
if (existsSync(globalPreferencesPath)) {
|
|
72
|
+
result.globalPreferencesPath = globalPreferencesPath;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
result.scope = computeScope(result);
|
|
76
|
+
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Determines the most specific scope from the resolved anchors.
|
|
82
|
+
* Order: SAAS_APP > PROJECT > FRAMEWORK > GLOBAL > UNINITIALIZED
|
|
83
|
+
*/
|
|
84
|
+
function computeScope(result: WorkspaceScopeResult): WorkspaceScope {
|
|
85
|
+
if (result.saasConfigPath) return WorkspaceScope.SAAS_APP;
|
|
86
|
+
if (result.projectConfigPath) return WorkspaceScope.PROJECT;
|
|
87
|
+
if (result.frameworkRoot) return WorkspaceScope.FRAMEWORK;
|
|
88
|
+
if (result.globalPreferencesPath) return WorkspaceScope.GLOBAL;
|
|
89
|
+
return WorkspaceScope.UNINITIALIZED;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function isDirectory(path: string): boolean {
|
|
93
|
+
try {
|
|
94
|
+
return statSync(path).isDirectory();
|
|
95
|
+
} catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|