@pascal-app/core 0.5.1 → 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/dist/events/bus.d.ts +74 -4
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/events/bus.js +1 -1
- package/dist/hooks/scene-registry/scene-registry.d.ts +2 -0
- package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.js +2 -0
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +164 -6
- package/dist/hooks/spatial-grid/spatial-grid.d.ts +2 -0
- package/dist/hooks/spatial-grid/spatial-grid.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid.js +43 -20
- package/dist/index.d.ts +9 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -11
- package/dist/lib/door-operation.d.ts +7 -0
- package/dist/lib/door-operation.d.ts.map +1 -0
- package/dist/lib/door-operation.js +25 -0
- package/dist/lib/polygon-geometry.d.ts +3 -0
- package/dist/lib/polygon-geometry.d.ts.map +1 -0
- package/dist/lib/polygon-geometry.js +90 -0
- package/dist/lib/slab-polygon.d.ts +3 -0
- package/dist/lib/slab-polygon.d.ts.map +1 -0
- package/dist/lib/slab-polygon.js +58 -0
- package/dist/lib/space-detection.d.ts +10 -17
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +666 -453
- package/dist/material-library.d.ts +20 -0
- package/dist/material-library.d.ts.map +1 -0
- package/dist/material-library.js +580 -0
- package/dist/schema/asset-url.d.ts +34 -0
- package/dist/schema/asset-url.d.ts.map +1 -0
- package/dist/schema/asset-url.js +79 -0
- package/dist/schema/asset-url.test.d.ts +2 -0
- package/dist/schema/asset-url.test.d.ts.map +1 -0
- package/dist/schema/asset-url.test.js +138 -0
- package/dist/schema/index.d.ts +14 -7
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +10 -7
- package/dist/schema/material.d.ts +112 -2
- package/dist/schema/material.d.ts.map +1 -1
- package/dist/schema/material.js +55 -1
- package/dist/schema/nodes/ceiling.d.ts +11 -1
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +6 -0
- package/dist/schema/nodes/column.d.ts +520 -0
- package/dist/schema/nodes/column.d.ts.map +1 -0
- package/dist/schema/nodes/column.js +385 -0
- package/dist/schema/nodes/door.d.ts +74 -1
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +39 -2
- package/dist/schema/nodes/fence.d.ts +34 -0
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +5 -0
- package/dist/schema/nodes/guide.d.ts +17 -0
- package/dist/schema/nodes/guide.d.ts.map +1 -1
- package/dist/schema/nodes/guide.js +11 -1
- package/dist/schema/nodes/item.d.ts +10 -2
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +18 -1
- package/dist/schema/nodes/level.d.ts +1 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +6 -0
- package/dist/schema/nodes/roof-segment.d.ts +3 -1
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +1 -0
- package/dist/schema/nodes/roof.d.ts +108 -0
- package/dist/schema/nodes/roof.d.ts.map +1 -1
- package/dist/schema/nodes/roof.js +58 -2
- package/dist/schema/nodes/scan.d.ts.map +1 -1
- package/dist/schema/nodes/scan.js +2 -1
- package/dist/schema/nodes/site.d.ts +2 -1
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/slab.d.ts +11 -1
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +7 -0
- package/dist/schema/nodes/spawn.d.ts +24 -0
- package/dist/schema/nodes/spawn.d.ts.map +1 -0
- package/dist/schema/nodes/spawn.js +8 -0
- package/dist/schema/nodes/stair-segment.d.ts +3 -1
- package/dist/schema/nodes/stair-segment.d.ts.map +1 -1
- package/dist/schema/nodes/stair-segment.js +1 -0
- package/dist/schema/nodes/stair.d.ts +122 -2
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +72 -2
- package/dist/schema/nodes/surface-hole-metadata.d.ts +10 -0
- package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -0
- package/dist/schema/nodes/surface-hole-metadata.js +5 -0
- package/dist/schema/nodes/wall.d.ts +87 -1
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +45 -4
- package/dist/schema/nodes/window.d.ts +57 -1
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +29 -0
- package/dist/schema/types.d.ts +653 -12
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +4 -0
- package/dist/store/actions/node-actions.d.ts +1 -1
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +181 -5
- package/dist/store/history-control.d.ts +14 -0
- package/dist/store/history-control.d.ts.map +1 -0
- package/dist/store/history-control.js +22 -0
- package/dist/store/use-interactive.d.ts +43 -0
- package/dist/store/use-interactive.d.ts.map +1 -1
- package/dist/store/use-interactive.js +66 -0
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +307 -3
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +7 -0
- package/dist/systems/fence/fence-system.d.ts.map +1 -1
- package/dist/systems/fence/fence-system.js +106 -39
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +31 -1
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +45 -8
- package/dist/systems/stair/stair-opening-sync.d.ts +6 -0
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-sync.js +576 -0
- package/dist/systems/stair/stair-opening-sync.test.d.ts +2 -0
- package/dist/systems/stair/stair-opening-sync.test.d.ts.map +1 -0
- package/dist/systems/stair/stair-opening-sync.test.js +65 -0
- package/dist/systems/stair/stair-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-system.js +119 -2
- package/dist/systems/wall/wall-curve.d.ts +43 -0
- package/dist/systems/wall/wall-curve.d.ts.map +1 -0
- package/dist/systems/wall/wall-curve.js +176 -0
- package/dist/systems/wall/wall-footprint.d.ts.map +1 -1
- package/dist/systems/wall/wall-footprint.js +16 -2
- package/dist/systems/wall/wall-mitering.d.ts +7 -0
- package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
- package/dist/systems/wall/wall-mitering.js +76 -3
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +202 -2
- package/package.json +33 -5
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Scheme allowlist for asset-like URLs embedded in scene graphs.
|
|
4
|
+
*
|
|
5
|
+
* Phase 3 security audit: `scan.url`, `guide.url`, `material.texture.url`, and
|
|
6
|
+
* `item.asset.src` were previously bare `z.string()`. That meant an
|
|
7
|
+
* attacker-crafted scene loaded in the editor could beacon to arbitrary URLs
|
|
8
|
+
* (e.g. `javascript:`, `file:///etc/passwd`, `http://169.254.169.254/...`).
|
|
9
|
+
*
|
|
10
|
+
* This validator rejects URLs that don't match the scheme allowlist below.
|
|
11
|
+
*/
|
|
12
|
+
const ALLOWED_SCHEMES = ['asset:', 'blob:', 'https:', 'data:image/'];
|
|
13
|
+
/**
|
|
14
|
+
* Optional environment variable that narrows which `https:` origins are
|
|
15
|
+
* accepted. Set to a comma-separated list (e.g. `https://cdn.pascal.app`).
|
|
16
|
+
* When unset, any `https:` origin is permitted.
|
|
17
|
+
*/
|
|
18
|
+
export const ALLOWED_ORIGINS_ENV = 'PASCAL_ALLOWED_ASSET_ORIGINS';
|
|
19
|
+
// Narrow access to the environment variable without requiring @types/node in
|
|
20
|
+
// this package. The core package ships to both browser and Node contexts.
|
|
21
|
+
function readAllowedOrigins() {
|
|
22
|
+
const g = globalThis;
|
|
23
|
+
const value = g.process?.env?.[ALLOWED_ORIGINS_ENV];
|
|
24
|
+
if (!value)
|
|
25
|
+
return undefined;
|
|
26
|
+
const list = value
|
|
27
|
+
.split(',')
|
|
28
|
+
.map((s) => s.trim())
|
|
29
|
+
.filter((s) => s.length > 0);
|
|
30
|
+
return list.length > 0 ? list : undefined;
|
|
31
|
+
}
|
|
32
|
+
function isAllowedAssetUrl(url) {
|
|
33
|
+
if (typeof url !== 'string' || url.length === 0)
|
|
34
|
+
return false;
|
|
35
|
+
if (url.startsWith('asset://'))
|
|
36
|
+
return true; // internal handle
|
|
37
|
+
if (url.startsWith('blob:'))
|
|
38
|
+
return true; // in-memory reference
|
|
39
|
+
if (url.startsWith('data:image/'))
|
|
40
|
+
return true; // inline image only (never data:text/html)
|
|
41
|
+
if (url.startsWith('/'))
|
|
42
|
+
return true; // app-relative path
|
|
43
|
+
try {
|
|
44
|
+
const parsed = new URL(url);
|
|
45
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')
|
|
46
|
+
return false;
|
|
47
|
+
// http is only permitted for localhost development
|
|
48
|
+
if (parsed.protocol === 'http:' && !['localhost', '127.0.0.1'].includes(parsed.hostname)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// optional env-driven origin allowlist (only enforced for https URLs)
|
|
52
|
+
if (parsed.protocol === 'https:') {
|
|
53
|
+
const allowlist = readAllowedOrigins();
|
|
54
|
+
if (allowlist)
|
|
55
|
+
return allowlist.includes(parsed.origin);
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Zod validator for asset-style URL fields. Accepts:
|
|
65
|
+
* - `asset://…` internal handles
|
|
66
|
+
* - `blob:…` in-memory references
|
|
67
|
+
* - `data:image/…` inline images (not `data:text/html` or other types)
|
|
68
|
+
* - `/…` app-relative paths
|
|
69
|
+
* - `https://…` public URLs (optionally narrowed to an env allowlist)
|
|
70
|
+
* - `http://localhost[:port]/…` or `http://127.0.0.1/…` for local dev
|
|
71
|
+
*
|
|
72
|
+
* Rejects every other scheme, including `javascript:`, `file:`, `ftp:`,
|
|
73
|
+
* and `data:text/html`, as well as empty strings and non-URL garbage.
|
|
74
|
+
*/
|
|
75
|
+
export const AssetUrl = z.string().refine(isAllowedAssetUrl, {
|
|
76
|
+
message: 'URL must be asset://, blob:, data:image/, /path, or https://. http://localhost allowed for dev.',
|
|
77
|
+
});
|
|
78
|
+
// re-export the scheme allowlist for documentation / downstream validators
|
|
79
|
+
export { ALLOWED_SCHEMES };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-url.test.d.ts","sourceRoot":"","sources":["../../src/schema/asset-url.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// @ts-expect-error — bun:test is provided by the Bun runtime; core does not
|
|
2
|
+
// depend on @types/bun so the import type is unresolved at compile time.
|
|
3
|
+
// The tsconfig in packages/core still emits this file; the @ts-expect-error
|
|
4
|
+
// keeps the build green while letting `bun test` pick it up normally.
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
|
|
6
|
+
import { ALLOWED_ORIGINS_ENV, AssetUrl } from './asset-url';
|
|
7
|
+
function isValid(url) {
|
|
8
|
+
return AssetUrl.safeParse(url).success;
|
|
9
|
+
}
|
|
10
|
+
describe('AssetUrl', () => {
|
|
11
|
+
describe('allowed URLs', () => {
|
|
12
|
+
const cases = [
|
|
13
|
+
['asset://abc', 'internal asset handle'],
|
|
14
|
+
['asset://catalog/items/chair-1', 'nested asset handle'],
|
|
15
|
+
['blob:http://example.com/uuid-1234', 'blob URL with http inner'],
|
|
16
|
+
['blob:https://example.com/uuid-5678', 'blob URL with https inner'],
|
|
17
|
+
['https://cdn.example.com/a.glb', 'https CDN URL'],
|
|
18
|
+
['https://cdn.example.com/models/chair.glb?v=2', 'https URL with query string'],
|
|
19
|
+
['http://localhost:3000/x', 'http localhost with port'],
|
|
20
|
+
['http://localhost/x', 'http localhost without port'],
|
|
21
|
+
['http://127.0.0.1:8080/texture.png', 'http 127.0.0.1 loopback'],
|
|
22
|
+
['/public/a.glb', 'app-relative path'],
|
|
23
|
+
['/material/wood1/albedoMap_basecolor.jpg', 'relative path deep'],
|
|
24
|
+
['data:image/png;base64,AAA', 'inline PNG data URL'],
|
|
25
|
+
['data:image/jpeg;base64,/9j/', 'inline JPEG data URL'],
|
|
26
|
+
['data:image/webp;base64,UklGR', 'inline WebP data URL'],
|
|
27
|
+
['data:image/svg+xml,%3Csvg%3E', 'inline SVG data URL'],
|
|
28
|
+
];
|
|
29
|
+
for (const [url, label] of cases) {
|
|
30
|
+
test(`accepts ${label}: ${url}`, () => {
|
|
31
|
+
expect(isValid(url)).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
describe('rejected URLs', () => {
|
|
36
|
+
const cases = [
|
|
37
|
+
['javascript:alert(1)', 'javascript scheme'],
|
|
38
|
+
['JAVASCRIPT:alert(1)', 'javascript scheme uppercase'],
|
|
39
|
+
['file:///etc/passwd', 'file scheme'],
|
|
40
|
+
['file://C:/Windows/System32/config', 'file scheme Windows'],
|
|
41
|
+
['http://evil.com/', 'non-loopback http'],
|
|
42
|
+
['http://example.com:3000/x', 'http on non-loopback host'],
|
|
43
|
+
['http://169.254.169.254/latest/meta-data/', 'http on link-local (cloud metadata)'],
|
|
44
|
+
['data:text/html,<script>alert(1)</script>', 'data text/html'],
|
|
45
|
+
['data:application/javascript,alert(1)', 'data application/javascript'],
|
|
46
|
+
['data:text/plain,hi', 'data text/plain'],
|
|
47
|
+
['ftp://a.b.com', 'ftp scheme'],
|
|
48
|
+
['ws://example.com/', 'websocket scheme'],
|
|
49
|
+
['vbscript:msgbox', 'vbscript scheme'],
|
|
50
|
+
['', 'empty string'],
|
|
51
|
+
['not a url at all', 'non-url string'],
|
|
52
|
+
['://missing-scheme', 'malformed'],
|
|
53
|
+
];
|
|
54
|
+
for (const [url, label] of cases) {
|
|
55
|
+
test(`rejects ${label}: ${url}`, () => {
|
|
56
|
+
expect(isValid(url)).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
describe(`env allowlist via ${ALLOWED_ORIGINS_ENV}`, () => {
|
|
61
|
+
const g = globalThis;
|
|
62
|
+
const original = g.process?.env?.[ALLOWED_ORIGINS_ENV];
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
if (g.process?.env)
|
|
65
|
+
delete g.process.env[ALLOWED_ORIGINS_ENV];
|
|
66
|
+
});
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
if (!g.process?.env)
|
|
69
|
+
return;
|
|
70
|
+
if (original === undefined) {
|
|
71
|
+
delete g.process.env[ALLOWED_ORIGINS_ENV];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = original;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
test('single origin allowlist accepts matching https URL', () => {
|
|
78
|
+
if (!g.process?.env)
|
|
79
|
+
return; // browser-only runtime
|
|
80
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
|
|
81
|
+
expect(isValid('https://cdn.pascal.app/a.glb')).toBe(true);
|
|
82
|
+
expect(isValid('https://cdn.pascal.app/deep/path?q=1')).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
test('single origin allowlist rejects non-matching https URL', () => {
|
|
85
|
+
if (!g.process?.env)
|
|
86
|
+
return;
|
|
87
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
|
|
88
|
+
expect(isValid('https://cdn.other.com/a.glb')).toBe(false);
|
|
89
|
+
expect(isValid('https://attacker.example.com/x')).toBe(false);
|
|
90
|
+
});
|
|
91
|
+
test('multi-origin allowlist accepts any listed origin', () => {
|
|
92
|
+
if (!g.process?.env)
|
|
93
|
+
return;
|
|
94
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app, https://assets.pascal.app';
|
|
95
|
+
expect(isValid('https://cdn.pascal.app/a.glb')).toBe(true);
|
|
96
|
+
expect(isValid('https://assets.pascal.app/tex.webp')).toBe(true);
|
|
97
|
+
expect(isValid('https://third.example.com/x')).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
test('allowlist ignores trailing / in URL path (origin match only)', () => {
|
|
100
|
+
if (!g.process?.env)
|
|
101
|
+
return;
|
|
102
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
|
|
103
|
+
expect(isValid('https://cdn.pascal.app/')).toBe(true);
|
|
104
|
+
expect(isValid('https://cdn.pascal.app')).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
test('empty allowlist behaves like unset', () => {
|
|
107
|
+
if (!g.process?.env)
|
|
108
|
+
return;
|
|
109
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = '';
|
|
110
|
+
expect(isValid('https://cdn.other.com/a.glb')).toBe(true);
|
|
111
|
+
});
|
|
112
|
+
test('allowlist does not restrict non-https schemes', () => {
|
|
113
|
+
if (!g.process?.env)
|
|
114
|
+
return;
|
|
115
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
|
|
116
|
+
// these should still pass because they match earlier scheme-based branches
|
|
117
|
+
expect(isValid('asset://x')).toBe(true);
|
|
118
|
+
expect(isValid('blob:https://example.com/abc')).toBe(true);
|
|
119
|
+
expect(isValid('data:image/png;base64,AAA')).toBe(true);
|
|
120
|
+
expect(isValid('/public/a.glb')).toBe(true);
|
|
121
|
+
expect(isValid('http://localhost:3000/x')).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
test('allowlist rejects subdomain spoofing', () => {
|
|
124
|
+
if (!g.process?.env)
|
|
125
|
+
return;
|
|
126
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app';
|
|
127
|
+
expect(isValid('https://cdn.pascal.app.evil.com/x')).toBe(false);
|
|
128
|
+
expect(isValid('https://evil.com/cdn.pascal.app')).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
test('allowlist respects ports', () => {
|
|
131
|
+
if (!g.process?.env)
|
|
132
|
+
return;
|
|
133
|
+
g.process.env[ALLOWED_ORIGINS_ENV] = 'https://cdn.pascal.app:8443';
|
|
134
|
+
expect(isValid('https://cdn.pascal.app:8443/x')).toBe(true);
|
|
135
|
+
expect(isValid('https://cdn.pascal.app/x')).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
export { BaseNode, generateId, Material, nodeType, objectId } from './base';
|
|
2
2
|
export { CameraSchema } from './camera';
|
|
3
3
|
export { type Collection, type CollectionId, generateCollectionId } from './collections';
|
|
4
|
-
export {
|
|
4
|
+
export type { MaterialMapProperties, MaterialMaps, MaterialPresetPayload, MaterialTarget as MaterialTargetValue, TextureWrapMode as TextureWrapModeValue, } from './material';
|
|
5
|
+
export { DEFAULT_MATERIALS, MaterialMapPropertiesSchema, MaterialMapsSchema, MaterialPreset, MaterialPresetPayloadSchema, MaterialProperties, MaterialSchema, MaterialTarget, resolveMaterial, TextureWrapMode, } from './material';
|
|
5
6
|
export { BuildingNode } from './nodes/building';
|
|
6
7
|
export { CeilingNode } from './nodes/ceiling';
|
|
8
|
+
export { COLUMN_PRESETS, ColumnBaseStyle, ColumnCapitalStyle, ColumnCarvingPlacement, ColumnCrossSection, ColumnNode, ColumnPanelShape, type ColumnPresetId, ColumnRingPlacement, ColumnShaftDetail, ColumnShaftProfile, ColumnStyle, } from './nodes/column';
|
|
7
9
|
export { DoorNode, DoorSegment } from './nodes/door';
|
|
8
10
|
export { FenceBaseStyle, FenceNode, FenceStyle } from './nodes/fence';
|
|
9
|
-
export { GuideNode } from './nodes/guide';
|
|
11
|
+
export { GuideNode, GuideScaleReference } from './nodes/guide';
|
|
10
12
|
export type { AnimationEffect, Asset, AssetInput, Control, Effect, Interactive, LightEffect, SliderControl, TemperatureControl, ToggleControl, } from './nodes/item';
|
|
11
|
-
export { getScaledDimensions, ItemNode } from './nodes/item';
|
|
13
|
+
export { getScaledDimensions, ItemNode, isLowProfileItemSurface, LOW_PROFILE_ITEM_SURFACE_MAX_HEIGHT, } from './nodes/item';
|
|
12
14
|
export { LevelNode } from './nodes/level';
|
|
13
|
-
export {
|
|
15
|
+
export type { RoofSurfaceMaterialRole, RoofSurfaceMaterialSpec } from './nodes/roof';
|
|
16
|
+
export { getEffectiveRoofSurfaceMaterial, RoofNode } from './nodes/roof';
|
|
14
17
|
export { RoofSegmentNode, RoofType } from './nodes/roof-segment';
|
|
15
18
|
export { ScanNode } from './nodes/scan';
|
|
16
19
|
export { SiteNode } from './nodes/site';
|
|
17
20
|
export { SlabNode } from './nodes/slab';
|
|
18
|
-
export {
|
|
21
|
+
export { SpawnNode } from './nodes/spawn';
|
|
22
|
+
export type { StairSurfaceMaterialRole, StairSurfaceMaterialSpec } from './nodes/stair';
|
|
23
|
+
export { getEffectiveStairSurfaceMaterial, StairNode, StairRailingMode, StairSlabOpeningMode, StairTopLandingMode, StairType, } from './nodes/stair';
|
|
19
24
|
export { AttachmentSide, StairSegmentNode, StairSegmentType } from './nodes/stair-segment';
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
25
|
+
export { SurfaceHoleMetadata } from './nodes/surface-hole-metadata';
|
|
26
|
+
export type { WallSurfaceMaterialSpec, WallSurfaceSide } from './nodes/wall';
|
|
27
|
+
export { getEffectiveWallSurfaceMaterial, getWallSurfaceMaterialSignature, WallNode, } from './nodes/wall';
|
|
28
|
+
export { WindowNode, WindowType } from './nodes/window';
|
|
22
29
|
export { ZoneNode } from './nodes/zone';
|
|
23
30
|
export type { AnyNodeId, AnyNodeType } from './types';
|
|
24
31
|
export { AnyNode } from './types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"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"}
|
package/dist/schema/index.js
CHANGED
|
@@ -5,24 +5,27 @@ export { CameraSchema } from './camera';
|
|
|
5
5
|
// Collections
|
|
6
6
|
export { generateCollectionId } from './collections';
|
|
7
7
|
// Material
|
|
8
|
-
export { DEFAULT_MATERIALS, MaterialPreset, MaterialProperties, MaterialSchema, resolveMaterial, } from './material';
|
|
8
|
+
export { DEFAULT_MATERIALS, MaterialMapPropertiesSchema, MaterialMapsSchema, MaterialPreset, MaterialPresetPayloadSchema, MaterialProperties, MaterialSchema, MaterialTarget, resolveMaterial, TextureWrapMode, } from './material';
|
|
9
9
|
export { BuildingNode } from './nodes/building';
|
|
10
10
|
export { CeilingNode } from './nodes/ceiling';
|
|
11
|
+
export { COLUMN_PRESETS, ColumnBaseStyle, ColumnCapitalStyle, ColumnCarvingPlacement, ColumnCrossSection, ColumnNode, ColumnPanelShape, ColumnRingPlacement, ColumnShaftDetail, ColumnShaftProfile, ColumnStyle, } from './nodes/column';
|
|
11
12
|
export { DoorNode, DoorSegment } from './nodes/door';
|
|
12
13
|
export { FenceBaseStyle, FenceNode, FenceStyle } from './nodes/fence';
|
|
13
|
-
export { GuideNode } from './nodes/guide';
|
|
14
|
-
export { getScaledDimensions, ItemNode } from './nodes/item';
|
|
14
|
+
export { GuideNode, GuideScaleReference } from './nodes/guide';
|
|
15
|
+
export { getScaledDimensions, ItemNode, isLowProfileItemSurface, LOW_PROFILE_ITEM_SURFACE_MAX_HEIGHT, } from './nodes/item';
|
|
15
16
|
export { LevelNode } from './nodes/level';
|
|
16
|
-
export { RoofNode } from './nodes/roof';
|
|
17
|
+
export { getEffectiveRoofSurfaceMaterial, RoofNode } from './nodes/roof';
|
|
17
18
|
export { RoofSegmentNode, RoofType } from './nodes/roof-segment';
|
|
18
19
|
export { ScanNode } from './nodes/scan';
|
|
19
20
|
// Nodes
|
|
20
21
|
export { SiteNode } from './nodes/site';
|
|
21
22
|
export { SlabNode } from './nodes/slab';
|
|
22
|
-
export {
|
|
23
|
+
export { SpawnNode } from './nodes/spawn';
|
|
24
|
+
export { getEffectiveStairSurfaceMaterial, StairNode, StairRailingMode, StairSlabOpeningMode, StairTopLandingMode, StairType, } from './nodes/stair';
|
|
23
25
|
export { AttachmentSide, StairSegmentNode, StairSegmentType } from './nodes/stair-segment';
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
26
|
+
export { SurfaceHoleMetadata } from './nodes/surface-hole-metadata';
|
|
27
|
+
export { getEffectiveWallSurfaceMaterial, getWallSurfaceMaterialSignature, WallNode, } from './nodes/wall';
|
|
28
|
+
export { WindowNode, WindowType } from './nodes/window';
|
|
26
29
|
export { ZoneNode } from './nodes/zone';
|
|
27
30
|
// Union types
|
|
28
31
|
export { AnyNode } from './types';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const MaterialPreset: z.ZodEnum<{
|
|
3
|
-
custom: "custom";
|
|
4
3
|
white: "white";
|
|
5
4
|
brick: "brick";
|
|
6
5
|
concrete: "concrete";
|
|
@@ -10,6 +9,7 @@ export declare const MaterialPreset: z.ZodEnum<{
|
|
|
10
9
|
plaster: "plaster";
|
|
11
10
|
tile: "tile";
|
|
12
11
|
marble: "marble";
|
|
12
|
+
custom: "custom";
|
|
13
13
|
}>;
|
|
14
14
|
export type MaterialPreset = z.infer<typeof MaterialPreset>;
|
|
15
15
|
export declare const MaterialProperties: z.ZodObject<{
|
|
@@ -26,8 +26,8 @@ export declare const MaterialProperties: z.ZodObject<{
|
|
|
26
26
|
}, z.core.$strip>;
|
|
27
27
|
export type MaterialProperties = z.infer<typeof MaterialProperties>;
|
|
28
28
|
export declare const MaterialSchema: z.ZodObject<{
|
|
29
|
+
id: z.ZodOptional<z.ZodString>;
|
|
29
30
|
preset: z.ZodOptional<z.ZodEnum<{
|
|
30
|
-
custom: "custom";
|
|
31
31
|
white: "white";
|
|
32
32
|
brick: "brick";
|
|
33
33
|
concrete: "concrete";
|
|
@@ -37,6 +37,7 @@ export declare const MaterialSchema: z.ZodObject<{
|
|
|
37
37
|
plaster: "plaster";
|
|
38
38
|
tile: "tile";
|
|
39
39
|
marble: "marble";
|
|
40
|
+
custom: "custom";
|
|
40
41
|
}>>;
|
|
41
42
|
properties: z.ZodOptional<z.ZodObject<{
|
|
42
43
|
color: z.ZodDefault<z.ZodString>;
|
|
@@ -57,6 +58,115 @@ export declare const MaterialSchema: z.ZodObject<{
|
|
|
57
58
|
}, z.core.$strip>>;
|
|
58
59
|
}, z.core.$strip>;
|
|
59
60
|
export type MaterialSchema = z.infer<typeof MaterialSchema>;
|
|
61
|
+
export declare const MaterialTarget: z.ZodEnum<{
|
|
62
|
+
wall: "wall";
|
|
63
|
+
roof: "roof";
|
|
64
|
+
"roof-segment": "roof-segment";
|
|
65
|
+
stair: "stair";
|
|
66
|
+
"stair-segment": "stair-segment";
|
|
67
|
+
fence: "fence";
|
|
68
|
+
column: "column";
|
|
69
|
+
slab: "slab";
|
|
70
|
+
ceiling: "ceiling";
|
|
71
|
+
door: "door";
|
|
72
|
+
window: "window";
|
|
73
|
+
}>;
|
|
74
|
+
export type MaterialTarget = z.infer<typeof MaterialTarget>;
|
|
75
|
+
export declare const TextureWrapMode: z.ZodEnum<{
|
|
76
|
+
Repeat: "Repeat";
|
|
77
|
+
ClampToEdge: "ClampToEdge";
|
|
78
|
+
MirroredRepeat: "MirroredRepeat";
|
|
79
|
+
}>;
|
|
80
|
+
export type TextureWrapMode = z.infer<typeof TextureWrapMode>;
|
|
81
|
+
export declare const MaterialMapsSchema: z.ZodObject<{
|
|
82
|
+
albedoMap: z.ZodOptional<z.ZodString>;
|
|
83
|
+
metalnessMap: z.ZodOptional<z.ZodString>;
|
|
84
|
+
roughnessMap: z.ZodOptional<z.ZodString>;
|
|
85
|
+
normalMap: z.ZodOptional<z.ZodString>;
|
|
86
|
+
displacementMap: z.ZodOptional<z.ZodString>;
|
|
87
|
+
aoMap: z.ZodOptional<z.ZodString>;
|
|
88
|
+
emissiveMap: z.ZodOptional<z.ZodString>;
|
|
89
|
+
bumpMap: z.ZodOptional<z.ZodString>;
|
|
90
|
+
alphaMap: z.ZodOptional<z.ZodString>;
|
|
91
|
+
lightMap: z.ZodOptional<z.ZodString>;
|
|
92
|
+
}, z.core.$strip>;
|
|
93
|
+
export type MaterialMaps = z.infer<typeof MaterialMapsSchema>;
|
|
94
|
+
export declare const MaterialMapPropertiesSchema: z.ZodObject<{
|
|
95
|
+
color: z.ZodDefault<z.ZodString>;
|
|
96
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
97
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
98
|
+
repeatX: z.ZodDefault<z.ZodNumber>;
|
|
99
|
+
repeatY: z.ZodDefault<z.ZodNumber>;
|
|
100
|
+
rotation: z.ZodDefault<z.ZodNumber>;
|
|
101
|
+
wrapS: z.ZodDefault<z.ZodEnum<{
|
|
102
|
+
Repeat: "Repeat";
|
|
103
|
+
ClampToEdge: "ClampToEdge";
|
|
104
|
+
MirroredRepeat: "MirroredRepeat";
|
|
105
|
+
}>>;
|
|
106
|
+
wrapT: z.ZodDefault<z.ZodEnum<{
|
|
107
|
+
Repeat: "Repeat";
|
|
108
|
+
ClampToEdge: "ClampToEdge";
|
|
109
|
+
MirroredRepeat: "MirroredRepeat";
|
|
110
|
+
}>>;
|
|
111
|
+
normalScaleX: z.ZodDefault<z.ZodNumber>;
|
|
112
|
+
normalScaleY: z.ZodDefault<z.ZodNumber>;
|
|
113
|
+
emissiveIntensity: z.ZodDefault<z.ZodNumber>;
|
|
114
|
+
displacementScale: z.ZodDefault<z.ZodNumber>;
|
|
115
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
116
|
+
flipY: z.ZodDefault<z.ZodBoolean>;
|
|
117
|
+
bumpScale: z.ZodDefault<z.ZodNumber>;
|
|
118
|
+
emissiveColor: z.ZodDefault<z.ZodString>;
|
|
119
|
+
aoMapIntensity: z.ZodDefault<z.ZodNumber>;
|
|
120
|
+
side: z.ZodDefault<z.ZodNumber>;
|
|
121
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
122
|
+
lightMapIntensity: z.ZodDefault<z.ZodNumber>;
|
|
123
|
+
}, z.core.$strip>;
|
|
124
|
+
export type MaterialMapProperties = z.infer<typeof MaterialMapPropertiesSchema>;
|
|
125
|
+
export declare const MaterialPresetPayloadSchema: z.ZodObject<{
|
|
126
|
+
maps: z.ZodObject<{
|
|
127
|
+
albedoMap: z.ZodOptional<z.ZodString>;
|
|
128
|
+
metalnessMap: z.ZodOptional<z.ZodString>;
|
|
129
|
+
roughnessMap: z.ZodOptional<z.ZodString>;
|
|
130
|
+
normalMap: z.ZodOptional<z.ZodString>;
|
|
131
|
+
displacementMap: z.ZodOptional<z.ZodString>;
|
|
132
|
+
aoMap: z.ZodOptional<z.ZodString>;
|
|
133
|
+
emissiveMap: z.ZodOptional<z.ZodString>;
|
|
134
|
+
bumpMap: z.ZodOptional<z.ZodString>;
|
|
135
|
+
alphaMap: z.ZodOptional<z.ZodString>;
|
|
136
|
+
lightMap: z.ZodOptional<z.ZodString>;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
mapProperties: z.ZodObject<{
|
|
139
|
+
color: z.ZodDefault<z.ZodString>;
|
|
140
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
141
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
142
|
+
repeatX: z.ZodDefault<z.ZodNumber>;
|
|
143
|
+
repeatY: z.ZodDefault<z.ZodNumber>;
|
|
144
|
+
rotation: z.ZodDefault<z.ZodNumber>;
|
|
145
|
+
wrapS: z.ZodDefault<z.ZodEnum<{
|
|
146
|
+
Repeat: "Repeat";
|
|
147
|
+
ClampToEdge: "ClampToEdge";
|
|
148
|
+
MirroredRepeat: "MirroredRepeat";
|
|
149
|
+
}>>;
|
|
150
|
+
wrapT: z.ZodDefault<z.ZodEnum<{
|
|
151
|
+
Repeat: "Repeat";
|
|
152
|
+
ClampToEdge: "ClampToEdge";
|
|
153
|
+
MirroredRepeat: "MirroredRepeat";
|
|
154
|
+
}>>;
|
|
155
|
+
normalScaleX: z.ZodDefault<z.ZodNumber>;
|
|
156
|
+
normalScaleY: z.ZodDefault<z.ZodNumber>;
|
|
157
|
+
emissiveIntensity: z.ZodDefault<z.ZodNumber>;
|
|
158
|
+
displacementScale: z.ZodDefault<z.ZodNumber>;
|
|
159
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
160
|
+
flipY: z.ZodDefault<z.ZodBoolean>;
|
|
161
|
+
bumpScale: z.ZodDefault<z.ZodNumber>;
|
|
162
|
+
emissiveColor: z.ZodDefault<z.ZodString>;
|
|
163
|
+
aoMapIntensity: z.ZodDefault<z.ZodNumber>;
|
|
164
|
+
side: z.ZodDefault<z.ZodNumber>;
|
|
165
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
166
|
+
lightMapIntensity: z.ZodDefault<z.ZodNumber>;
|
|
167
|
+
}, z.core.$strip>;
|
|
168
|
+
}, z.core.$strip>;
|
|
169
|
+
export type MaterialPresetPayload = z.infer<typeof MaterialPresetPayloadSchema>;
|
|
60
170
|
export declare const DEFAULT_MATERIALS: Record<MaterialPreset, MaterialProperties>;
|
|
61
171
|
export declare function resolveMaterial(material?: MaterialSchema): MaterialProperties;
|
|
62
172
|
//# sourceMappingURL=material.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/schema/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/schema/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,cAAc;;;;;;;;;;;EAWzB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,kBAAkB;;;;;;;;;;;iBAO7B,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEnE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAWzB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,cAAc;;;;;;;;;;;;EAYzB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,eAAe;;;;EAAsD,CAAA;AAClF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,kBAAkB;;;;;;;;;;;iBAW7B,CAAA;AACF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAE7D,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGtC,CAAA;AACF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAiFxE,CAAA;AAED,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,kBAAkB,CAiB7E"}
|
package/dist/schema/material.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { AssetUrl } from './asset-url';
|
|
2
3
|
export const MaterialPreset = z.enum([
|
|
3
4
|
'white',
|
|
4
5
|
'brick',
|
|
@@ -20,16 +21,69 @@ export const MaterialProperties = z.object({
|
|
|
20
21
|
side: z.enum(['front', 'back', 'double']).default('front'),
|
|
21
22
|
});
|
|
22
23
|
export const MaterialSchema = z.object({
|
|
24
|
+
id: z.string().optional(),
|
|
23
25
|
preset: MaterialPreset.optional(),
|
|
24
26
|
properties: MaterialProperties.optional(),
|
|
25
27
|
texture: z
|
|
26
28
|
.object({
|
|
27
|
-
url:
|
|
29
|
+
url: AssetUrl,
|
|
28
30
|
repeat: z.tuple([z.number(), z.number()]).optional(),
|
|
29
31
|
scale: z.number().optional(),
|
|
30
32
|
})
|
|
31
33
|
.optional(),
|
|
32
34
|
});
|
|
35
|
+
export const MaterialTarget = z.enum([
|
|
36
|
+
'wall',
|
|
37
|
+
'roof',
|
|
38
|
+
'roof-segment',
|
|
39
|
+
'stair',
|
|
40
|
+
'stair-segment',
|
|
41
|
+
'fence',
|
|
42
|
+
'column',
|
|
43
|
+
'slab',
|
|
44
|
+
'ceiling',
|
|
45
|
+
'door',
|
|
46
|
+
'window',
|
|
47
|
+
]);
|
|
48
|
+
export const TextureWrapMode = z.enum(['Repeat', 'ClampToEdge', 'MirroredRepeat']);
|
|
49
|
+
export const MaterialMapsSchema = z.object({
|
|
50
|
+
albedoMap: AssetUrl.optional(),
|
|
51
|
+
metalnessMap: AssetUrl.optional(),
|
|
52
|
+
roughnessMap: AssetUrl.optional(),
|
|
53
|
+
normalMap: AssetUrl.optional(),
|
|
54
|
+
displacementMap: AssetUrl.optional(),
|
|
55
|
+
aoMap: AssetUrl.optional(),
|
|
56
|
+
emissiveMap: AssetUrl.optional(),
|
|
57
|
+
bumpMap: AssetUrl.optional(),
|
|
58
|
+
alphaMap: AssetUrl.optional(),
|
|
59
|
+
lightMap: AssetUrl.optional(),
|
|
60
|
+
});
|
|
61
|
+
export const MaterialMapPropertiesSchema = z.object({
|
|
62
|
+
color: z.string().default('#ffffff'),
|
|
63
|
+
roughness: z.number().min(0).max(1).default(0.5),
|
|
64
|
+
metalness: z.number().min(0).max(1).default(0),
|
|
65
|
+
repeatX: z.number().default(1),
|
|
66
|
+
repeatY: z.number().default(1),
|
|
67
|
+
rotation: z.number().default(0),
|
|
68
|
+
wrapS: TextureWrapMode.default('Repeat'),
|
|
69
|
+
wrapT: TextureWrapMode.default('Repeat'),
|
|
70
|
+
normalScaleX: z.number().default(1),
|
|
71
|
+
normalScaleY: z.number().default(1),
|
|
72
|
+
emissiveIntensity: z.number().default(1),
|
|
73
|
+
displacementScale: z.number().default(0.02),
|
|
74
|
+
transparent: z.boolean().default(false),
|
|
75
|
+
flipY: z.boolean().default(true),
|
|
76
|
+
bumpScale: z.number().default(1),
|
|
77
|
+
emissiveColor: z.string().default('#000000'),
|
|
78
|
+
aoMapIntensity: z.number().default(1),
|
|
79
|
+
side: z.number().default(0),
|
|
80
|
+
opacity: z.number().min(0).max(1).default(1),
|
|
81
|
+
lightMapIntensity: z.number().default(1),
|
|
82
|
+
});
|
|
83
|
+
export const MaterialPresetPayloadSchema = z.object({
|
|
84
|
+
maps: MaterialMapsSchema,
|
|
85
|
+
mapProperties: MaterialMapPropertiesSchema,
|
|
86
|
+
});
|
|
33
87
|
export const DEFAULT_MATERIALS = {
|
|
34
88
|
white: {
|
|
35
89
|
color: '#ffffff',
|
|
@@ -19,8 +19,8 @@ export declare const CeilingNode: z.ZodObject<{
|
|
|
19
19
|
type: z.ZodDefault<z.ZodLiteral<"ceiling">>;
|
|
20
20
|
children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>>>;
|
|
21
21
|
material: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
id: z.ZodOptional<z.ZodString>;
|
|
22
23
|
preset: z.ZodOptional<z.ZodEnum<{
|
|
23
|
-
custom: "custom";
|
|
24
24
|
white: "white";
|
|
25
25
|
brick: "brick";
|
|
26
26
|
concrete: "concrete";
|
|
@@ -30,6 +30,7 @@ export declare const CeilingNode: z.ZodObject<{
|
|
|
30
30
|
plaster: "plaster";
|
|
31
31
|
tile: "tile";
|
|
32
32
|
marble: "marble";
|
|
33
|
+
custom: "custom";
|
|
33
34
|
}>>;
|
|
34
35
|
properties: z.ZodOptional<z.ZodObject<{
|
|
35
36
|
color: z.ZodDefault<z.ZodString>;
|
|
@@ -49,9 +50,18 @@ export declare const CeilingNode: z.ZodObject<{
|
|
|
49
50
|
scale: z.ZodOptional<z.ZodNumber>;
|
|
50
51
|
}, z.core.$strip>>;
|
|
51
52
|
}, z.core.$strip>>;
|
|
53
|
+
materialPreset: z.ZodOptional<z.ZodString>;
|
|
52
54
|
polygon: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
53
55
|
holes: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>>;
|
|
56
|
+
holeMetadata: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
57
|
+
source: z.ZodDefault<z.ZodEnum<{
|
|
58
|
+
stair: "stair";
|
|
59
|
+
manual: "manual";
|
|
60
|
+
}>>;
|
|
61
|
+
stairId: z.ZodOptional<z.ZodString>;
|
|
62
|
+
}, z.core.$strip>>>;
|
|
54
63
|
height: z.ZodDefault<z.ZodNumber>;
|
|
64
|
+
autoFromWalls: z.ZodDefault<z.ZodBoolean>;
|
|
55
65
|
}, z.core.$strip>;
|
|
56
66
|
export type CeilingNode = z.infer<typeof CeilingNode>;
|
|
57
67
|
//# sourceMappingURL=ceiling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceiling.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/ceiling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"ceiling.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/ceiling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmBvB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA"}
|
|
@@ -3,16 +3,22 @@ import { z } from 'zod';
|
|
|
3
3
|
import { BaseNode, nodeType, objectId } from '../base';
|
|
4
4
|
import { MaterialSchema } from '../material';
|
|
5
5
|
import { ItemNode } from './item';
|
|
6
|
+
import { SurfaceHoleMetadata } from './surface-hole-metadata';
|
|
6
7
|
export const CeilingNode = BaseNode.extend({
|
|
7
8
|
id: objectId('ceiling'),
|
|
8
9
|
type: nodeType('ceiling'),
|
|
9
10
|
children: z.array(ItemNode.shape.id).default([]),
|
|
10
11
|
material: MaterialSchema.optional(),
|
|
12
|
+
materialPreset: z.string().optional(),
|
|
11
13
|
polygon: z.array(z.tuple([z.number(), z.number()])),
|
|
12
14
|
holes: z.array(z.array(z.tuple([z.number(), z.number()]))).default([]),
|
|
15
|
+
holeMetadata: z.array(SurfaceHoleMetadata).default([]),
|
|
13
16
|
height: z.number().default(2.5), // Height in meters
|
|
17
|
+
autoFromWalls: z.boolean().default(false),
|
|
14
18
|
}).describe(dedent `
|
|
15
19
|
Ceiling node - used to represent a ceiling in the building
|
|
16
20
|
- polygon: array of [x, z] points defining the ceiling boundary
|
|
17
21
|
- holes: array of polygons representing holes in the ceiling
|
|
22
|
+
- holeMetadata: metadata parallel to holes, used to preserve manual and stair-managed cutouts
|
|
23
|
+
- autoFromWalls: whether the ceiling is automatically generated from a closed wall loop
|
|
18
24
|
`);
|