From 0870214528af0931ae7d2cd0ead62bd95eedb498 Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Tue, 4 Aug 2026 09:12:42 -0500 Subject: [PATCH 1/8] Test properties file --- .sonarcloud.properties | 1 + 1 file changed, 1 insertion(+) create mode 100644 .sonarcloud.properties diff --git a/.sonarcloud.properties b/.sonarcloud.properties new file mode 100644 index 000000000..589c5daa2 --- /dev/null +++ b/.sonarcloud.properties @@ -0,0 +1 @@ +sonar.exclusions=examples/** From 9fcfa74475ce03aa05d16c0050e2155cb88a03e5 Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Tue, 4 Aug 2026 10:56:46 -0500 Subject: [PATCH 2/8] Script fixes --- .github/workflows/branch.yml | 6 +++--- .github/workflows/master.yml | 8 ++++---- .github/workflows/testing.yml | 4 ++-- scripts/generate_docs.sh | 2 +- scripts/publish_canary.sh | 16 ++++++++-------- scripts/publish_release.sh | 2 +- scripts/publish_testing.sh | 16 ++++++++-------- scripts/release.sh | 4 ++-- scripts/release_notes.sh | 3 ++- scripts/utils.sh | 4 ++++ 10 files changed, 35 insertions(+), 30 deletions(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 84539e364..d1fb598dc 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -50,7 +50,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Lint" run: "yarn lint" test: @@ -73,7 +73,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Test" run: "yarn test:ci" docs: @@ -96,7 +96,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Generate docs" run: "yarn generate:docs" - name: "Test docs" diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 1991f20b8..813224773 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -23,7 +23,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install --frozen-lockfile" + run: "yarn install --ignore-scripts --frozen-lockfile" - name: "Build" run: "yarn build" - name: "Test" @@ -78,7 +78,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Publish Canary to NPM" env: NODE_AUTH_TOKEN: "${{ secrets.NPMJS_ACCESS_TOKEN }}" @@ -116,7 +116,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Publish Release to NPM" env: NODE_AUTH_TOKEN: "${{ secrets.NPMJS_ACCESS_TOKEN }}" @@ -147,7 +147,7 @@ jobs: with: node-version: "${{ steps.nvm.outputs.NVMRC }}" - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Generate docs" run: "yarn generate:docs" - name: "Upload docs as pages artifact" diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index bf66a5d15..d1b489f75 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -23,7 +23,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install --frozen-lockfile" + run: "yarn install --ignore-scripts --frozen-lockfile" - name: "Build" run: "yarn build" - name: "Upload build artifacts" @@ -61,7 +61,7 @@ jobs: - name: Enable Corepack run: corepack enable - name: "Install" - run: "yarn install" + run: "yarn install --ignore-scripts" - name: "Publish Testing build to NPM" env: NODE_AUTH_TOKEN: "${{ secrets.NPMJS_ACCESS_TOKEN }}" diff --git a/scripts/generate_docs.sh b/scripts/generate_docs.sh index 63e1c5f6e..c3effadc9 100755 --- a/scripts/generate_docs.sh +++ b/scripts/generate_docs.sh @@ -16,7 +16,7 @@ install_mo() { if ! test -x ./.lib/mo then - curl -sSL https://git.io/get-mo -o mo + curl --proto '=https' --tlsv1.2 -sSL https://git.io/get-mo -o mo chmod +x mo mv mo ./.lib/mo fi diff --git a/scripts/publish_canary.sh b/scripts/publish_canary.sh index 69985e8f3..08630c6a1 100755 --- a/scripts/publish_canary.sh +++ b/scripts/publish_canary.sh @@ -10,28 +10,28 @@ preid="canary" dist_tag="canary" next_bump=`jq -r '.nextVersionBump' package.json` version=`jq -r '.version' lerna.json` -next_version=`npx semver "$version" --increment "$next_bump"` +next_version=`npx_ignore_scripts semver "$version" --increment "$next_bump"` published_canary_versions=`npm view @vertexvis/viewer --json versions | jq --arg version "$next_version-" -r '.[] | select(contains($version) and contains("canary"))'` if test -n "$published_canary_versions" then - published_version=`npx semver $(echo "$published_canary_versions") | tail -1` + published_version=`npx_ignore_scripts semver $(echo "$published_canary_versions") | tail -1` echo "Detected published canary version $published_version" - next_canary_version=`npx semver "$published_version" --increment prerelease` + next_canary_version=`npx_ignore_scripts semver "$published_version" --increment prerelease` echo "Publishing canary version $next_canary_version" - npx lerna version --no-push --no-git-tag-version --exact "$next_canary_version" --yes + npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact "$next_canary_version" --yes git commit -am "Canary release $next_canary_version" - npx lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes + npx_ignore_scripts lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes else echo "No published canary version found for $next_version" - next_canary_version=`npx semver "$version" --increment pre"$next_bump" --preid "$preid"` + next_canary_version=`npx_ignore_scripts semver "$version" --increment pre"$next_bump" --preid "$preid"` echo "Publishing canary version $next_canary_version" - npx lerna version --no-push --no-git-tag-version --exact "$next_canary_version" --yes + npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact "$next_canary_version" --yes git commit -am "Canary release $next_canary_version" - npx lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes + npx_ignore_scripts lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes fi diff --git a/scripts/publish_release.sh b/scripts/publish_release.sh index 7295aa14e..9a16ab1a8 100755 --- a/scripts/publish_release.sh +++ b/scripts/publish_release.sh @@ -11,7 +11,7 @@ version="v$(get_version)" notes="$(get_release_notes)" sha="$(git rev-parse HEAD)" -npx lerna publish from-package --yes +npx_ignore_scripts lerna publish from-package --yes curl -s -X POST https://api.github.com/repos/$REPOSITORY/releases \ -H "Authorization: token $GITHUB_TOKEN" \ diff --git a/scripts/publish_testing.sh b/scripts/publish_testing.sh index 165f6f872..2356ddb7c 100755 --- a/scripts/publish_testing.sh +++ b/scripts/publish_testing.sh @@ -10,28 +10,28 @@ preid="testing" dist_tag="testing" next_bump=`jq -r '.nextVersionBump' package.json` version=`jq -r '.version' lerna.json` -next_version=`npx semver "$version" --increment "$next_bump"` +next_version=`npx_ignore_scripts semver "$version" --increment "$next_bump"` published_testing_versions=`npm view @vertexvis/viewer --json versions | jq --arg version "$next_version-" -r '.[] | select(contains($version) and contains("testing"))'` if test -n "$published_testing_versions" then - published_version=`npx semver $(echo "$published_testing_versions") | tail -1` + published_version=`npx_ignore_scripts semver $(echo "$published_testing_versions") | tail -1` echo "Detected published testing version $published_version" - next_testing_version=`npx semver "$published_version" --increment prerelease` + next_testing_version=`npx_ignore_scripts semver "$published_version" --increment prerelease` echo "Publishing testing version $next_testing_version" - npx lerna version --no-push --no-git-tag-version --exact "$next_testing_version" --yes + npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact "$next_testing_version" --yes git commit -am "testing release $next_testing_version" - npx lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes + npx_ignore_scripts lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes else echo "No published testing version found for $next_version" - next_testing_version=`npx semver "$version" --increment pre"$next_bump" --preid "$preid"` + next_testing_version=`npx_ignore_scripts semver "$version" --increment pre"$next_bump" --preid "$preid"` echo "Publishing testing version $next_testing_version" - npx lerna version --no-push --no-git-tag-version --exact "$next_testing_version" --yes + npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact "$next_testing_version" --yes git commit -am "testing release $next_testing_version" - npx lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes + npx_ignore_scripts lerna publish from-package --canary --preid "$preid" --exact --dist-tag "$dist_tag" --yes fi diff --git a/scripts/release.sh b/scripts/release.sh index ee8666233..5e7206a7c 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -32,10 +32,10 @@ git checkout --track=direct -b $local_branch # Bump version and generate docs with updated versions if test -n "$ASK_VERSION" then - npx lerna version --no-push --no-git-tag-version --exact + npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact else next_bump=`jq -r '.nextVersionBump' package.json` - npx lerna version --no-push --no-git-tag-version --exact "$next_bump" + npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact "$next_bump" fi yarn install diff --git a/scripts/release_notes.sh b/scripts/release_notes.sh index b817a3053..4aa55ac24 100755 --- a/scripts/release_notes.sh +++ b/scripts/release_notes.sh @@ -27,7 +27,8 @@ function get_release_notes() { if [ ! -z "$PR_NUMBER" ]; then DESC=$( - curl -L https://api.github.com/repos/$REPOSITORY/pulls/$PR_NUMBER \ + curl --proto '=https' --tlsv1.2 \ + -L https://api.github.com/repos/$REPOSITORY/pulls/$PR_NUMBER \ -H "Accept: application/vnd.github+json" \ -H "Authorization: token $GITHUB_TOKEN" \ | jq '.body' diff --git a/scripts/utils.sh b/scripts/utils.sh index 6ce88236b..20b10553c 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -3,3 +3,7 @@ function get_version { jq -r '.version' ./lerna.json } + +function npx_ignore_scripts { + npx --ignore-scripts "$@" +} From eabade2bb3278b076810727bb07dd6bde1d8fcd9 Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Tue, 4 Aug 2026 17:42:38 -0500 Subject: [PATCH 3/8] Reliability issue fixes --- packages/geometry/src/boundingBox.ts | 5 ++- packages/geometry/src/vector3.ts | 2 +- packages/utils/src/async.ts | 2 +- packages/utils/src/binaryReader.ts | 2 +- packages/utils/src/color.ts | 16 +++++----- .../components/scene-tree/lib/controller.ts | 2 +- .../lib/indicator.ts | 2 +- .../viewer-hit-result-indicator/lib/plane.ts | 2 +- .../viewer-hit-result-indicator/lib/point.ts | 2 +- .../components/viewer-markup/markup-utils.ts | 2 +- .../viewer-measurement-line.spec.tsx | 32 +++++++++---------- .../viewer-pin-label/viewer-pin-label.tsx | 6 ++-- .../viewer-transform-widget-components.tsx | 6 ++-- .../viewer-transform-widget.tsx | 2 +- packages/viewer/src/lib/grpc.ts | 2 +- .../interactions/baseInteractionHandler.ts | 6 ++-- .../src/lib/interactions/mouseInteractions.ts | 6 ++-- packages/viewer/src/lib/rendering/canvas.ts | 2 +- .../src/lib/transforms/axis-translation.ts | 2 +- packages/viewer/src/lib/transforms/hits.ts | 2 +- packages/viewer/src/lib/transforms/line.ts | 12 ++++--- packages/viewer/src/testing/canvases.ts | 27 ++++++++-------- scripts/detect_release.sh | 2 +- scripts/generate_docs.sh | 6 ++-- scripts/generate_vscode_workspace.sh | 6 ++-- scripts/publish_canary.sh | 2 +- scripts/publish_testing.sh | 2 +- scripts/release.sh | 8 ++--- scripts/release_notes.sh | 2 +- 29 files changed, 87 insertions(+), 83 deletions(-) diff --git a/packages/geometry/src/boundingBox.ts b/packages/geometry/src/boundingBox.ts index 1c281fc95..b5c1976a7 100644 --- a/packages/geometry/src/boundingBox.ts +++ b/packages/geometry/src/boundingBox.ts @@ -78,10 +78,9 @@ export function union( ): BoundingBox; export function union(...boxes: BoundingBox[]): BoundingBox | undefined; export function union(box: BoundingBox, ...rest: BoundingBox[]): BoundingBox { - const boxes = [box, ...rest]; - return boxes.reduce((a, b) => { + return rest.reduce((a, b) => { return create(Vector3.min(a.min, b.min), Vector3.max(a.max, b.max)); - }); + }, box); } /* eslint-enable padding-line-between-statements */ diff --git a/packages/geometry/src/vector3.ts b/packages/geometry/src/vector3.ts index 053691164..89725bc53 100644 --- a/packages/geometry/src/vector3.ts +++ b/packages/geometry/src/vector3.ts @@ -61,7 +61,7 @@ export function create(...args: any[]): Vector3 { * component. A component is invalid if it contains a non-finite or NaN value. */ export function isValid({ x, y, z }: Vector3): boolean { - return [x, y, z].every((v) => isFinite(v) && !isNaN(v)); + return [x, y, z].every((v) => Number.isFinite(v) && !Number.isNaN(v)); } /** diff --git a/packages/utils/src/async.ts b/packages/utils/src/async.ts index 3b212cedd..01c63c857 100644 --- a/packages/utils/src/async.ts +++ b/packages/utils/src/async.ts @@ -86,7 +86,7 @@ export async function timeout(...args: unknown[]): Promise { return timeout; } } else { - return Promise.reject('First argument to `timeout` must be a number'); + return Promise.reject(new Error('First argument to `timeout` must be a number')); } } diff --git a/packages/utils/src/binaryReader.ts b/packages/utils/src/binaryReader.ts index d678580b3..3e4e87d35 100644 --- a/packages/utils/src/binaryReader.ts +++ b/packages/utils/src/binaryReader.ts @@ -54,7 +54,7 @@ export const readUtf8String = ( length: number, reader: BinaryReader, ): BinaryReaderValue => { - const value = String.fromCharCode.apply( + const value = String.fromCodePoint.apply( null, Array.from(new Uint8Array(reader.data.buffer, reader.offset, length)), ); diff --git a/packages/utils/src/color.ts b/packages/utils/src/color.ts index c4b37e4e4..1991766d4 100644 --- a/packages/utils/src/color.ts +++ b/packages/utils/src/color.ts @@ -59,7 +59,7 @@ export const fromNumber = (num: number): Color => { export const fromHexString = (str: string): Color | undefined => { const match = hexRegex.exec(str); if (match != null) { - return fromNumber(parseInt(match[2], 16)); + return fromNumber(Number.parseInt(match[2], 16)); } }; @@ -72,19 +72,19 @@ export const fromCss = (css: string): Color | undefined => { const rgbMatch = rgbRegex.exec(css); if (rgbMatch != null) { return create( - parseInt(rgbMatch[1]), - parseInt(rgbMatch[2]), - parseInt(rgbMatch[3]), + Number.parseInt(rgbMatch[1]), + Number.parseInt(rgbMatch[2]), + Number.parseInt(rgbMatch[3]), ); } const rgbaMatch = rgbaRegex.exec(css); if (rgbaMatch != null) { return create( - parseInt(rgbaMatch[1]), - parseInt(rgbaMatch[2]), - parseInt(rgbaMatch[3]), - Math.floor(parseFloat(rgbaMatch[4]) * 255), + Number.parseInt(rgbaMatch[1]), + Number.parseInt(rgbaMatch[2]), + Number.parseInt(rgbaMatch[3]), + Math.floor(Number.parseFloat(rgbaMatch[4]) * 255), ); } diff --git a/packages/viewer/src/components/scene-tree/lib/controller.ts b/packages/viewer/src/components/scene-tree/lib/controller.ts index 9d05e67fc..683f5c8a4 100644 --- a/packages/viewer/src/components/scene-tree/lib/controller.ts +++ b/packages/viewer/src/components/scene-tree/lib/controller.ts @@ -164,7 +164,7 @@ export class SceneTreeController { private pages = new Map(); private activeRowRange = [0, 0]; private metadataKeys: MetadataKey[] = []; - private debugLogs = false; + private debugLogs = true; private pendingFilterGrpcRes?: UnaryResponse; private reconnectTimer?: number; diff --git a/packages/viewer/src/components/viewer-hit-result-indicator/lib/indicator.ts b/packages/viewer/src/components/viewer-hit-result-indicator/lib/indicator.ts index 215d8699c..c99e3124a 100644 --- a/packages/viewer/src/components/viewer-hit-result-indicator/lib/indicator.ts +++ b/packages/viewer/src/components/viewer-hit-result-indicator/lib/indicator.ts @@ -226,7 +226,7 @@ export class HitIndicator extends ReglComponent { private getPlaneOpacity(): number { if (this.planeOpacity != null) { return typeof this.planeOpacity === 'string' - ? parseFloat(this.planeOpacity) + ? Number.parseFloat(this.planeOpacity) : this.planeOpacity; } return DEFAULT_PLANE_OPACITY; diff --git a/packages/viewer/src/components/viewer-hit-result-indicator/lib/plane.ts b/packages/viewer/src/components/viewer-hit-result-indicator/lib/plane.ts index 258d31a86..0d5771283 100644 --- a/packages/viewer/src/components/viewer-hit-result-indicator/lib/plane.ts +++ b/packages/viewer/src/components/viewer-hit-result-indicator/lib/plane.ts @@ -58,7 +58,7 @@ export function computePlaneNdcValues( const world = [bottomLeft, topLeft, topRight, bottomRight]; return new MeshPoints( - !isNaN(worldX.x), + !Number.isNaN(worldX.x), [bottomLeft, topLeft, topRight, bottomRight], world.map((v) => Vector3.multiplyByTransformMatrixColumnMajor( diff --git a/packages/viewer/src/components/viewer-hit-result-indicator/lib/point.ts b/packages/viewer/src/components/viewer-hit-result-indicator/lib/point.ts index 29befdc88..30494e09b 100644 --- a/packages/viewer/src/components/viewer-hit-result-indicator/lib/point.ts +++ b/packages/viewer/src/components/viewer-hit-result-indicator/lib/point.ts @@ -71,7 +71,7 @@ export function computePointNdcValues( ]; return new MeshPoints( - !isNaN(worldX.x), + !Number.isNaN(worldX.x), world, world.map((v) => Vector3.multiplyByTransformMatrixColumnMajor( diff --git a/packages/viewer/src/components/viewer-markup/markup-utils.ts b/packages/viewer/src/components/viewer-markup/markup-utils.ts index c79c49a1e..f66495ed5 100644 --- a/packages/viewer/src/components/viewer-markup/markup-utils.ts +++ b/packages/viewer/src/components/viewer-markup/markup-utils.ts @@ -323,7 +323,7 @@ export function isVertexViewerMarkupElement( } export function isValidPointData(...points: Point.Point[]): boolean { - return points.every((pt) => !isNaN(pt.x) && !isNaN(pt.y)); + return points.every((pt) => !Number.isNaN(pt.x) && !Number.isNaN(pt.y)); } export function isValidStartEvent(event: PointerEvent): boolean { diff --git a/packages/viewer/src/components/viewer-measurement-line/viewer-measurement-line.spec.tsx b/packages/viewer/src/components/viewer-measurement-line/viewer-measurement-line.spec.tsx index 0bb29b736..45a027272 100644 --- a/packages/viewer/src/components/viewer-measurement-line/viewer-measurement-line.spec.tsx +++ b/packages/viewer/src/components/viewer-measurement-line/viewer-measurement-line.spec.tsx @@ -59,28 +59,28 @@ describe('vertex-viewer-measurement-line', () => { ?.querySelector('.line-fill') ?.querySelector('.end-cap') as SVGLineElement; - expect(parseFloat(fillStartCap.getAttribute('x1') ?? '')).toBeCloseTo(0); - expect(parseFloat(fillStartCap.getAttribute('y1') ?? '')).toBeCloseTo(5); - expect(parseFloat(fillStartCap.getAttribute('x2') ?? '')).toBeCloseTo(0); - expect(parseFloat(fillStartCap.getAttribute('y2') ?? '')).toBeCloseTo(-5); + expect(Number.parseFloat(fillStartCap.getAttribute('x1') ?? '')).toBeCloseTo(0); + expect(Number.parseFloat(fillStartCap.getAttribute('y1') ?? '')).toBeCloseTo(5); + expect(Number.parseFloat(fillStartCap.getAttribute('x2') ?? '')).toBeCloseTo(0); + expect(Number.parseFloat(fillStartCap.getAttribute('y2') ?? '')).toBeCloseTo(-5); - expect(parseFloat(fillEndCap.getAttribute('x1') ?? '')).toBeCloseTo(100); - expect(parseFloat(fillEndCap.getAttribute('y1') ?? '')).toBeCloseTo(5); - expect(parseFloat(fillEndCap.getAttribute('x2') ?? '')).toBeCloseTo(100); - expect(parseFloat(fillEndCap.getAttribute('y2') ?? '')).toBeCloseTo(-5); + expect(Number.parseFloat(fillEndCap.getAttribute('x1') ?? '')).toBeCloseTo(100); + expect(Number.parseFloat(fillEndCap.getAttribute('y1') ?? '')).toBeCloseTo(5); + expect(Number.parseFloat(fillEndCap.getAttribute('x2') ?? '')).toBeCloseTo(100); + expect(Number.parseFloat(fillEndCap.getAttribute('y2') ?? '')).toBeCloseTo(-5); - expect(parseFloat(strokeStartCap.getAttribute('x1') ?? '')).toBeCloseTo(0); - expect(parseFloat(strokeStartCap.getAttribute('y1') ?? '')).toBeCloseTo( + expect(Number.parseFloat(strokeStartCap.getAttribute('x1') ?? '')).toBeCloseTo(0); + expect(Number.parseFloat(strokeStartCap.getAttribute('y1') ?? '')).toBeCloseTo( 5.5, ); - expect(parseFloat(strokeStartCap.getAttribute('x2') ?? '')).toBeCloseTo(0); - expect(parseFloat(strokeStartCap.getAttribute('y2') ?? '')).toBeCloseTo( + expect(Number.parseFloat(strokeStartCap.getAttribute('x2') ?? '')).toBeCloseTo(0); + expect(Number.parseFloat(strokeStartCap.getAttribute('y2') ?? '')).toBeCloseTo( -5.5, ); - expect(parseFloat(strokeEndCap.getAttribute('x1') ?? '')).toBeCloseTo(100); - expect(parseFloat(strokeEndCap.getAttribute('y1') ?? '')).toBeCloseTo(5.5); - expect(parseFloat(strokeEndCap.getAttribute('x2') ?? '')).toBeCloseTo(100); - expect(parseFloat(strokeEndCap.getAttribute('y2') ?? '')).toBeCloseTo(-5.5); + expect(Number.parseFloat(strokeEndCap.getAttribute('x1') ?? '')).toBeCloseTo(100); + expect(Number.parseFloat(strokeEndCap.getAttribute('y1') ?? '')).toBeCloseTo(5.5); + expect(Number.parseFloat(strokeEndCap.getAttribute('x2') ?? '')).toBeCloseTo(100); + expect(Number.parseFloat(strokeEndCap.getAttribute('y2') ?? '')).toBeCloseTo(-5.5); }); }); diff --git a/packages/viewer/src/components/viewer-pin-label/viewer-pin-label.tsx b/packages/viewer/src/components/viewer-pin-label/viewer-pin-label.tsx index 27074f956..f8574e6f1 100644 --- a/packages/viewer/src/components/viewer-pin-label/viewer-pin-label.tsx +++ b/packages/viewer/src/components/viewer-pin-label/viewer-pin-label.tsx @@ -313,9 +313,9 @@ export class VertexPinLabel { this.textareaRows = Math.max( 1, Math.ceil( - (parseFloat(computedStyles.getPropertyValue('height')) - - parseFloat(computedStyles.getPropertyValue('borderWidth')) * 2) / - parseFloat(computedStyles.getPropertyValue('lineHeight')), + (Number.parseFloat(computedStyles.getPropertyValue('height')) - + Number.parseFloat(computedStyles.getPropertyValue('borderWidth')) * 2) / + Number.parseFloat(computedStyles.getPropertyValue('lineHeight')), ), ); } diff --git a/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget-components.tsx b/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget-components.tsx index b05b1364a..97f8f8eaa 100644 --- a/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget-components.tsx +++ b/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget-components.tsx @@ -73,10 +73,10 @@ export const TransformWidgetInput: FunctionalComponent< }) => { const handleChange = (event: Event): void => { if (event.target != null) { - const parsed = parseFloat((event.target as HTMLInputElement).value); + const parsed = Number.parseFloat((event.target as HTMLInputElement).value); - if (!isNaN(parsed)) { - onChange?.(parseFloat((event.target as HTMLInputElement).value)); + if (!Number.isNaN(parsed)) { + onChange?.(Number.parseFloat((event.target as HTMLInputElement).value)); } } }; diff --git a/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget.tsx b/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget.tsx index 559497ba8..5c752ebe5 100644 --- a/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget.tsx +++ b/packages/viewer/src/components/viewer-transform-widget/viewer-transform-widget.tsx @@ -1048,7 +1048,7 @@ export class ViewerTransformWidget { if (this.inputRef != null) { const definedValue = this.getDisplayedDistance() ?? this.getDisplayedAngle() ?? 0; - const displayValue = `${parseFloat( + const displayValue = `${Number.parseFloat( definedValue.toFixed(this.decimalPlaces), )}`; diff --git a/packages/viewer/src/lib/grpc.ts b/packages/viewer/src/lib/grpc.ts index a28ec77cc..52bec2c25 100644 --- a/packages/viewer/src/lib/grpc.ts +++ b/packages/viewer/src/lib/grpc.ts @@ -17,7 +17,7 @@ export function requestUnary( return new Promise((resolve, reject) => { caller((err, res) => { if (err != null) { - reject(err); + reject(err instanceof Error ? err : new Error(String(err))); } else if (res != null) { resolve(res); } else { diff --git a/packages/viewer/src/lib/interactions/baseInteractionHandler.ts b/packages/viewer/src/lib/interactions/baseInteractionHandler.ts index a998877c6..1b45dc581 100644 --- a/packages/viewer/src/lib/interactions/baseInteractionHandler.ts +++ b/packages/viewer/src/lib/interactions/baseInteractionHandler.ts @@ -353,14 +353,14 @@ export abstract class BaseInteractionHandler implements InteractionHandler { if (this.bodyStyleCache == null) { const bodyStyle = window.getComputedStyle(document.body); const fontSize = - parseFloat(bodyStyle.getPropertyValue('fontSize')) || DEFAULT_FONT_SIZE; - const lineHeight = parseFloat(bodyStyle.getPropertyValue('lineHeight')); + Number.parseFloat(bodyStyle.getPropertyValue('fontSize')) || DEFAULT_FONT_SIZE; + const lineHeight = Number.parseFloat(bodyStyle.getPropertyValue('lineHeight')); this.bodyStyleCache = { lineHeightPixels: Number.isFinite(lineHeight) ? lineHeight : fontSize * DEFAULT_FONT_TO_LINE_HEIGHT_MULTIPLIER, height: - parseFloat(bodyStyle.getPropertyValue('height')) || + Number.parseFloat(bodyStyle.getPropertyValue('height')) || window.innerHeight, }; window.setTimeout(() => { diff --git a/packages/viewer/src/lib/interactions/mouseInteractions.ts b/packages/viewer/src/lib/interactions/mouseInteractions.ts index e3e1af551..dda1d30a0 100644 --- a/packages/viewer/src/lib/interactions/mouseInteractions.ts +++ b/packages/viewer/src/lib/interactions/mouseInteractions.ts @@ -26,15 +26,15 @@ export abstract class MouseInteraction { canvasPosition: Point.Point, api: InteractionApi, element: HTMLElement, - ): void { + ): void | Promise { // noop } - public drag(event: MouseEvent, api: InteractionApi): void { + public drag(event: MouseEvent, api: InteractionApi): void | Promise { // noop } - public endDrag(event: MouseEvent, api: InteractionApi): void { + public endDrag(event: MouseEvent, api: InteractionApi): void | Promise { if (this.currentPosition != null) { api.endInteraction(); this.currentPosition = undefined; diff --git a/packages/viewer/src/lib/rendering/canvas.ts b/packages/viewer/src/lib/rendering/canvas.ts index 1aef21be6..cde3b8a6a 100644 --- a/packages/viewer/src/lib/rendering/canvas.ts +++ b/packages/viewer/src/lib/rendering/canvas.ts @@ -91,7 +91,7 @@ export function measureCanvasRenderer( } const avgFps = - fpsHistory.reduce((res, num) => res + num) / fpsHistory.length; + fpsHistory.reduce((res, num) => res + num, 0) / fpsHistory.length; console.debug(`Paint rate: ${fpsFrameCount}fps`); console.debug(`Paint rate (avg): ${avgFps}`); fpsFrameCount = undefined; diff --git a/packages/viewer/src/lib/transforms/axis-translation.ts b/packages/viewer/src/lib/transforms/axis-translation.ts index 18824a2ab..e4edf579b 100644 --- a/packages/viewer/src/lib/transforms/axis-translation.ts +++ b/packages/viewer/src/lib/transforms/axis-translation.ts @@ -83,7 +83,7 @@ export function computeArrowNdcValues( const up = Ray.at(yRay, triangleSize * sizeScalar * 3); return new TriangleMeshPoints( - !isNaN(worldX.x), + !Number.isNaN(worldX.x), position, left, right, diff --git a/packages/viewer/src/lib/transforms/hits.ts b/packages/viewer/src/lib/transforms/hits.ts index fb59d897d..76ea9fe6f 100644 --- a/packages/viewer/src/lib/transforms/hits.ts +++ b/packages/viewer/src/lib/transforms/hits.ts @@ -91,7 +91,7 @@ export function testTriangle( // if in orthographic to correctly return hit results when close // to the camera. // TODO: revisit with https://vertexvis.atlassian.net/browse/PLAT-1549 - return !isNaN(r) && (r > 0 || frame.scene.camera.isOrthographic()); + return !Number.isNaN(r) && (r > 0 || frame.scene.camera.isOrthographic()); } return false; } diff --git a/packages/viewer/src/lib/transforms/line.ts b/packages/viewer/src/lib/transforms/line.ts index 0ef116ade..640da4209 100644 --- a/packages/viewer/src/lib/transforms/line.ts +++ b/packages/viewer/src/lib/transforms/line.ts @@ -5,6 +5,12 @@ import { JoinStyle, ShapeProps } from 'regl-shape'; import { CreateShape } from '../../lib/transforms/shape'; import { Drawable, DrawablePoints } from './drawable'; +const DEFAULT_AXIS_LINE_SHAPE_PROPS: Partial = { thickness: 3 }; + +const DEFAULT_ROTATION_LINE_SHAPE_PROPS: Partial = { + join: 'round' as JoinStyle, +}; + export class AxisLinePoints implements DrawablePoints { public constructor( public valid: boolean, @@ -36,7 +42,7 @@ export class AxisLine extends Drawable { points: AxisLinePoints, outlineColor: Color.Color | string = '#000000', fillColor: Color.Color | string = '#000000', - shapeProps: Partial = { thickness: 3 }, + shapeProps: Partial = DEFAULT_AXIS_LINE_SHAPE_PROPS, ) { super( createShape, @@ -79,9 +85,7 @@ export class RotationLine extends Drawable { identifier: string, points: RotationLinePoints, outlineColor: Color.Color | string = '#000000', - shapeProps: Partial = { - join: 'round' as JoinStyle, - }, + shapeProps: Partial = DEFAULT_ROTATION_LINE_SHAPE_PROPS, public disabled: boolean = false, ) { super( diff --git a/packages/viewer/src/testing/canvases.ts b/packages/viewer/src/testing/canvases.ts index 365608fb9..0294837b9 100644 --- a/packages/viewer/src/testing/canvases.ts +++ b/packages/viewer/src/testing/canvases.ts @@ -150,31 +150,32 @@ export function makeCallout(value: Partial = {}): CanvasItem { } export function makeLineEndShape( - shape: ArrowEndShape | CircleEndShape | DashEndShape = { - type: 'arrow-end', - width: 1, - filled: true, - }, + shape?: ArrowEndShape | CircleEndShape | DashEndShape, ): ApiEndShape { const s = new ApiEndShape(); + const effectiveShape = shape ?? { + type: 'arrow-end', + filled: true, + width: 1, + }; - if (shape.type === 'arrow-end') { + if (effectiveShape.type === 'arrow-end') { const a = new ApiArrowEndShape(); - a.setFilled(shape.filled); - a.setWidth(shape.width); + a.setFilled(effectiveShape.filled); + a.setWidth(effectiveShape.width); s.setArrow(a); } - if (shape.type === 'circle-end') { + if (effectiveShape.type === 'circle-end') { const c = new ApiCircleEndShape(); - c.setFilled(shape.filled); - c.setDiameter(shape.diameter); + c.setFilled(effectiveShape.filled); + c.setDiameter(effectiveShape.diameter); s.setCircle(c); } - if (shape.type === 'dash-end') { + if (effectiveShape.type === 'dash-end') { const d = new ApiDashEndShape(); - d.setWidth(shape.width); + d.setWidth(effectiveShape.width); s.setDash(d); } diff --git a/scripts/detect_release.sh b/scripts/detect_release.sh index 4bdfe2828..e0e25c321 100755 --- a/scripts/detect_release.sh +++ b/scripts/detect_release.sh @@ -9,7 +9,7 @@ set -e version=$(get_version) published_version=`npm view @vertexvis/viewer --json versions | jq --arg version "$version" -r '.[] | select(. == $version)'` -if test -z "$published_version" +if [[ -z "$published_version" ]] then echo 1 else diff --git a/scripts/generate_docs.sh b/scripts/generate_docs.sh index c3effadc9..bbe568608 100755 --- a/scripts/generate_docs.sh +++ b/scripts/generate_docs.sh @@ -1,11 +1,11 @@ -#/bin/sh +#!/bin/bash # # Script to generate SDK documentation. set -e create_lib_dir() { - if ! test -d ./.lib + if [[ ! -d ./.lib ]] then mkdir ./.lib fi @@ -14,7 +14,7 @@ create_lib_dir() { install_mo() { create_lib_dir - if ! test -x ./.lib/mo + if [[ ! -x ./.lib/mo ]] then curl --proto '=https' --tlsv1.2 -sSL https://git.io/get-mo -o mo chmod +x mo diff --git a/scripts/generate_vscode_workspace.sh b/scripts/generate_vscode_workspace.sh index a99ae94d1..e505b4db5 100755 --- a/scripts/generate_vscode_workspace.sh +++ b/scripts/generate_vscode_workspace.sh @@ -39,7 +39,7 @@ update_workspace_projects() { } update_shadow_root() { - if ! test -d "$shadow_dir" + if [[ ! -d "$shadow_dir" ]] then mkdir "$shadow_dir" fi @@ -48,7 +48,7 @@ update_shadow_root() { for file in $root_files do - if ! test -r "$shadow_dir/$file" + if [[ ! -r "$shadow_dir/$file" ]] then ln -s "../$file" "$shadow_dir/$file" fi @@ -56,7 +56,7 @@ update_shadow_root() { } create_workspace_file() { - if ! test -r "$workspace_file" + if [[ ! -r "$workspace_file" ]] then touch "$workspace_file" jq -n '{"folders": [], "settings": {}}' > $workspace_file diff --git a/scripts/publish_canary.sh b/scripts/publish_canary.sh index 08630c6a1..3954edf9c 100755 --- a/scripts/publish_canary.sh +++ b/scripts/publish_canary.sh @@ -13,7 +13,7 @@ version=`jq -r '.version' lerna.json` next_version=`npx_ignore_scripts semver "$version" --increment "$next_bump"` published_canary_versions=`npm view @vertexvis/viewer --json versions | jq --arg version "$next_version-" -r '.[] | select(contains($version) and contains("canary"))'` -if test -n "$published_canary_versions" +if [[ -n "$published_canary_versions" ]] then published_version=`npx_ignore_scripts semver $(echo "$published_canary_versions") | tail -1` echo "Detected published canary version $published_version" diff --git a/scripts/publish_testing.sh b/scripts/publish_testing.sh index 2356ddb7c..2e2ed0e09 100755 --- a/scripts/publish_testing.sh +++ b/scripts/publish_testing.sh @@ -13,7 +13,7 @@ version=`jq -r '.version' lerna.json` next_version=`npx_ignore_scripts semver "$version" --increment "$next_bump"` published_testing_versions=`npm view @vertexvis/viewer --json versions | jq --arg version "$next_version-" -r '.[] | select(contains($version) and contains("testing"))'` -if test -n "$published_testing_versions" +if [[ -n "$published_testing_versions" ]] then published_version=`npx_ignore_scripts semver $(echo "$published_testing_versions") | tail -1` echo "Detected published testing version $published_version" diff --git a/scripts/release.sh b/scripts/release.sh index 5e7206a7c..8b0f07f65 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -4,21 +4,21 @@ set -e . "$(pwd)"/scripts/utils.sh -if test "$(git rev-parse --abbrev-ref HEAD)" != "master" +if [[ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]] then echo "Cannot release from non-master branch" exit 1 fi # Check if the local repo is clean -if test -n "$(git status --porcelain --untracked-files=no)" +if [[ -n "$(git status --porcelain --untracked-files=no)" ]] then echo "Working directory contains uncommitted changes." exit 1 fi # Check if upstream has changes -if test -n "$(git status -sb --porcelain origin | grep "\[behind")" +if [[ -n "$(git status -sb --porcelain origin | grep "\[behind")" ]] then echo "Working directory is behind upstream. Pull upstream and try again." exit 1 @@ -30,7 +30,7 @@ local_branch=release-temp/$timestamp git checkout --track=direct -b $local_branch # Bump version and generate docs with updated versions -if test -n "$ASK_VERSION" +if [[ -n "$ASK_VERSION" ]] then npx_ignore_scripts lerna version --no-push --no-git-tag-version --exact else diff --git a/scripts/release_notes.sh b/scripts/release_notes.sh index 4aa55ac24..baad1b57d 100755 --- a/scripts/release_notes.sh +++ b/scripts/release_notes.sh @@ -25,7 +25,7 @@ function __read_summary() { function get_release_notes() { PR_NUMBER=$(git log -1 | grep -oE '(\(#)([0-9]*)[)]' | grep -oE '[0-9]*') - if [ ! -z "$PR_NUMBER" ]; then + if [[ -n "$PR_NUMBER" ]]; then DESC=$( curl --proto '=https' --tlsv1.2 \ -L https://api.github.com/repos/$REPOSITORY/pulls/$PR_NUMBER \ From 8bef72a6e3372c28173552a4e1a41d1e2fa661d0 Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Tue, 4 Aug 2026 17:45:39 -0500 Subject: [PATCH 4/8] Additional fix --- scripts/utils.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/utils.sh b/scripts/utils.sh index 20b10553c..dcd767493 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -6,4 +6,5 @@ function get_version { function npx_ignore_scripts { npx --ignore-scripts "$@" + return $? } From 779cfd45e9acf183bb2ae1f788c89369afdeab9c Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Wed, 5 Aug 2026 09:18:47 -0500 Subject: [PATCH 5/8] Testing examples analysis --- examples/metadata-operations/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/metadata-operations/index.html b/examples/metadata-operations/index.html index 92834feef..67273285a 100644 --- a/examples/metadata-operations/index.html +++ b/examples/metadata-operations/index.html @@ -20,6 +20,7 @@ + From 89efd3da1ed5d72869632fe94fb7939f9d3ecf54 Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Wed, 5 Aug 2026 09:22:27 -0500 Subject: [PATCH 6/8] Remove testing commit --- examples/metadata-operations/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/metadata-operations/index.html b/examples/metadata-operations/index.html index 67273285a..92834feef 100644 --- a/examples/metadata-operations/index.html +++ b/examples/metadata-operations/index.html @@ -20,7 +20,6 @@ - From 8f2d596ec135f8a5eb6c8c31ad55b78a83ea51c8 Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Wed, 5 Aug 2026 09:49:20 -0500 Subject: [PATCH 7/8] Cleanup examples over exclusion --- .sonarcloud.properties | 1 - examples/helpers.js | 12 ++++----- examples/metadata-operations/index.html | 11 +++++--- examples/metadata-operations/styles.css | 34 ++++++++++++++++++++++--- examples/scene-tree-columns/main.js | 2 +- 5 files changed, 45 insertions(+), 15 deletions(-) delete mode 100644 .sonarcloud.properties diff --git a/.sonarcloud.properties b/.sonarcloud.properties deleted file mode 100644 index 589c5daa2..000000000 --- a/.sonarcloud.properties +++ /dev/null @@ -1 +0,0 @@ -sonar.exclusions=examples/** diff --git a/examples/helpers.js b/examples/helpers.js index 652ac7d96..3f3046784 100644 --- a/examples/helpers.js +++ b/examples/helpers.js @@ -3,13 +3,13 @@ const DEFAULT_STREAM_KEY = 'ydD87RtDdJCZQaa6twueZTEtsciQmAWl5qnP'; export async function loadViewerWithQueryParams( viewer, - { env, streamKey } = { - streamKey: getStreamKey() || DEFAULT_STREAM_KEY, - env: getEnvironment() || DEFAULT_ENV, - } + options ) { - viewer.configEnv = env; - await viewer.load(`urn:vertex:stream-key:${streamKey}`); + const effectiveStreamKey = options?.streamKey ?? getStreamKey() ?? DEFAULT_STREAM_KEY; + const effectiveEnv = options?.env ?? getEnvironment() ?? DEFAULT_ENV; + + viewer.configEnv = effectiveEnv; + await viewer.load(`urn:vertex:stream-key:${effectiveStreamKey}`); } export function getStreamKey() { diff --git a/examples/metadata-operations/index.html b/examples/metadata-operations/index.html index 92834feef..7776eb3cc 100644 --- a/examples/metadata-operations/index.html +++ b/examples/metadata-operations/index.html @@ -16,13 +16,16 @@ > - - +
+ + +
+ + - - +
diff --git a/examples/metadata-operations/styles.css b/examples/metadata-operations/styles.css index 3a824a765..36bec8ffb 100644 --- a/examples/metadata-operations/styles.css +++ b/examples/metadata-operations/styles.css @@ -1,5 +1,33 @@ +html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} + +.app { + width: 100%; + height: 100%; + padding: 0.5rem; + box-sizing: border-box; + display: flex; + flex-direction: column; +} + .viewer { - display: block; - width: 500px; - height: 500px; + width: 100%; + height: 100%; + grid-column: 1 / 5; +} + +.inputs { + display: flex; + gap: 1rem; + align-items: center; + justify-content: center; } + +.invisible { + position: absolute; + visibility: hidden; +} \ No newline at end of file diff --git a/examples/scene-tree-columns/main.js b/examples/scene-tree-columns/main.js index f49b21112..3a533099c 100644 --- a/examples/scene-tree-columns/main.js +++ b/examples/scene-tree-columns/main.js @@ -40,7 +40,7 @@ async function main() { // Get array of selected metadata keys const selectedMetadataKeys = Array.from(selectedColumns); - if (!searchInput || !selectedColumns.size === 0) { + if (!searchInput) { console.warn('No search input currently, resetting phantom state') // If no search value, reset phantom state await scene.elements((op) => [op.items.where((q) => q.all()).clearPhantom()]).execute(); From a4b8ae1361f69fc0437361d349098f334f8d974a Mon Sep 17 00:00:00 2001 From: Jeff Murray Date: Wed, 5 Aug 2026 10:26:45 -0500 Subject: [PATCH 8/8] Debug logs false --- packages/viewer/src/components/scene-tree/lib/controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/viewer/src/components/scene-tree/lib/controller.ts b/packages/viewer/src/components/scene-tree/lib/controller.ts index 683f5c8a4..9d05e67fc 100644 --- a/packages/viewer/src/components/scene-tree/lib/controller.ts +++ b/packages/viewer/src/components/scene-tree/lib/controller.ts @@ -164,7 +164,7 @@ export class SceneTreeController { private pages = new Map(); private activeRowRange = [0, 0]; private metadataKeys: MetadataKey[] = []; - private debugLogs = true; + private debugLogs = false; private pendingFilterGrpcRes?: UnaryResponse; private reconnectTimer?: number;