@navios/adapter-xml 0.1.0 → 0.7.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.
- package/CHANGELOG.md +29 -0
- package/README.md +2 -1
- package/bun-plugin.mts +5 -3
- package/bunPlugin.cache +1 -1
- package/dist/bun-plugin.d.mts.map +1 -1
- package/dist/src/adapters/xml-stream-adapter.service.d.mts +63 -8
- package/dist/src/adapters/xml-stream-adapter.service.d.mts.map +1 -1
- package/dist/src/decorators/component.decorator.d.mts +68 -2
- package/dist/src/decorators/component.decorator.d.mts.map +1 -1
- package/dist/src/decorators/xml-stream.decorator.d.mts +58 -3
- package/dist/src/decorators/xml-stream.decorator.d.mts.map +1 -1
- package/dist/src/define-environment.d.mts +2 -2
- package/dist/src/define-environment.d.mts.map +1 -1
- package/dist/src/handlers/xml-stream.d.mts +25 -3
- package/dist/src/handlers/xml-stream.d.mts.map +1 -1
- package/dist/src/runtime/render-to-xml.d.mts +70 -2
- package/dist/src/runtime/render-to-xml.d.mts.map +1 -1
- package/dist/src/tags/define-tag.d.mts +8 -0
- package/dist/src/tags/define-tag.d.mts.map +1 -1
- package/dist/src/types/component.d.mts +46 -2
- package/dist/src/types/component.d.mts.map +1 -1
- package/dist/src/types/config.d.mts +22 -0
- package/dist/src/types/config.d.mts.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/tsconfig.spec.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsdown.config.d.mts +3 -0
- package/dist/tsdown.config.d.mts.map +1 -0
- package/dist/vitest.e2e.fastify.config.d.mts.map +1 -1
- package/lib/create-element--Gd2L8UR.d.cts +26 -0
- package/lib/create-element--Gd2L8UR.d.cts.map +1 -0
- package/lib/create-element-61MP7_99.d.mts +26 -0
- package/lib/create-element-61MP7_99.d.mts.map +1 -0
- package/lib/create-element-CTOxv6Df.cjs +183 -0
- package/lib/create-element-CTOxv6Df.cjs.map +1 -0
- package/lib/create-element-NZEYaRw5.mjs +124 -0
- package/lib/create-element-NZEYaRw5.mjs.map +1 -0
- package/lib/index.cjs +746 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +520 -0
- package/lib/index.d.cts.map +1 -0
- package/lib/index.d.mts +520 -29
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +692 -223
- package/lib/index.mjs.map +1 -1
- package/lib/jsx-dev-runtime.cjs +11 -0
- package/lib/jsx-dev-runtime.cjs.map +1 -0
- package/lib/jsx-dev-runtime.d.cts +8 -0
- package/lib/jsx-dev-runtime.d.cts.map +1 -0
- package/lib/jsx-dev-runtime.d.mts +8 -4
- package/lib/jsx-dev-runtime.d.mts.map +1 -0
- package/lib/jsx-dev-runtime.mjs +5 -6
- package/lib/jsx-dev-runtime.mjs.map +1 -1
- package/lib/jsx-runtime.cjs +5 -0
- package/lib/jsx-runtime.d.cts +3 -0
- package/lib/jsx-runtime.d.mts +3 -3
- package/lib/jsx-runtime.mjs +3 -3
- package/lib/jsx.cjs +0 -0
- package/lib/jsx.d.cts +19 -0
- package/lib/jsx.d.cts.map +1 -0
- package/lib/jsx.d.mts +19 -1
- package/lib/jsx.d.mts.map +1 -0
- package/lib/jsx.mjs +1 -3
- package/lib/xml-node-BQA44ydQ.d.mts +96 -0
- package/lib/xml-node-BQA44ydQ.d.mts.map +1 -0
- package/lib/xml-node-CddziLym.d.cts +96 -0
- package/lib/xml-node-CddziLym.d.cts.map +1 -0
- package/package.json +9 -9
- package/project.json +2 -2
- package/src/adapters/xml-stream-adapter.service.mts +77 -16
- package/src/decorators/component.decorator.mts +72 -10
- package/src/decorators/component.decorator.spec.mts +40 -22
- package/src/decorators/xml-stream.decorator.mts +58 -3
- package/src/define-environment.mts +5 -6
- package/src/handlers/xml-stream.mts +25 -3
- package/src/runtime/render-to-xml.mts +72 -4
- package/src/tags/define-tag.mts +8 -0
- package/src/types/component.mts +46 -2
- package/src/types/config.mts +22 -0
- package/tsdown.config.mts +39 -0
- package/lib/_tsup-dts-rollup.d.mts +0 -414
- package/lib/_tsup-dts-rollup.d.ts +0 -414
- package/lib/chunk-6OR6LGJA.mjs +0 -153
- package/lib/chunk-6OR6LGJA.mjs.map +0 -1
- package/lib/index.d.ts +0 -29
- package/lib/index.js +0 -376
- package/lib/index.js.map +0 -1
- package/lib/jsx-dev-runtime.d.ts +0 -4
- package/lib/jsx-dev-runtime.js +0 -61
- package/lib/jsx-dev-runtime.js.map +0 -1
- package/lib/jsx-runtime.d.ts +0 -3
- package/lib/jsx-runtime.js +0 -57
- package/lib/jsx-runtime.js.map +0 -1
- package/lib/jsx-runtime.mjs.map +0 -1
- package/lib/jsx.d.ts +0 -1
- package/lib/jsx.js +0 -4
- package/lib/jsx.js.map +0 -1
- package/lib/jsx.mjs.map +0 -1
- package/tsup.config.mts +0 -18
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
const require_create_element = require('./create-element-CTOxv6Df.cjs');
|
|
2
|
+
let __navios_core = require("@navios/core");
|
|
3
|
+
|
|
4
|
+
//#region src/runtime/special-nodes.mts
|
|
5
|
+
/**
|
|
6
|
+
* CDATA component - wraps content in <![CDATA[...]]>
|
|
7
|
+
* Use for text content that may contain characters like < > &
|
|
8
|
+
* that would otherwise need escaping.
|
|
9
|
+
*
|
|
10
|
+
* Note: If content contains "]]>", it will be split into multiple CDATA sections.
|
|
11
|
+
*/
|
|
12
|
+
function CData({ children }) {
|
|
13
|
+
return {
|
|
14
|
+
type: require_create_element.CDataSymbol,
|
|
15
|
+
content: String(children)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* DangerouslyInsertRawXml - inserts raw XML/HTML without any escaping or wrapping
|
|
20
|
+
*
|
|
21
|
+
* WARNING: This bypasses all XML escaping. Only use with trusted content!
|
|
22
|
+
* Use cases:
|
|
23
|
+
* - Pre-rendered XML fragments
|
|
24
|
+
* - HTML content in RSS/Atom feeds (in description/content:encoded)
|
|
25
|
+
* - Including XML from external sources that's already valid
|
|
26
|
+
*/
|
|
27
|
+
function DangerouslyInsertRawXml({ children }) {
|
|
28
|
+
return {
|
|
29
|
+
type: require_create_element.RawXmlSymbol,
|
|
30
|
+
content: String(children)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/runtime/render-to-xml.mts
|
|
36
|
+
/**
|
|
37
|
+
* Error thrown when attempting to render a class component without a container.
|
|
38
|
+
*
|
|
39
|
+
* Class components require a dependency injection container to be instantiated.
|
|
40
|
+
* This error is thrown when `renderToXml` is called with a class component in
|
|
41
|
+
* the tree but no container is provided in the options.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* try {
|
|
46
|
+
* await renderToXml(<MyClassComponent />)
|
|
47
|
+
* } catch (error) {
|
|
48
|
+
* if (error instanceof MissingContainerError) {
|
|
49
|
+
* // Provide a container
|
|
50
|
+
* await renderToXml(<MyClassComponent />, { container })
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/ var MissingContainerError = class extends Error {
|
|
55
|
+
constructor(componentName) {
|
|
56
|
+
super(`[@navios/adapter-xml] Cannot render class component "${componentName}" without a container. Pass a container to renderToXml options: renderToXml(node, { container })`);
|
|
57
|
+
this.name = "MissingContainerError";
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Renders a JSX XML node tree to an XML string.
|
|
62
|
+
*
|
|
63
|
+
* This function handles:
|
|
64
|
+
* - Regular XML nodes (tags with props and children)
|
|
65
|
+
* - Async components (resolves promises in parallel)
|
|
66
|
+
* - Class components (resolves via DI container)
|
|
67
|
+
* - CDATA sections
|
|
68
|
+
* - Raw XML content
|
|
69
|
+
* - Fragments
|
|
70
|
+
* - Text content with proper escaping
|
|
71
|
+
*
|
|
72
|
+
* @param node - The root XML node (JSX element) to render.
|
|
73
|
+
* @param options - Rendering options including declaration, encoding, pretty printing, and container.
|
|
74
|
+
* @returns A promise that resolves to the XML string.
|
|
75
|
+
*
|
|
76
|
+
* @throws {MissingContainerError} If the tree contains class components but no container is provided.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* // Simple rendering
|
|
81
|
+
* const xml = await renderToXml(<rss version="2.0"><channel>...</channel></rss>)
|
|
82
|
+
*
|
|
83
|
+
* // With options
|
|
84
|
+
* const xml = await renderToXml(<feed>...</feed>, {
|
|
85
|
+
* declaration: true,
|
|
86
|
+
* encoding: 'UTF-8',
|
|
87
|
+
* pretty: true,
|
|
88
|
+
* })
|
|
89
|
+
*
|
|
90
|
+
* // With class components (requires container)
|
|
91
|
+
* const container = new Container()
|
|
92
|
+
* container.beginRequest('request-id')
|
|
93
|
+
* const xml = await renderToXml(<MyClassComponent />, { container })
|
|
94
|
+
* ```
|
|
95
|
+
*/ async function renderToXml(node, options = {}) {
|
|
96
|
+
const { declaration = true, encoding = "UTF-8", pretty = false, container } = options;
|
|
97
|
+
let xml = "";
|
|
98
|
+
if (declaration) {
|
|
99
|
+
xml += `<?xml version="1.0" encoding="${encoding}"?>`;
|
|
100
|
+
if (pretty) xml += "\n";
|
|
101
|
+
}
|
|
102
|
+
xml += await renderNode(node, pretty ? 0 : -1, container);
|
|
103
|
+
return xml;
|
|
104
|
+
}
|
|
105
|
+
async function renderNode(node, indent, container) {
|
|
106
|
+
if (node == null) return "";
|
|
107
|
+
if (typeof node === "string") return escapeXml(node);
|
|
108
|
+
if (typeof node === "number") return String(node);
|
|
109
|
+
if (isClassComponentNode(node)) {
|
|
110
|
+
if (!container) throw new MissingContainerError(node.componentClass.name);
|
|
111
|
+
const result = (await container.get(node.componentClass, node.props)).render();
|
|
112
|
+
return renderNode(result instanceof Promise ? await result : result, indent, container);
|
|
113
|
+
}
|
|
114
|
+
if (isAsyncNode(node)) return renderNode(await node.promise, indent, container);
|
|
115
|
+
if (isCDataNode(node)) return renderCData(node.content);
|
|
116
|
+
if (isRawXmlNode(node)) return node.content;
|
|
117
|
+
const { type, props, children } = node;
|
|
118
|
+
if (type === require_create_element.Fragment) return (await Promise.all(children.filter((c) => c != null).map((c) => renderNode(c, indent, container)))).join("");
|
|
119
|
+
const prefix = indent >= 0 ? " ".repeat(indent) : "";
|
|
120
|
+
const newline = indent >= 0 ? "\n" : "";
|
|
121
|
+
const attrs = Object.entries(props).filter(([_, v]) => v != null).map(([k, v]) => ` ${k}="${escapeAttr(String(v))}"`).join("");
|
|
122
|
+
if (children.length === 0) return `${prefix}<${type}${attrs}/>${newline}`;
|
|
123
|
+
const childIndent = indent >= 0 ? indent + 1 : -1;
|
|
124
|
+
const childContent = (await Promise.all(children.filter((c) => c != null).map((c) => renderNode(c, childIndent, container)))).join("");
|
|
125
|
+
if (children.every((c) => typeof c === "string" || typeof c === "number" || isCDataNode(c) || isRawXmlNode(c))) return `${prefix}<${type}${attrs}>${childContent}</${type}>${newline}`;
|
|
126
|
+
return `${prefix}<${type}${attrs}>${newline}${childContent}${prefix}</${type}>${newline}`;
|
|
127
|
+
}
|
|
128
|
+
function isClassComponentNode(node) {
|
|
129
|
+
return node !== null && typeof node === "object" && "type" in node && node.type === require_create_element.ClassComponent;
|
|
130
|
+
}
|
|
131
|
+
function isAsyncNode(node) {
|
|
132
|
+
return node !== null && typeof node === "object" && "type" in node && node.type === require_create_element.AsyncComponent;
|
|
133
|
+
}
|
|
134
|
+
function isCDataNode(node) {
|
|
135
|
+
return node && typeof node === "object" && node.type === require_create_element.CDataSymbol;
|
|
136
|
+
}
|
|
137
|
+
function isRawXmlNode(node) {
|
|
138
|
+
return node && typeof node === "object" && node.type === require_create_element.RawXmlSymbol;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Renders content as CDATA section.
|
|
142
|
+
* If content contains "]]>", splits into multiple CDATA sections.
|
|
143
|
+
* The technique is to end the CDATA section before ]]>, then start a new one.
|
|
144
|
+
*/ function renderCData(content) {
|
|
145
|
+
if (content.includes("]]>")) return `<![CDATA[${content.replace(/]]>/g, "]]]]><![CDATA[>")}]]>`;
|
|
146
|
+
return `<![CDATA[${content}]]>`;
|
|
147
|
+
}
|
|
148
|
+
function escapeXml(str) {
|
|
149
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
150
|
+
}
|
|
151
|
+
function escapeAttr(str) {
|
|
152
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/tags/define-tag.mts
|
|
157
|
+
/**
|
|
158
|
+
* Creates a type-safe XML tag component with optional Zod schema validation.
|
|
159
|
+
*
|
|
160
|
+
* @param name - The tag name (supports namespace prefixes like 'atom:link')
|
|
161
|
+
* @param propsSchema - Optional Zod schema for validating props
|
|
162
|
+
* @returns A component function that can be used in JSX
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```tsx
|
|
166
|
+
* // Simple tag
|
|
167
|
+
* const item = defineTag('item')
|
|
168
|
+
* <item>Content</item>
|
|
169
|
+
*
|
|
170
|
+
* // Namespaced tag with Zod validation
|
|
171
|
+
* const atomLink = defineTag('atom:link', z.object({
|
|
172
|
+
* href: z.string().url(),
|
|
173
|
+
* rel: z.enum(['self', 'alternate']),
|
|
174
|
+
* type: z.string().optional(),
|
|
175
|
+
* }))
|
|
176
|
+
* <atomLink href="https://example.com/feed" rel="self" />
|
|
177
|
+
* ```
|
|
178
|
+
*/ function defineTag(name, propsSchema) {
|
|
179
|
+
const component = (props) => {
|
|
180
|
+
const { children, ...rest } = props ?? {};
|
|
181
|
+
if (propsSchema) propsSchema.parse(rest);
|
|
182
|
+
return {
|
|
183
|
+
type: name,
|
|
184
|
+
props: rest,
|
|
185
|
+
children: Array.isArray(children) ? children : children ? [children] : []
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
component.tagName = name;
|
|
189
|
+
return component;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/decorators/xml-stream.decorator.mts
|
|
194
|
+
/**
|
|
195
|
+
* Decorator for XML Stream endpoints that return JSX-based XML responses.
|
|
196
|
+
*
|
|
197
|
+
* This decorator marks controller methods that return JSX elements, which will be
|
|
198
|
+
* automatically rendered to XML and sent with the appropriate Content-Type header.
|
|
199
|
+
* The method can be async and can contain async components, class components, and
|
|
200
|
+
* regular JSX elements.
|
|
201
|
+
*
|
|
202
|
+
* @template Method - The HTTP method (GET, POST, etc.).
|
|
203
|
+
* @template Url - The URL path pattern (supports parameters like `/posts/:id`).
|
|
204
|
+
* @template QuerySchema - Optional Zod schema for query parameter validation.
|
|
205
|
+
* @template RequestSchema - Optional Zod schema for request body validation.
|
|
206
|
+
*
|
|
207
|
+
* @param endpoint - The endpoint declaration created with `declareXmlStream`.
|
|
208
|
+
* @returns A method decorator function.
|
|
209
|
+
*
|
|
210
|
+
* @throws {Error} If used on a non-function or non-method.
|
|
211
|
+
* @throws {Error} If the endpoint URL already exists.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* import { XmlStream, declareXmlStream } from '@navios/adapter-xml'
|
|
216
|
+
* import { Controller } from '@navios/core'
|
|
217
|
+
*
|
|
218
|
+
* const getRssFeed = declareXmlStream({
|
|
219
|
+
* method: 'GET',
|
|
220
|
+
* url: '/feed.xml',
|
|
221
|
+
* contentType: 'application/rss+xml',
|
|
222
|
+
* })
|
|
223
|
+
*
|
|
224
|
+
* @Controller('/api')
|
|
225
|
+
* class FeedController {
|
|
226
|
+
* @XmlStream(getRssFeed)
|
|
227
|
+
* async getFeed() {
|
|
228
|
+
* return (
|
|
229
|
+
* <rss version="2.0">
|
|
230
|
+
* <channel>
|
|
231
|
+
* <title>My Feed</title>
|
|
232
|
+
* </channel>
|
|
233
|
+
* </rss>
|
|
234
|
+
* )
|
|
235
|
+
* }
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* // With query parameters
|
|
242
|
+
* const getSitemap = declareXmlStream({
|
|
243
|
+
* method: 'GET',
|
|
244
|
+
* url: '/sitemap.xml',
|
|
245
|
+
* querySchema: z.object({ page: z.string().optional() }),
|
|
246
|
+
* })
|
|
247
|
+
*
|
|
248
|
+
* @Controller()
|
|
249
|
+
* class SitemapController {
|
|
250
|
+
* @XmlStream(getSitemap)
|
|
251
|
+
* async getSitemap(params: { query?: { page?: string } }) {
|
|
252
|
+
* const page = params.query?.page
|
|
253
|
+
* return <urlset>...</urlset>
|
|
254
|
+
* }
|
|
255
|
+
* }
|
|
256
|
+
* ```
|
|
257
|
+
*/ function XmlStream(endpoint) {
|
|
258
|
+
return (target, context) => {
|
|
259
|
+
if (typeof target !== "function") throw new Error("[Navios] XmlStream decorator can only be used on functions.");
|
|
260
|
+
if (context.kind !== "method") throw new Error("[Navios] XmlStream decorator can only be used on methods.");
|
|
261
|
+
const config = endpoint.config;
|
|
262
|
+
if (context.metadata) {
|
|
263
|
+
const endpointMetadata = (0, __navios_core.getEndpointMetadata)(target, context);
|
|
264
|
+
if (endpointMetadata.config && endpointMetadata.config.url) throw new Error(`[Navios] Endpoint ${config.method} ${config.url} already exists.`);
|
|
265
|
+
endpointMetadata.config = config;
|
|
266
|
+
endpointMetadata.adapterToken = __navios_core.XmlStreamAdapterToken;
|
|
267
|
+
endpointMetadata.classMethod = target.name;
|
|
268
|
+
endpointMetadata.httpMethod = config.method;
|
|
269
|
+
endpointMetadata.url = config.url;
|
|
270
|
+
}
|
|
271
|
+
return target;
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/handlers/xml-stream.mts
|
|
277
|
+
/**
|
|
278
|
+
* Declares an XML Stream endpoint configuration for use with `@XmlStream` decorator.
|
|
279
|
+
*
|
|
280
|
+
* This function creates an endpoint declaration that can be used with the `@XmlStream`
|
|
281
|
+
* decorator to mark controller methods that return JSX-based XML responses.
|
|
282
|
+
*
|
|
283
|
+
* @template Method - The HTTP method (GET, POST, etc.).
|
|
284
|
+
* @template Url - The URL path pattern (supports parameters like `/posts/:id`).
|
|
285
|
+
* @template QuerySchema - Optional Zod schema for query parameter validation.
|
|
286
|
+
* @template RequestSchema - Optional Zod schema for request body validation.
|
|
287
|
+
*
|
|
288
|
+
* @param config - The endpoint configuration including method, URL, schemas, and XML options.
|
|
289
|
+
* @returns An endpoint declaration object to be used with `@XmlStream` decorator.
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* import { declareXmlStream } from '@navios/adapter-xml'
|
|
294
|
+
* import { z } from 'zod/v4'
|
|
295
|
+
*
|
|
296
|
+
* // Simple endpoint
|
|
297
|
+
* export const getRssFeed = declareXmlStream({
|
|
298
|
+
* method: 'GET',
|
|
299
|
+
* url: '/feed.xml',
|
|
300
|
+
* contentType: 'application/rss+xml',
|
|
301
|
+
* })
|
|
302
|
+
*
|
|
303
|
+
* // With query parameters
|
|
304
|
+
* export const getSitemap = declareXmlStream({
|
|
305
|
+
* method: 'GET',
|
|
306
|
+
* url: '/sitemap.xml',
|
|
307
|
+
* querySchema: z.object({
|
|
308
|
+
* page: z.string().optional(),
|
|
309
|
+
* }),
|
|
310
|
+
* contentType: 'application/xml',
|
|
311
|
+
* xmlDeclaration: true,
|
|
312
|
+
* encoding: 'UTF-8',
|
|
313
|
+
* })
|
|
314
|
+
* ```
|
|
315
|
+
*/ function declareXmlStream(config) {
|
|
316
|
+
return { config };
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region src/adapters/xml-stream-adapter.service.mts
|
|
321
|
+
function applyDecs2203RFactory() {
|
|
322
|
+
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
323
|
+
return function addInitializer(initializer) {
|
|
324
|
+
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
325
|
+
assertCallable(initializer, "An initializer");
|
|
326
|
+
initializers.push(initializer);
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
|
|
330
|
+
var kindStr;
|
|
331
|
+
switch (kind) {
|
|
332
|
+
case 1:
|
|
333
|
+
kindStr = "accessor";
|
|
334
|
+
break;
|
|
335
|
+
case 2:
|
|
336
|
+
kindStr = "method";
|
|
337
|
+
break;
|
|
338
|
+
case 3:
|
|
339
|
+
kindStr = "getter";
|
|
340
|
+
break;
|
|
341
|
+
case 4:
|
|
342
|
+
kindStr = "setter";
|
|
343
|
+
break;
|
|
344
|
+
default: kindStr = "field";
|
|
345
|
+
}
|
|
346
|
+
var ctx = {
|
|
347
|
+
kind: kindStr,
|
|
348
|
+
name: isPrivate ? "#" + name : name,
|
|
349
|
+
static: isStatic,
|
|
350
|
+
private: isPrivate,
|
|
351
|
+
metadata
|
|
352
|
+
};
|
|
353
|
+
var decoratorFinishedRef = { v: false };
|
|
354
|
+
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
355
|
+
var get, set;
|
|
356
|
+
if (kind === 0) if (isPrivate) {
|
|
357
|
+
get = desc.get;
|
|
358
|
+
set = desc.set;
|
|
359
|
+
} else {
|
|
360
|
+
get = function() {
|
|
361
|
+
return this[name];
|
|
362
|
+
};
|
|
363
|
+
set = function(v) {
|
|
364
|
+
this[name] = v;
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
else if (kind === 2) get = function() {
|
|
368
|
+
return desc.value;
|
|
369
|
+
};
|
|
370
|
+
else {
|
|
371
|
+
if (kind === 1 || kind === 3) get = function() {
|
|
372
|
+
return desc.get.call(this);
|
|
373
|
+
};
|
|
374
|
+
if (kind === 1 || kind === 4) set = function(v) {
|
|
375
|
+
desc.set.call(this, v);
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
ctx.access = get && set ? {
|
|
379
|
+
get,
|
|
380
|
+
set
|
|
381
|
+
} : get ? { get } : { set };
|
|
382
|
+
try {
|
|
383
|
+
return dec(value, ctx);
|
|
384
|
+
} finally {
|
|
385
|
+
decoratorFinishedRef.v = true;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function assertNotFinished(decoratorFinishedRef, fnName) {
|
|
389
|
+
if (decoratorFinishedRef.v) throw new Error("attempted to call " + fnName + " after decoration was finished");
|
|
390
|
+
}
|
|
391
|
+
function assertCallable(fn, hint) {
|
|
392
|
+
if (typeof fn !== "function") throw new TypeError(hint + " must be a function");
|
|
393
|
+
}
|
|
394
|
+
function assertValidReturnValue(kind, value) {
|
|
395
|
+
var type = typeof value;
|
|
396
|
+
if (kind === 1) {
|
|
397
|
+
if (type !== "object" || value === null) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
398
|
+
if (value.get !== void 0) assertCallable(value.get, "accessor.get");
|
|
399
|
+
if (value.set !== void 0) assertCallable(value.set, "accessor.set");
|
|
400
|
+
if (value.init !== void 0) assertCallable(value.init, "accessor.init");
|
|
401
|
+
} else if (type !== "function") {
|
|
402
|
+
var hint;
|
|
403
|
+
if (kind === 0) hint = "field";
|
|
404
|
+
else if (kind === 10) hint = "class";
|
|
405
|
+
else hint = "method";
|
|
406
|
+
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
|
|
410
|
+
var decs = decInfo[0];
|
|
411
|
+
var desc, init, value;
|
|
412
|
+
if (isPrivate) if (kind === 0 || kind === 1) desc = {
|
|
413
|
+
get: decInfo[3],
|
|
414
|
+
set: decInfo[4]
|
|
415
|
+
};
|
|
416
|
+
else if (kind === 3) desc = { get: decInfo[3] };
|
|
417
|
+
else if (kind === 4) desc = { set: decInfo[3] };
|
|
418
|
+
else desc = { value: decInfo[3] };
|
|
419
|
+
else if (kind !== 0) desc = Object.getOwnPropertyDescriptor(base, name);
|
|
420
|
+
if (kind === 1) value = {
|
|
421
|
+
get: desc.get,
|
|
422
|
+
set: desc.set
|
|
423
|
+
};
|
|
424
|
+
else if (kind === 2) value = desc.value;
|
|
425
|
+
else if (kind === 3) value = desc.get;
|
|
426
|
+
else if (kind === 4) value = desc.set;
|
|
427
|
+
var newValue, get, set;
|
|
428
|
+
if (typeof decs === "function") {
|
|
429
|
+
newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
430
|
+
if (newValue !== void 0) {
|
|
431
|
+
assertValidReturnValue(kind, newValue);
|
|
432
|
+
if (kind === 0) init = newValue;
|
|
433
|
+
else if (kind === 1) {
|
|
434
|
+
init = newValue.init;
|
|
435
|
+
get = newValue.get || value.get;
|
|
436
|
+
set = newValue.set || value.set;
|
|
437
|
+
value = {
|
|
438
|
+
get,
|
|
439
|
+
set
|
|
440
|
+
};
|
|
441
|
+
} else value = newValue;
|
|
442
|
+
}
|
|
443
|
+
} else for (var i = decs.length - 1; i >= 0; i--) {
|
|
444
|
+
var dec = decs[i];
|
|
445
|
+
newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
446
|
+
if (newValue !== void 0) {
|
|
447
|
+
assertValidReturnValue(kind, newValue);
|
|
448
|
+
var newInit;
|
|
449
|
+
if (kind === 0) newInit = newValue;
|
|
450
|
+
else if (kind === 1) {
|
|
451
|
+
newInit = newValue.init;
|
|
452
|
+
get = newValue.get || value.get;
|
|
453
|
+
set = newValue.set || value.set;
|
|
454
|
+
value = {
|
|
455
|
+
get,
|
|
456
|
+
set
|
|
457
|
+
};
|
|
458
|
+
} else value = newValue;
|
|
459
|
+
if (newInit !== void 0) if (init === void 0) init = newInit;
|
|
460
|
+
else if (typeof init === "function") init = [init, newInit];
|
|
461
|
+
else init.push(newInit);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (kind === 0 || kind === 1) {
|
|
465
|
+
if (init === void 0) init = function(instance, init$1) {
|
|
466
|
+
return init$1;
|
|
467
|
+
};
|
|
468
|
+
else if (typeof init !== "function") {
|
|
469
|
+
var ownInitializers = init;
|
|
470
|
+
init = function(instance, init$1) {
|
|
471
|
+
var value$1 = init$1;
|
|
472
|
+
for (var i$1 = 0; i$1 < ownInitializers.length; i$1++) value$1 = ownInitializers[i$1].call(instance, value$1);
|
|
473
|
+
return value$1;
|
|
474
|
+
};
|
|
475
|
+
} else {
|
|
476
|
+
var originalInitializer = init;
|
|
477
|
+
init = function(instance, init$1) {
|
|
478
|
+
return originalInitializer.call(instance, init$1);
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
ret.push(init);
|
|
482
|
+
}
|
|
483
|
+
if (kind !== 0) {
|
|
484
|
+
if (kind === 1) {
|
|
485
|
+
desc.get = value.get;
|
|
486
|
+
desc.set = value.set;
|
|
487
|
+
} else if (kind === 2) desc.value = value;
|
|
488
|
+
else if (kind === 3) desc.get = value;
|
|
489
|
+
else if (kind === 4) desc.set = value;
|
|
490
|
+
if (isPrivate) if (kind === 1) {
|
|
491
|
+
ret.push(function(instance, args) {
|
|
492
|
+
return value.get.call(instance, args);
|
|
493
|
+
});
|
|
494
|
+
ret.push(function(instance, args) {
|
|
495
|
+
return value.set.call(instance, args);
|
|
496
|
+
});
|
|
497
|
+
} else if (kind === 2) ret.push(value);
|
|
498
|
+
else ret.push(function(instance, args) {
|
|
499
|
+
return value.call(instance, args);
|
|
500
|
+
});
|
|
501
|
+
else Object.defineProperty(base, name, desc);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function applyMemberDecs(Class, decInfos, metadata) {
|
|
505
|
+
var ret = [];
|
|
506
|
+
var protoInitializers;
|
|
507
|
+
var staticInitializers;
|
|
508
|
+
var existingProtoNonFields = /* @__PURE__ */ new Map();
|
|
509
|
+
var existingStaticNonFields = /* @__PURE__ */ new Map();
|
|
510
|
+
for (var i = 0; i < decInfos.length; i++) {
|
|
511
|
+
var decInfo = decInfos[i];
|
|
512
|
+
if (!Array.isArray(decInfo)) continue;
|
|
513
|
+
var kind = decInfo[1];
|
|
514
|
+
var name = decInfo[2];
|
|
515
|
+
var isPrivate = decInfo.length > 3;
|
|
516
|
+
var isStatic = kind >= 5;
|
|
517
|
+
var base;
|
|
518
|
+
var initializers;
|
|
519
|
+
if (isStatic) {
|
|
520
|
+
base = Class;
|
|
521
|
+
kind = kind - 5;
|
|
522
|
+
staticInitializers = staticInitializers || [];
|
|
523
|
+
initializers = staticInitializers;
|
|
524
|
+
} else {
|
|
525
|
+
base = Class.prototype;
|
|
526
|
+
protoInitializers = protoInitializers || [];
|
|
527
|
+
initializers = protoInitializers;
|
|
528
|
+
}
|
|
529
|
+
if (kind !== 0 && !isPrivate) {
|
|
530
|
+
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
531
|
+
var existingKind = existingNonFields.get(name) || 0;
|
|
532
|
+
if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
533
|
+
else if (!existingKind && kind > 2) existingNonFields.set(name, kind);
|
|
534
|
+
else existingNonFields.set(name, true);
|
|
535
|
+
}
|
|
536
|
+
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
537
|
+
}
|
|
538
|
+
pushInitializers(ret, protoInitializers);
|
|
539
|
+
pushInitializers(ret, staticInitializers);
|
|
540
|
+
return ret;
|
|
541
|
+
}
|
|
542
|
+
function pushInitializers(ret, initializers) {
|
|
543
|
+
if (initializers) ret.push(function(instance) {
|
|
544
|
+
for (var i = 0; i < initializers.length; i++) initializers[i].call(instance);
|
|
545
|
+
return instance;
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
function applyClassDecs(targetClass, classDecs, metadata) {
|
|
549
|
+
if (classDecs.length > 0) {
|
|
550
|
+
var initializers = [];
|
|
551
|
+
var newClass = targetClass;
|
|
552
|
+
var name = targetClass.name;
|
|
553
|
+
for (var i = classDecs.length - 1; i >= 0; i--) {
|
|
554
|
+
var decoratorFinishedRef = { v: false };
|
|
555
|
+
try {
|
|
556
|
+
var nextNewClass = classDecs[i](newClass, {
|
|
557
|
+
kind: "class",
|
|
558
|
+
name,
|
|
559
|
+
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
560
|
+
metadata
|
|
561
|
+
});
|
|
562
|
+
} finally {
|
|
563
|
+
decoratorFinishedRef.v = true;
|
|
564
|
+
}
|
|
565
|
+
if (nextNewClass !== void 0) {
|
|
566
|
+
assertValidReturnValue(10, nextNewClass);
|
|
567
|
+
newClass = nextNewClass;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return [defineMetadata(newClass, metadata), function() {
|
|
571
|
+
for (var i$1 = 0; i$1 < initializers.length; i$1++) initializers[i$1].call(newClass);
|
|
572
|
+
}];
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function defineMetadata(Class, metadata) {
|
|
576
|
+
return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
|
|
577
|
+
configurable: true,
|
|
578
|
+
enumerable: true,
|
|
579
|
+
value: metadata
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
|
|
583
|
+
if (parentClass !== void 0) var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
|
|
584
|
+
var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
|
|
585
|
+
var e = applyMemberDecs(targetClass, memberDecs, metadata);
|
|
586
|
+
if (!classDecs.length) defineMetadata(targetClass, metadata);
|
|
587
|
+
return {
|
|
588
|
+
e,
|
|
589
|
+
get c() {
|
|
590
|
+
return applyClassDecs(targetClass, classDecs, metadata);
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
596
|
+
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
597
|
+
}
|
|
598
|
+
var _dec, _initClass;
|
|
599
|
+
let _XmlStreamAdapterService;
|
|
600
|
+
_dec = (0, __navios_core.Injectable)({ token: __navios_core.XmlStreamAdapterToken });
|
|
601
|
+
var XmlStreamAdapterService = class {
|
|
602
|
+
static {
|
|
603
|
+
({c: [_XmlStreamAdapterService, _initClass]} = _apply_decs_2203_r(this, [], [_dec]));
|
|
604
|
+
}
|
|
605
|
+
/** Base stream adapter - we proxy hasSchema, prepareArguments, provideSchema to it */ streamAdapter = (0, __navios_core.inject)(__navios_core.StreamAdapterToken);
|
|
606
|
+
/**
|
|
607
|
+
* Prepares argument getters for parsing request data.
|
|
608
|
+
*
|
|
609
|
+
* Proxies to the base stream adapter to reuse existing argument preparation logic
|
|
610
|
+
* that handles query parameters, request body, and URL parameters for both
|
|
611
|
+
* Fastify and Bun adapters.
|
|
612
|
+
*
|
|
613
|
+
* @param handlerMetadata - The handler metadata with schemas and configuration.
|
|
614
|
+
* @returns An array of getter functions that populate request arguments.
|
|
615
|
+
*/ prepareArguments(handlerMetadata) {
|
|
616
|
+
return this.streamAdapter.prepareArguments?.(handlerMetadata) ?? [];
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Provides schema information for the handler.
|
|
620
|
+
*
|
|
621
|
+
* Proxies to the base stream adapter to reuse existing schema generation logic.
|
|
622
|
+
* For Fastify, this enables built-in validation. For Bun, this returns an empty object.
|
|
623
|
+
*
|
|
624
|
+
* @param handlerMetadata - The handler metadata containing configuration and schemas.
|
|
625
|
+
* @returns Schema information (Fastify route schema or empty object for Bun).
|
|
626
|
+
*/ provideSchema(handlerMetadata) {
|
|
627
|
+
if ("provideSchema" in this.streamAdapter && typeof this.streamAdapter.provideSchema === "function") return this.streamAdapter.provideSchema(handlerMetadata);
|
|
628
|
+
return {};
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Checks if the handler has any validation schemas defined.
|
|
632
|
+
*
|
|
633
|
+
* Proxies to the base stream adapter to check for query or request schemas.
|
|
634
|
+
*
|
|
635
|
+
* @param handlerMetadata - The handler metadata containing configuration.
|
|
636
|
+
* @returns `true` if the handler has any schemas (query or request).
|
|
637
|
+
*/ hasSchema(handlerMetadata) {
|
|
638
|
+
if ("hasSchema" in this.streamAdapter && typeof this.streamAdapter.hasSchema === "function") return this.streamAdapter.hasSchema(handlerMetadata);
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Creates a request handler function for XML Stream endpoints.
|
|
643
|
+
*
|
|
644
|
+
* This method generates a handler that:
|
|
645
|
+
* 1. Parses and validates request data (body, query, URL params) using the base adapter
|
|
646
|
+
* 2. Invokes the controller method with validated arguments (returns JSX)
|
|
647
|
+
* 3. Renders the JSX tree to XML string (resolves async and class components)
|
|
648
|
+
* 4. Sends the XML response with appropriate Content-Type header
|
|
649
|
+
*
|
|
650
|
+
* The handler automatically detects the environment (Fastify vs Bun) and uses the
|
|
651
|
+
* appropriate response mechanism (reply object vs Response object).
|
|
652
|
+
*
|
|
653
|
+
* @param controller - The controller class containing the handler method.
|
|
654
|
+
* @param handlerMetadata - The handler metadata with configuration and schemas.
|
|
655
|
+
* @returns A function that handles incoming requests and sends XML responses.
|
|
656
|
+
*/ provideHandler(controller, handlerMetadata) {
|
|
657
|
+
const getters = this.prepareArguments(handlerMetadata);
|
|
658
|
+
const config = handlerMetadata.config;
|
|
659
|
+
const formatArguments = async (request) => {
|
|
660
|
+
const argument = {};
|
|
661
|
+
const promises = [];
|
|
662
|
+
for (const getter of getters) {
|
|
663
|
+
const res = getter(argument, request);
|
|
664
|
+
if (res instanceof Promise) promises.push(res);
|
|
665
|
+
}
|
|
666
|
+
await Promise.all(promises);
|
|
667
|
+
return argument;
|
|
668
|
+
};
|
|
669
|
+
const contentType = config.contentType ?? "application/xml";
|
|
670
|
+
return async (context, request, reply) => {
|
|
671
|
+
const controllerInstance = await context.get(controller);
|
|
672
|
+
const argument = await formatArguments(request);
|
|
673
|
+
const xml = await renderToXml(await controllerInstance[handlerMetadata.classMethod](argument), {
|
|
674
|
+
declaration: config.xmlDeclaration ?? true,
|
|
675
|
+
encoding: config.encoding ?? "UTF-8",
|
|
676
|
+
container: context
|
|
677
|
+
});
|
|
678
|
+
if (reply === void 0) {
|
|
679
|
+
const headers = { "Content-Type": contentType };
|
|
680
|
+
for (const [key, value] of Object.entries(handlerMetadata.headers)) if (value != null) headers[key] = String(value);
|
|
681
|
+
return new Response(xml, {
|
|
682
|
+
status: handlerMetadata.successStatusCode,
|
|
683
|
+
headers
|
|
684
|
+
});
|
|
685
|
+
} else reply.status(handlerMetadata.successStatusCode).header("Content-Type", contentType).headers(handlerMetadata.headers).send(xml);
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
static {
|
|
689
|
+
_initClass();
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/define-environment.mts
|
|
695
|
+
/**
|
|
696
|
+
* Creates the XML environment configuration to be merged with base adapter (Fastify/Bun).
|
|
697
|
+
*
|
|
698
|
+
* @example
|
|
699
|
+
* ```typescript
|
|
700
|
+
* import { defineFastifyEnvironment } from '@navios/adapter-fastify'
|
|
701
|
+
* import { defineXmlEnvironment } from '@navios/adapter-xml'
|
|
702
|
+
* import { NaviosFactory } from '@navios/core'
|
|
703
|
+
*
|
|
704
|
+
* const fastifyEnv = defineFastifyEnvironment()
|
|
705
|
+
* const xmlEnv = defineXmlEnvironment()
|
|
706
|
+
*
|
|
707
|
+
* // Merge environments
|
|
708
|
+
* const mergedEnv = {
|
|
709
|
+
* httpTokens: new Map([
|
|
710
|
+
* ...fastifyEnv.httpTokens,
|
|
711
|
+
* ...xmlEnv.httpTokens,
|
|
712
|
+
* ]),
|
|
713
|
+
* }
|
|
714
|
+
*
|
|
715
|
+
* const app = await NaviosFactory.create(AppModule, {
|
|
716
|
+
* adapter: mergedEnv,
|
|
717
|
+
* })
|
|
718
|
+
* ```
|
|
719
|
+
*/ function defineXmlEnvironment() {
|
|
720
|
+
return { httpTokens: new Map([[__navios_core.XmlStreamAdapterToken, _XmlStreamAdapterService]]) };
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
//#endregion
|
|
724
|
+
exports.AsyncComponent = require_create_element.AsyncComponent;
|
|
725
|
+
exports.CData = CData;
|
|
726
|
+
exports.CDataSymbol = require_create_element.CDataSymbol;
|
|
727
|
+
exports.ClassComponent = require_create_element.ClassComponent;
|
|
728
|
+
exports.Component = require_create_element.Component;
|
|
729
|
+
exports.DangerouslyInsertRawXml = DangerouslyInsertRawXml;
|
|
730
|
+
exports.Fragment = require_create_element.Fragment;
|
|
731
|
+
exports.MissingContainerError = MissingContainerError;
|
|
732
|
+
exports.RawXmlSymbol = require_create_element.RawXmlSymbol;
|
|
733
|
+
exports.XmlStream = XmlStream;
|
|
734
|
+
Object.defineProperty(exports, 'XmlStreamAdapterService', {
|
|
735
|
+
enumerable: true,
|
|
736
|
+
get: function () {
|
|
737
|
+
return _XmlStreamAdapterService;
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
exports.createElement = require_create_element.createElement;
|
|
741
|
+
exports.declareXmlStream = declareXmlStream;
|
|
742
|
+
exports.defineTag = defineTag;
|
|
743
|
+
exports.defineXmlEnvironment = defineXmlEnvironment;
|
|
744
|
+
exports.isComponentClass = require_create_element.isComponentClass;
|
|
745
|
+
exports.renderToXml = renderToXml;
|
|
746
|
+
//# sourceMappingURL=index.cjs.map
|