Skip to content

Commit 456a0c2

Browse files
committed
feat: registerXrdModel
1 parent 673cff0 commit 456a0c2

File tree

2 files changed

+102
-2
lines changed

2 files changed

+102
-2
lines changed

packages/sdk/src/Model/index.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,79 @@ type Status = {
1313
[key: string]: any
1414
}
1515

16+
// XRD Model Registry types
17+
export interface XrdModelRegistryEntry {
18+
modelClass: typeof Model
19+
group: string
20+
kind: string
21+
}
22+
23+
export interface XrdModelRegistry {
24+
[key: string]: XrdModelRegistryEntry
25+
}
26+
27+
// Global registry for XRD models
28+
const xrdModelRegistry: XrdModelRegistry = {}
29+
30+
/**
31+
* Register an XRD model class with the global registry
32+
* @param group - The API group (e.g., "workspace.fabrique.social.gouv.fr")
33+
* @param kind - The resource kind (e.g., "XRedis")
34+
* @returns Class decorator function
35+
*/
36+
export function registerXrdModel(group: string, kind: string) {
37+
return function <T extends new (...args: any[]) => Model<any>>(target: T): T {
38+
const registryKey = `${group}/${kind}`
39+
40+
xrdModelRegistry[registryKey] = {
41+
modelClass: target as any,
42+
group,
43+
kind,
44+
}
45+
46+
return target
47+
}
48+
}
49+
50+
/**
51+
* Get a registered XRD model class by group and kind
52+
* @param group - The API group
53+
* @param kind - The resource kind
54+
* @returns The registered model class or undefined if not found
55+
*/
56+
export function getRegisteredXrdModel(group: string, kind: string): typeof Model | undefined {
57+
const registryKey = `${group}/${kind}`
58+
return xrdModelRegistry[registryKey]?.modelClass
59+
}
60+
61+
/**
62+
* Get a registered XRD model class by apiVersion and kind
63+
* @param apiVersion - The full API version (e.g., "workspace.fabrique.social.gouv.fr/v1alpha1")
64+
* @param kind - The resource kind
65+
* @returns The registered model class or undefined if not found
66+
*/
67+
export function getRegisteredXrdModelByApiVersion(
68+
apiVersion: string,
69+
kind: string
70+
): typeof Model | undefined {
71+
// Extract group from apiVersion
72+
// If no '/' is present, use "core" as convention for core resources
73+
const group = apiVersion.includes("/") ? apiVersion.split("/")[0] : "core"
74+
return getRegisteredXrdModel(group, kind)
75+
}
76+
77+
/**
78+
* Get all registered XRD models
79+
* @returns The complete registry
80+
*/
81+
export function getXrdModelRegistry(): XrdModelRegistry {
82+
return { ...xrdModelRegistry }
83+
}
84+
1685
export class Model<T> extends BaseModel<T> {
1786
getMetadata(): IObjectMeta {
1887
const self = this as any
19-
if (!self.metadatata) {
88+
if (!self.metadata) {
2089
throw new Error("No metadata found")
2190
}
2291
return self.metadata

packages/server/src/executor.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fs from "fs"
22

33
import { createLogger } from "@crossplane-js/libs"
4+
import { getRegisteredXrdModelByApiVersion } from "@crossplane-js/sdk"
45

56
import type { NodeResponse, NodeError, FunctionInput } from "./types"
67

@@ -68,7 +69,37 @@ export async function executeCode(
6869

6970
let result
7071
try {
71-
result = await module.default(input)
72+
let composite: any = input
73+
74+
// Try to instantiate using registered XRD model if available
75+
try {
76+
const inputData = input as any
77+
const compositeResource = inputData?.observed?.composite?.resource
78+
79+
if (compositeResource?.apiVersion && compositeResource?.kind) {
80+
const RegisteredModelClass = getRegisteredXrdModelByApiVersion(
81+
compositeResource.apiVersion,
82+
compositeResource.kind
83+
)
84+
85+
if (RegisteredModelClass) {
86+
moduleLogger.debug(`Using registered XRD model for ${compositeResource.kind}`)
87+
composite = new RegisteredModelClass(compositeResource)
88+
} else {
89+
moduleLogger.debug(
90+
`No registered XRD model found for ${compositeResource.kind}, using raw input`
91+
)
92+
}
93+
}
94+
} catch (modelErr) {
95+
moduleLogger.debug(
96+
`Failed to instantiate XRD model, falling back to raw input: ${(modelErr as Error).message}`
97+
)
98+
// Fall back to raw input if model instantiation fails
99+
composite = input
100+
}
101+
102+
result = await module.default(composite)
72103
moduleLogger.debug("Function execution completed")
73104
} catch (execErr) {
74105
moduleLogger.error(`Error during function execution: ${(execErr as Error).message}`)

0 commit comments

Comments
 (0)