@malloydata/render-validator 0.0.354

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,5 @@
1
+ /**
2
+ * Install minimal DOM globals if not already present.
3
+ * Called automatically on import; safe to call again.
4
+ */
5
+ export declare function ensureFakeDom(): void;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ensureFakeDom = ensureFakeDom;
8
+ /**
9
+ * Minimal DOM stub for headless environments (Node.js).
10
+ * Provides just enough surface for the renderer's UMD bundle to load
11
+ * without crashing. Not suitable for actual rendering.
12
+ *
13
+ * Importing this module auto-installs globals if they are absent.
14
+ */
15
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
16
+ const noop = () => { };
17
+ class Node {
18
+ constructor() {
19
+ this.childNodes = [];
20
+ this.parentNode = null;
21
+ // Event stubs — Solid.js delegates events on document
22
+ this.addEventListener = noop;
23
+ this.removeEventListener = noop;
24
+ }
25
+ appendChild(child) {
26
+ child.parentNode = this;
27
+ this.childNodes.push(child);
28
+ return child;
29
+ }
30
+ removeChild(child) {
31
+ const idx = this.childNodes.indexOf(child);
32
+ if (idx !== -1)
33
+ this.childNodes.splice(idx, 1);
34
+ child.parentNode = null;
35
+ return child;
36
+ }
37
+ get firstChild() {
38
+ var _a;
39
+ return (_a = this.childNodes[0]) !== null && _a !== void 0 ? _a : null;
40
+ }
41
+ }
42
+ class Text extends Node {
43
+ constructor(textContent) {
44
+ super();
45
+ this.textContent = textContent;
46
+ }
47
+ }
48
+ class Element extends Node {
49
+ constructor(tagName) {
50
+ super();
51
+ this.attrs = {};
52
+ this.style = {};
53
+ this.tagName = tagName.toUpperCase();
54
+ }
55
+ setAttribute(name, value) {
56
+ this.attrs[name] = value;
57
+ }
58
+ getAttribute(name) {
59
+ var _a;
60
+ return (_a = this.attrs[name]) !== null && _a !== void 0 ? _a : null;
61
+ }
62
+ removeAttribute(name) {
63
+ delete this.attrs[name];
64
+ }
65
+ }
66
+ class Document extends Node {
67
+ constructor() {
68
+ super(...arguments);
69
+ this.head = new Element('HEAD');
70
+ this.body = new Element('BODY');
71
+ this.documentElement = new Element('HTML');
72
+ }
73
+ createElement(tag) {
74
+ return new Element(tag);
75
+ }
76
+ createElementNS(_ns, tag) {
77
+ return new Element(tag);
78
+ }
79
+ createTextNode(text) {
80
+ return new Text(text);
81
+ }
82
+ }
83
+ /**
84
+ * Install minimal DOM globals if not already present.
85
+ * Called automatically on import; safe to call again.
86
+ */
87
+ function ensureFakeDom() {
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ const g = globalThis;
90
+ if (typeof g.document === 'undefined') {
91
+ g.document = new Document();
92
+ }
93
+ if (typeof g.navigator === 'undefined') {
94
+ g.navigator = { userAgent: '' };
95
+ }
96
+ else if (typeof g.navigator.userAgent === 'undefined') {
97
+ g.navigator.userAgent = '';
98
+ }
99
+ if (typeof g.window === 'undefined') {
100
+ g.window = Object.assign(g, {
101
+ addEventListener: noop,
102
+ removeEventListener: noop,
103
+ getComputedStyle: () => ({}),
104
+ requestAnimationFrame: noop,
105
+ cancelAnimationFrame: noop,
106
+ });
107
+ }
108
+ }
109
+ // Auto-install on import
110
+ ensureFakeDom();
111
+ //# sourceMappingURL=fake-dom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-dom.js","sourceRoot":"","sources":["../src/fake-dom.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AA0FH,sCAuBC;AA/GD;;;;;;GAMG;AAEH,gEAAgE;AAChE,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtB,MAAM,IAAI;IAAV;QACE,eAAU,GAAW,EAAE,CAAC;QACxB,eAAU,GAAgB,IAAI,CAAC;QAmB/B,sDAAsD;QACtD,qBAAgB,GAAG,IAAI,CAAC;QACxB,wBAAmB,GAAG,IAAI,CAAC;IAC7B,CAAC;IApBC,WAAW,CAAC,KAAW;QACrB,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,WAAW,CAAC,KAAW;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/C,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU;;QACZ,OAAO,MAAA,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;IACpC,CAAC;CAKF;AAED,MAAM,IAAK,SAAQ,IAAI;IACrB,YAAmB,WAAmB;QACpC,KAAK,EAAE,CAAC;QADS,gBAAW,GAAX,WAAW,CAAQ;IAEtC,CAAC;CACF;AAED,MAAM,OAAQ,SAAQ,IAAI;IAKxB,YAAY,OAAe;QACzB,KAAK,EAAE,CAAC;QAJF,UAAK,GAA2B,EAAE,CAAC;QAC3C,UAAK,GAA2B,EAAE,CAAC;QAIjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACvC,CAAC;IAED,YAAY,CAAC,IAAY,EAAE,KAAa;QACtC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,YAAY,CAAC,IAAY;;QACvB,OAAO,MAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAI,IAAI,CAAC;IAClC,CAAC;IAED,eAAe,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,QAAS,SAAQ,IAAI;IAA3B;;QACE,SAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3B,SAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3B,oBAAe,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAaxC,CAAC;IAXC,aAAa,CAAC,GAAW;QACvB,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,eAAe,CAAC,GAAW,EAAE,GAAW;QACtC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,cAAc,CAAC,IAAY;QACzB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;CACF;AAED;;;GAGG;AACH,SAAgB,aAAa;IAC3B,8DAA8D;IAC9D,MAAM,CAAC,GAAG,UAAiB,CAAC;IAE5B,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACtC,CAAC,CAAC,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;QACvC,CAAC,CAAC,SAAS,GAAG,EAAC,SAAS,EAAE,EAAE,EAAC,CAAC;IAChC,CAAC;SAAM,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;QACxD,CAAC,CAAC,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;YAC1B,gBAAgB,EAAE,IAAI;YACtB,mBAAmB,EAAE,IAAI;YACzB,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,qBAAqB,EAAE,IAAI;YAC3B,oBAAoB,EAAE,IAAI;SAC3B,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,yBAAyB;AACzB,aAAa,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import './fake-dom';
2
+ import type * as Malloy from '@malloydata/malloy-interfaces';
3
+ /**
4
+ * Validate renderer tags on a Malloy result without executing the query
5
+ * or requiring a browser DOM. Intended for headless / MCP use.
6
+ *
7
+ * @param result A `Malloy.Result` (typically from `PreparedResult.toStableResult()`)
8
+ * @returns Array of log messages (errors, warnings) from tag validation
9
+ */
10
+ export declare function validateRenderTags(result: Malloy.Result): Malloy.LogMessage[];
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.validateRenderTags = validateRenderTags;
8
+ // Fake DOM must be installed before the renderer UMD loads,
9
+ // because Solid.js (bundled inside) touches DOM globals at init time.
10
+ // CJS require() is synchronous, so this is guaranteed to run first.
11
+ require("./fake-dom");
12
+ const render_1 = require("@malloydata/render");
13
+ /**
14
+ * Validate renderer tags on a Malloy result without executing the query
15
+ * or requiring a browser DOM. Intended for headless / MCP use.
16
+ *
17
+ * @param result A `Malloy.Result` (typically from `PreparedResult.toStableResult()`)
18
+ * @returns Array of log messages (errors, warnings) from tag validation
19
+ */
20
+ function validateRenderTags(result) {
21
+ const renderer = new render_1.MalloyRenderer();
22
+ const viz = renderer.createViz();
23
+ viz.setResult(result);
24
+ return viz.getLogs();
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAiBH,gDAKC;AApBD,4DAA4D;AAC5D,sEAAsE;AACtE,oEAAoE;AACpE,sBAAoB;AAGpB,+CAAkD;AAElD;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,MAAqB;IACtD,MAAM,QAAQ,GAAG,IAAI,uBAAc,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;IACjC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC;AACvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@malloydata/render-validator",
3
+ "version": "0.0.354",
4
+ "license": "MIT",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "homepage": "https://github.com/malloydata/malloy#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/malloydata/malloy"
11
+ },
12
+ "engines": {
13
+ "node": ">=20"
14
+ },
15
+ "scripts": {
16
+ "build": "tsc --build",
17
+ "clean": "tsc --build --clean && rm -f tsconfig.tsbuildinfo"
18
+ },
19
+ "dependencies": {
20
+ "@malloydata/malloy-interfaces": "0.0.354",
21
+ "@malloydata/render": "0.0.354"
22
+ }
23
+ }
@@ -0,0 +1,120 @@
1
+ /*
2
+ * Copyright Contributors to the Malloy project
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ /**
7
+ * Minimal DOM stub for headless environments (Node.js).
8
+ * Provides just enough surface for the renderer's UMD bundle to load
9
+ * without crashing. Not suitable for actual rendering.
10
+ *
11
+ * Importing this module auto-installs globals if they are absent.
12
+ */
13
+
14
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
15
+ const noop = () => {};
16
+
17
+ class Node {
18
+ childNodes: Node[] = [];
19
+ parentNode: Node | null = null;
20
+
21
+ appendChild(child: Node): Node {
22
+ child.parentNode = this;
23
+ this.childNodes.push(child);
24
+ return child;
25
+ }
26
+
27
+ removeChild(child: Node): Node {
28
+ const idx = this.childNodes.indexOf(child);
29
+ if (idx !== -1) this.childNodes.splice(idx, 1);
30
+ child.parentNode = null;
31
+ return child;
32
+ }
33
+
34
+ get firstChild(): Node | null {
35
+ return this.childNodes[0] ?? null;
36
+ }
37
+
38
+ // Event stubs — Solid.js delegates events on document
39
+ addEventListener = noop;
40
+ removeEventListener = noop;
41
+ }
42
+
43
+ class Text extends Node {
44
+ constructor(public textContent: string) {
45
+ super();
46
+ }
47
+ }
48
+
49
+ class Element extends Node {
50
+ tagName: string;
51
+ private attrs: Record<string, string> = {};
52
+ style: Record<string, string> = {};
53
+
54
+ constructor(tagName: string) {
55
+ super();
56
+ this.tagName = tagName.toUpperCase();
57
+ }
58
+
59
+ setAttribute(name: string, value: string) {
60
+ this.attrs[name] = value;
61
+ }
62
+
63
+ getAttribute(name: string): string | null {
64
+ return this.attrs[name] ?? null;
65
+ }
66
+
67
+ removeAttribute(name: string) {
68
+ delete this.attrs[name];
69
+ }
70
+ }
71
+
72
+ class Document extends Node {
73
+ head = new Element('HEAD');
74
+ body = new Element('BODY');
75
+ documentElement = new Element('HTML');
76
+
77
+ createElement(tag: string): Element {
78
+ return new Element(tag);
79
+ }
80
+
81
+ createElementNS(_ns: string, tag: string): Element {
82
+ return new Element(tag);
83
+ }
84
+
85
+ createTextNode(text: string): Text {
86
+ return new Text(text);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Install minimal DOM globals if not already present.
92
+ * Called automatically on import; safe to call again.
93
+ */
94
+ export function ensureFakeDom(): void {
95
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ const g = globalThis as any;
97
+
98
+ if (typeof g.document === 'undefined') {
99
+ g.document = new Document();
100
+ }
101
+
102
+ if (typeof g.navigator === 'undefined') {
103
+ g.navigator = {userAgent: ''};
104
+ } else if (typeof g.navigator.userAgent === 'undefined') {
105
+ g.navigator.userAgent = '';
106
+ }
107
+
108
+ if (typeof g.window === 'undefined') {
109
+ g.window = Object.assign(g, {
110
+ addEventListener: noop,
111
+ removeEventListener: noop,
112
+ getComputedStyle: () => ({}),
113
+ requestAnimationFrame: noop,
114
+ cancelAnimationFrame: noop,
115
+ });
116
+ }
117
+ }
118
+
119
+ // Auto-install on import
120
+ ensureFakeDom();
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright Contributors to the Malloy project
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ // Fake DOM must be installed before the renderer UMD loads,
7
+ // because Solid.js (bundled inside) touches DOM globals at init time.
8
+ // CJS require() is synchronous, so this is guaranteed to run first.
9
+ import './fake-dom';
10
+
11
+ import type * as Malloy from '@malloydata/malloy-interfaces';
12
+ import {MalloyRenderer} from '@malloydata/render';
13
+
14
+ /**
15
+ * Validate renderer tags on a Malloy result without executing the query
16
+ * or requiring a browser DOM. Intended for headless / MCP use.
17
+ *
18
+ * @param result A `Malloy.Result` (typically from `PreparedResult.toStableResult()`)
19
+ * @returns Array of log messages (errors, warnings) from tag validation
20
+ */
21
+ export function validateRenderTags(result: Malloy.Result): Malloy.LogMessage[] {
22
+ const renderer = new MalloyRenderer();
23
+ const viz = renderer.createViz();
24
+ viz.setResult(result);
25
+ return viz.getLogs();
26
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.packages.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "composite": true
7
+ },
8
+ "include": ["./src"]
9
+ }