Adds an 'object sender' module (#2355)
* feat(objectsender): wip serializer and sender * feat(objectsender): mostly done * feat(objectsender): chores * feat(objectsender): chores * build refactor * linting issue fix * minor type adjustments * adding in type definitions into build * sha tests * config fix * fixed up servertransport * added tests to ci * added coverage * storing coverage? --------- Co-authored-by: Kristaps Fabians Geikins <fabis94@live.com>
This commit is contained in:
committed by
GitHub
parent
24b71644a7
commit
01c9c3fa0e
@@ -28,6 +28,9 @@ workflows:
|
||||
- test-viewer:
|
||||
filters: *filters-allow-all
|
||||
|
||||
- test-objectsender:
|
||||
filters: *filters-allow-all
|
||||
|
||||
- test-ui-components:
|
||||
filters: *filters-allow-all
|
||||
|
||||
@@ -58,6 +61,7 @@ workflows:
|
||||
- deployment-testing-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
- docker-build-server
|
||||
- docker-build-frontend
|
||||
@@ -77,6 +81,7 @@ workflows:
|
||||
- deployment-testing-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
- docker-build-server
|
||||
- docker-build-frontend
|
||||
@@ -169,6 +174,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-frontend:
|
||||
@@ -181,6 +187,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-frontend-2:
|
||||
@@ -193,6 +200,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-webhooks:
|
||||
@@ -205,6 +213,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-file-imports:
|
||||
@@ -217,6 +226,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-previews:
|
||||
@@ -229,6 +239,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-test-container:
|
||||
@@ -241,6 +252,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-monitor-container:
|
||||
@@ -253,6 +265,7 @@ workflows:
|
||||
- publish-approval
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
- test-server
|
||||
|
||||
- docker-publish-docker-compose-ingress:
|
||||
@@ -304,6 +317,7 @@ workflows:
|
||||
- test-ui-components
|
||||
- test-frontend-2
|
||||
- test-viewer
|
||||
- test-objectsender
|
||||
|
||||
- publish-viewer-sandbox-cloudflare-pages:
|
||||
filters: *filters-publish
|
||||
@@ -568,6 +582,41 @@ jobs:
|
||||
command: yarn test
|
||||
working_directory: 'packages/viewer'
|
||||
|
||||
test-objectsender:
|
||||
docker: &docker-node-browsers-image
|
||||
- image: cimg/node:18.19.0-browsers
|
||||
resource_class: large
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
name: Restore Yarn Package Cache
|
||||
keys:
|
||||
- yarn-packages-server-{{ checksum "yarn.lock" }}
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: yarn
|
||||
|
||||
- run:
|
||||
name: Install Dependencies v2 (.node files missing bug)
|
||||
command: yarn
|
||||
|
||||
- save_cache:
|
||||
name: Save Yarn Package Cache
|
||||
key: yarn-packages-server-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- .yarn/cache
|
||||
- .yarn/unplugged
|
||||
|
||||
- run:
|
||||
name: Build public packages
|
||||
command: yarn build:public
|
||||
- run:
|
||||
name: Run tests
|
||||
command: yarn test:ci
|
||||
working_directory: 'packages/objectsender'
|
||||
- store_artifacts:
|
||||
path: 'packages/objectsender/coverage'
|
||||
|
||||
test-ui-components:
|
||||
docker: *docker-node-browsers-image
|
||||
resource_class: xlarge
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
@@ -0,0 +1,49 @@
|
||||
import { baseConfigs, globals, getESMDirname } from '../../eslint.config.mjs'
|
||||
import tseslint from 'typescript-eslint'
|
||||
|
||||
/**
|
||||
* @type {Array<import('eslint').Linter.FlatConfig>}
|
||||
*/
|
||||
const configs = [
|
||||
...baseConfigs,
|
||||
{
|
||||
files: ['examples/browser/**/*.{ts,js}'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser
|
||||
}
|
||||
}
|
||||
},
|
||||
...tseslint.configs.recommendedTypeChecked.map((c) => ({
|
||||
...c,
|
||||
files: [...(c.files || []), '**/*.ts', '**/*.d.ts']
|
||||
})),
|
||||
{
|
||||
files: ['**/*.ts', '**/*.d.ts'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
tsconfigRootDir: getESMDirname(import.meta.url),
|
||||
project: './tsconfig.eslint.json'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/restrict-template-expressions': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.d.ts'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['vite.config.ts'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export default configs
|
||||
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@speckle/objectsender example</title>
|
||||
<style>
|
||||
body {
|
||||
max-width: 850px;
|
||||
margin: 40px auto;
|
||||
padding: 0 10px;
|
||||
font: 18px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
color: #444;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
color: #c9d1d9;
|
||||
background: #0d1117;
|
||||
}
|
||||
a:link {
|
||||
color: #58a6ff;
|
||||
}
|
||||
a:visited {
|
||||
color: #8e96f0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<h1 class="text-2xl">Object Sender Test</h1>
|
||||
<p>All the magic is in the console.</p>
|
||||
<p>This will send a random speckle object to the server to flex things around.</p>
|
||||
<div>
|
||||
<p>How does this work?</p>
|
||||
<pre>
|
||||
import { send, Base } from '@speckle/objectsender'
|
||||
|
||||
const testObject = new Base({
|
||||
prop: value,
|
||||
'@detachedValue': new Base({...}),
|
||||
'@detachedArray': [...Array(100).fill(0).map( _ => new Base({...}))],
|
||||
'@(10)chunkedArr': [...Array(100).fill(0)]
|
||||
})
|
||||
|
||||
const { hash } = await send(testObject, { serverUrl, projectId, token })
|
||||
</pre
|
||||
>
|
||||
<p>For more info check src/examples/browser/main.ts</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="serverUrl" class="text-xs text-neutral-500">Server:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="serverUrl"
|
||||
name="serverUrl"
|
||||
minlength="42"
|
||||
required
|
||||
value="https://app.speckle.systems"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="apiToken" class="text-xs text-neutral-500">API token:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="apiToken"
|
||||
name="apiToken"
|
||||
minlength="42"
|
||||
required
|
||||
placeholder="c6cef1e202e0dbd4275ed7019bf2719135128071b6"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="projectId" class="text-xs text-neutral-500">Project id:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="projectId"
|
||||
name="projectId"
|
||||
minlength="6"
|
||||
required
|
||||
placeholder="67ab820e8b"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
<button type="button" onclick="loadData()">Send random object</button>
|
||||
<pre id="result">
|
||||
resulting link will be displayed here (note, nothing will be visible in the viewer)</pre
|
||||
>
|
||||
</div>
|
||||
<script type="module" src="/src/examples/browser/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "@speckle/objectsender",
|
||||
"version": "1.0.1",
|
||||
"description": "Simple API helper to serialize and send objects to the server.",
|
||||
"type": "module",
|
||||
"main": "dist/objectsender.cjs",
|
||||
"module": "dist/objectsender.js",
|
||||
"homepage": "https://speckle.systems",
|
||||
"types": "./dist/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/specklesystems/speckle-server.git",
|
||||
"directory": "packages/objectsender"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"dev": "vite",
|
||||
"example": "yarn dev",
|
||||
"build": "tsc && vite build",
|
||||
"prepack": "yarn build",
|
||||
"test": "vitest",
|
||||
"test:ci": "vitest --run --coverage"
|
||||
},
|
||||
"keywords": [
|
||||
"speckle",
|
||||
"aec",
|
||||
"speckle api"
|
||||
],
|
||||
"author": "AEC Systems",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@speckle/shared": "workspace:^",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.17.5",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
||||
"@typescript-eslint/parser": "^7.12.0",
|
||||
"@vitest/coverage-v8": "^1.6.0",
|
||||
"eslint": "^9.4.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"prettier": "^3.3.2",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^5.2.0",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.6.0"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"default": "./dist/objectsender.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"require": {
|
||||
"default": "./dist/objectsender.cjs",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"imports": {
|
||||
"#lodash": {
|
||||
"require": "lodash",
|
||||
"import": "lodash-es"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,13 @@
|
||||
# objectsender
|
||||
|
||||
Utility for sending objects to a Speckle server instance
|
||||
|
||||
## Testing around / playground
|
||||
|
||||
Run `yarn example` in the app, and open up the URL outputted in the console
|
||||
|
||||
## Development
|
||||
|
||||
For development and/or the example app you can run a dev server in dev mode that will run the util in the browser: `yarn dev`
|
||||
|
||||
To do a real build that will build the library run `yarn build`.
|
||||
@@ -0,0 +1,120 @@
|
||||
import { send, Base, type SendResult } from '../../index'
|
||||
import { times } from '#lodash'
|
||||
|
||||
interface ExampleAppWindow extends Window {
|
||||
send: typeof import('../../index').send
|
||||
loadData: () => Promise<void>
|
||||
}
|
||||
|
||||
const appWindow = window as unknown as ExampleAppWindow
|
||||
|
||||
appWindow.send = send
|
||||
|
||||
const setInputValue = (
|
||||
key: string,
|
||||
value: string,
|
||||
options?: Partial<{ valueKey: 'value' | 'textContent' }>
|
||||
) => {
|
||||
const { valueKey = 'value' } = options || {}
|
||||
const input = document.getElementById(key) as HTMLInputElement | undefined
|
||||
if (!input) {
|
||||
console.error("Unexpectedly couldn't find core input: " + key)
|
||||
return
|
||||
}
|
||||
|
||||
input[valueKey] = value
|
||||
}
|
||||
|
||||
const getInputValue = (key: string) => {
|
||||
const input = document.getElementById(key) as HTMLInputElement | undefined
|
||||
if (!input) {
|
||||
throw new Error("Unexpectedly couldn't find core input: " + key)
|
||||
}
|
||||
|
||||
return input.value
|
||||
}
|
||||
|
||||
appWindow.onload = () => {
|
||||
const serverUrl = localStorage.getItem('serverUrl')
|
||||
const apiToken = localStorage.getItem('apiToken')
|
||||
const projectId = localStorage.getItem('projectId')
|
||||
|
||||
if (serverUrl) {
|
||||
setInputValue('serverUrl', serverUrl)
|
||||
}
|
||||
if (apiToken) {
|
||||
setInputValue('apiToken', apiToken)
|
||||
}
|
||||
if (projectId) {
|
||||
setInputValue('projectId', projectId)
|
||||
}
|
||||
}
|
||||
|
||||
appWindow.loadData = async () => {
|
||||
const serverUrl = getInputValue('serverUrl')
|
||||
const apiToken = getInputValue('apiToken')
|
||||
const projectId = getInputValue('projectId')
|
||||
|
||||
localStorage.setItem('serverUrl', serverUrl)
|
||||
localStorage.setItem('projectId', projectId)
|
||||
localStorage.setItem('apiToken', apiToken)
|
||||
|
||||
setInputValue('result', '...', { valueKey: 'textContent' })
|
||||
|
||||
const obj = generateTestObject()
|
||||
let res: SendResult | undefined = undefined
|
||||
|
||||
try {
|
||||
res = await send(obj, {
|
||||
serverUrl,
|
||||
projectId,
|
||||
token: apiToken
|
||||
})
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : JSON.stringify(e)
|
||||
setInputValue('result', msg, { valueKey: 'textContent' })
|
||||
throw e
|
||||
}
|
||||
|
||||
const objectUrl = new URL(`/projects/${projectId}/models/${res.hash}`, serverUrl)
|
||||
const objectLink = objectUrl.toString()
|
||||
console.log(objectLink)
|
||||
|
||||
setInputValue('result', objectLink, { valueKey: 'textContent' })
|
||||
}
|
||||
|
||||
function generateTestObject() {
|
||||
return new Base({
|
||||
start: 'end',
|
||||
primitiveArray: Array(100).fill(1),
|
||||
normalObject: {
|
||||
hello: 'world',
|
||||
how: 'are',
|
||||
you: '?',
|
||||
inner: {
|
||||
pasta: 'pesto',
|
||||
qux: 'mux'
|
||||
}
|
||||
},
|
||||
'@detachedValue': new RandomFoo({
|
||||
'@nestedDetachedValue_1': new RandomFoo({
|
||||
'@nestedDetachedValue_2': new RandomFoo({
|
||||
'@nestedDetachedValue_3': new RandomFoo()
|
||||
})
|
||||
})
|
||||
}),
|
||||
'@detachedArray': [
|
||||
...Array(100)
|
||||
.fill(0)
|
||||
.map(() => new RandomFoo({ bar: 'baz baz baz' }))
|
||||
],
|
||||
'@(10)chunkedArr': times(100, () => 42)
|
||||
})
|
||||
}
|
||||
|
||||
class RandomFoo extends Base {
|
||||
constructor(props?: Record<string, unknown>) {
|
||||
super(props)
|
||||
this.noise = Math.random().toString(16)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Serializer } from './utils/Serializer'
|
||||
import { ServerTransport } from './transports/ServerTransport'
|
||||
import { Base } from './utils/Base'
|
||||
export { Base }
|
||||
|
||||
export type SendParams = {
|
||||
serverUrl?: string
|
||||
projectId: string
|
||||
token: string
|
||||
logger?: {
|
||||
log: (message: unknown) => void
|
||||
error: (message: unknown) => void
|
||||
}
|
||||
}
|
||||
|
||||
export type SendResult = {
|
||||
hash: string
|
||||
traversed: Record<string, unknown>
|
||||
}
|
||||
|
||||
/**
|
||||
* Decomposes, serializes and sends to a speckle server a given object. Note, for objects to be detached, they need to have a 'speckle_type' property.
|
||||
* @param object object to decompose, serialise and send to speckle
|
||||
* @param parameters: server url, project id and token
|
||||
* @returns the hash of the root object and the value of the root object
|
||||
*/
|
||||
export const send = async (
|
||||
object: Base,
|
||||
{
|
||||
serverUrl = 'https://app.speckle.systems',
|
||||
projectId,
|
||||
token,
|
||||
logger = console
|
||||
}: SendParams
|
||||
) => {
|
||||
const t0 = performance.now()
|
||||
logger?.log('Starting to send')
|
||||
const transport = new ServerTransport(serverUrl, projectId, token)
|
||||
const serializer = new Serializer(transport)
|
||||
|
||||
let result: SendResult
|
||||
try {
|
||||
result = await serializer.write(object)
|
||||
} finally {
|
||||
transport.dispose()
|
||||
serializer.dispose()
|
||||
}
|
||||
const t1 = performance.now()
|
||||
logger.log(`Finished sending in ${(t1 - t0) / 1000}s.`)
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export interface ITransport {
|
||||
/**
|
||||
* Instructs the transport to write this object to its storage layer.
|
||||
* @param serialisedObject
|
||||
* @param size approximate objects size
|
||||
*/
|
||||
write(serialisedObject: string, size: number): Promise<void>
|
||||
/**
|
||||
* Flushes the buffer ensuring it is persisted to its storage layer.
|
||||
*/
|
||||
flush(): Promise<void>
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import { ITransport } from './ITransport'
|
||||
import { IDisposable } from '../utils/IDisposable'
|
||||
import { retry, timeoutAt } from '@speckle/shared'
|
||||
|
||||
/**
|
||||
* Basic object sender to a speckle server
|
||||
*/
|
||||
export class ServerTransport implements ITransport, IDisposable {
|
||||
#buffer: string[]
|
||||
#maxSize: number
|
||||
#currSize: number
|
||||
#serverUrl: string
|
||||
#projectId: string
|
||||
#authToken: string
|
||||
#flushRetryCount: number
|
||||
#flushTimeout: number
|
||||
|
||||
constructor(
|
||||
serverUrl: string,
|
||||
projectId: string,
|
||||
authToken: string,
|
||||
options?: Partial<{
|
||||
maxSize: number
|
||||
flushRetryCount: number
|
||||
flushTimeout: number
|
||||
}>
|
||||
) {
|
||||
this.#maxSize = options?.maxSize || 200_000
|
||||
this.#flushRetryCount = options?.flushRetryCount || 3
|
||||
this.#flushTimeout = options?.flushTimeout || 2 * 60 * 1000
|
||||
|
||||
this.#currSize = 0
|
||||
this.#serverUrl = serverUrl
|
||||
this.#projectId = projectId
|
||||
this.#authToken = authToken
|
||||
this.#buffer = []
|
||||
}
|
||||
|
||||
async write(serialisedObject: string, size: number) {
|
||||
this.#buffer.push(serialisedObject)
|
||||
this.#currSize += size
|
||||
if (this.#currSize < this.#maxSize) return // return fast
|
||||
await this.flush() // block until we send objects
|
||||
}
|
||||
|
||||
async flush() {
|
||||
if (this.#buffer.length === 0) return
|
||||
|
||||
const formData = new FormData()
|
||||
const concat = '[' + this.#buffer.join(',') + ']'
|
||||
formData.append('object-batch', new Blob([concat], { type: 'application/json' }))
|
||||
const url = new URL(`/objects/${this.#projectId}`, this.#serverUrl)
|
||||
const res = await retry(
|
||||
async () =>
|
||||
await Promise.race([
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${this.#authToken}` },
|
||||
body: formData
|
||||
}),
|
||||
timeoutAt(this.#flushTimeout, 'Object sender flush timed out')
|
||||
]),
|
||||
this.#flushRetryCount,
|
||||
(i) => {
|
||||
return i * 1000
|
||||
}
|
||||
)
|
||||
|
||||
if (res.status !== 201) {
|
||||
throw new Error(
|
||||
`Unexpected error when sending data. Expected status 200, got ${res.status}`
|
||||
)
|
||||
}
|
||||
|
||||
this.#buffer = []
|
||||
this.#currSize = 0
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.#buffer = []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/* eslint-disable camelcase */
|
||||
/**
|
||||
* Basic 'Base'-like object from .NET. It will create a 'speckle_type' prop that defaults to the class' name. This can be overriden by providing yourself a 'speckle_type' property in the props argument of the constructor.
|
||||
*/
|
||||
export class Base implements Record<string, unknown> {
|
||||
speckle_type: string
|
||||
constructor(props?: Record<string, unknown>) {
|
||||
this.speckle_type = this.constructor.name
|
||||
|
||||
if (props) {
|
||||
for (const key in props) this[key] = props[key]
|
||||
}
|
||||
}
|
||||
[x: string]: unknown
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface IDisposable {
|
||||
dispose: () => void
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/* eslint-disable camelcase */
|
||||
import { SHA1 } from './Sha1'
|
||||
import { ITransport } from '../transports/ITransport'
|
||||
import { Base } from './Base'
|
||||
import { IDisposable } from './IDisposable'
|
||||
import { isObjectLike, get } from '#lodash'
|
||||
|
||||
type BasicSpeckleObject = Record<string, unknown> & {
|
||||
speckle_type: string
|
||||
}
|
||||
|
||||
const isSpeckleObject = (obj: unknown): obj is BasicSpeckleObject =>
|
||||
isObjectLike(obj) && !!get(obj, 'speckle_type')
|
||||
|
||||
export class Serializer implements IDisposable {
|
||||
chunkSize: number
|
||||
detachLineage: boolean[]
|
||||
lineage: string[]
|
||||
familyTree: Record<string, Record<string, number>>
|
||||
closureTable: Record<string, unknown>
|
||||
transport: ITransport | null
|
||||
uniqueId: number
|
||||
hashingFunction: (s: string) => string
|
||||
|
||||
constructor(
|
||||
transport: ITransport,
|
||||
chunkSize: number = 1000,
|
||||
hashingFunction: (s: string) => string = SHA1
|
||||
) {
|
||||
this.chunkSize = chunkSize
|
||||
this.detachLineage = [true] // first ever call is always detached
|
||||
this.lineage = []
|
||||
this.familyTree = {}
|
||||
this.closureTable = {}
|
||||
this.transport = transport
|
||||
this.uniqueId = 0
|
||||
this.hashingFunction = hashingFunction || SHA1
|
||||
}
|
||||
|
||||
async write(obj: Base) {
|
||||
return await this.#traverse(obj, true)
|
||||
}
|
||||
|
||||
async #traverse(obj: Record<string, unknown>, root: boolean) {
|
||||
const temporaryId = `${this.uniqueId++}-obj`
|
||||
this.lineage.push(temporaryId)
|
||||
|
||||
const traversed = { speckle_type: obj.speckle_type || 'Base' } as Record<
|
||||
string,
|
||||
unknown
|
||||
>
|
||||
|
||||
for (const propKey in obj) {
|
||||
const value = obj[propKey]
|
||||
// 0. skip some props
|
||||
if (!value || propKey === 'id' || propKey.startsWith('_')) continue
|
||||
|
||||
// 1. primitives (numbers, bools, strings)
|
||||
if (typeof value !== 'object') {
|
||||
traversed[propKey] = value
|
||||
continue
|
||||
}
|
||||
|
||||
const isDetachedProp = propKey.startsWith('@')
|
||||
|
||||
// 2. chunked arrays
|
||||
const isArray = Array.isArray(value)
|
||||
const isChunked = isArray ? propKey.match(/^@\((\d*)\)/) : false // chunk syntax
|
||||
if (isArray && isChunked && value.length !== 0 && typeof value[0] !== 'object') {
|
||||
const chunkSize = isChunked[1] !== '' ? parseInt(isChunked[1]) : this.chunkSize
|
||||
const chunkRefs = []
|
||||
|
||||
let chunk = new DataChunk()
|
||||
let count = 0
|
||||
for (const el of value) {
|
||||
if (count === chunkSize) {
|
||||
chunkRefs.push(await this.#handleChunk(chunk))
|
||||
chunk = new DataChunk()
|
||||
count = 0
|
||||
}
|
||||
chunk.data.push(el)
|
||||
count++
|
||||
}
|
||||
|
||||
if (chunk.data.length !== 0) chunkRefs.push(await this.#handleChunk(chunk))
|
||||
traversed[propKey.replace(isChunked[0], '')] = chunkRefs // strip chunk syntax
|
||||
continue
|
||||
}
|
||||
|
||||
// 3. speckle objects
|
||||
if ((value as Record<string, unknown>).speckle_type) {
|
||||
const child = (await this.#traverseValue({
|
||||
value,
|
||||
isDetached: isDetachedProp
|
||||
})) as {
|
||||
id: string
|
||||
}
|
||||
traversed[propKey] = isDetachedProp ? this.#detachHelper(child.id) : child
|
||||
continue
|
||||
}
|
||||
|
||||
// 4. other objects (dicts/maps, lists)
|
||||
traversed[propKey] = await this.#traverseValue({
|
||||
value,
|
||||
isDetached: isDetachedProp
|
||||
})
|
||||
}
|
||||
// We've finished going through all the properties of this object, now let's perform the last rites
|
||||
const detached = this.detachLineage.pop()
|
||||
const parent = this.lineage.pop() as string
|
||||
|
||||
if (this.familyTree[parent]) {
|
||||
const closure = {} as Record<string, number>
|
||||
|
||||
Object.entries(this.familyTree[parent]).forEach(([ref, depth]) => {
|
||||
closure[ref] = depth - this.detachLineage.length
|
||||
})
|
||||
|
||||
traversed['totalChildrenCount'] = Object.keys(closure).length
|
||||
|
||||
if (traversed['totalChildrenCount']) {
|
||||
traversed['__closure'] = closure
|
||||
}
|
||||
}
|
||||
|
||||
const { hash, serializedObject, size } = this.#generateId(traversed)
|
||||
traversed.id = hash
|
||||
|
||||
// Pop it in
|
||||
if ((detached || root) && this.transport) {
|
||||
await this.transport.write(serializedObject, size)
|
||||
}
|
||||
|
||||
// We've reached the end, let's flush
|
||||
if (root && this.transport) {
|
||||
await this.transport.flush()
|
||||
}
|
||||
|
||||
return { hash, traversed }
|
||||
}
|
||||
|
||||
async #traverseValue({
|
||||
value,
|
||||
isDetached = false
|
||||
}: {
|
||||
value: unknown
|
||||
isDetached?: boolean
|
||||
}): Promise<unknown> {
|
||||
// 1. primitives
|
||||
if (typeof value !== 'object') return value
|
||||
|
||||
// 2. arrays
|
||||
if (Array.isArray(value)) {
|
||||
const arr = value as unknown[]
|
||||
// 2.1 empty arrays
|
||||
if (arr.length === 0) return value as unknown
|
||||
|
||||
// 2.2 primitive arrays
|
||||
if (typeof arr[0] !== 'object') return arr
|
||||
|
||||
// 2.3. non-primitive non-detached arrays
|
||||
if (!isDetached) {
|
||||
return Promise.all(
|
||||
value.map(async (el) => await this.#traverseValue({ value: el }))
|
||||
)
|
||||
}
|
||||
|
||||
// 2.4 non-primitive detached arrays
|
||||
const detachedList = [] as unknown[]
|
||||
for (const el of value) {
|
||||
if (isSpeckleObject(el)) {
|
||||
this.detachLineage.push(isDetached)
|
||||
const { hash } = await this.#traverse(el, false)
|
||||
detachedList.push(this.#detachHelper(hash))
|
||||
} else {
|
||||
detachedList.push(await this.#traverseValue({ value: el, isDetached }))
|
||||
}
|
||||
}
|
||||
return detachedList
|
||||
}
|
||||
|
||||
// 3. dicts
|
||||
if (!(value as { speckle_type?: string }).speckle_type) return value
|
||||
|
||||
// 4. base objects
|
||||
if ((value as { speckle_type?: string }).speckle_type) {
|
||||
this.detachLineage.push(isDetached)
|
||||
const res = await this.#traverse(value as Record<string, unknown>, false)
|
||||
return res.traversed
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported type '${typeof value}': ${value}.`)
|
||||
}
|
||||
|
||||
#detachHelper(refHash: string) {
|
||||
this.lineage.forEach((parent) => {
|
||||
if (!this.familyTree[parent]) this.familyTree[parent] = {}
|
||||
|
||||
if (
|
||||
!this.familyTree[parent][refHash] ||
|
||||
this.familyTree[parent][refHash] > this.detachLineage.length
|
||||
) {
|
||||
this.familyTree[parent][refHash] = this.detachLineage.length
|
||||
}
|
||||
})
|
||||
return {
|
||||
referencedId: refHash,
|
||||
speckle_type: 'reference'
|
||||
}
|
||||
}
|
||||
|
||||
async #handleChunk(chunk: DataChunk) {
|
||||
this.detachLineage.push(true)
|
||||
const { hash } = await this.#traverse(
|
||||
chunk as unknown as Record<string, unknown>,
|
||||
false
|
||||
)
|
||||
return this.#detachHelper(hash)
|
||||
}
|
||||
|
||||
#generateId(obj: Record<string, unknown>) {
|
||||
const s = JSON.stringify(obj)
|
||||
const h = this.hashingFunction(s)
|
||||
const f = s.substring(0, 1) + `"id":"${h}",` + s.substring(1)
|
||||
return {
|
||||
hash: SHA1(s),
|
||||
serializedObject: f,
|
||||
size: s.length // approx, good enough as we're just limiting artificially batch sizes based on this
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.detachLineage = []
|
||||
this.lineage = []
|
||||
this.familyTree = {}
|
||||
this.closureTable = {}
|
||||
this.transport = null
|
||||
}
|
||||
}
|
||||
|
||||
class DataChunk {
|
||||
speckle_type: 'Speckle.Core.Models.DataChunk'
|
||||
data: unknown[]
|
||||
constructor() {
|
||||
this.data = []
|
||||
this.speckle_type = 'Speckle.Core.Models.DataChunk'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { expect, describe, it } from 'vitest'
|
||||
import { SHA1 } from './Sha1'
|
||||
|
||||
describe('SHA1 encryption', () => {
|
||||
it.each([
|
||||
['le speckle', '67413ddfa55bab1b735d4d90bf5be7f5fafbcdfb'],
|
||||
[
|
||||
'the quick brown fox jumped over the lazy dog? i think',
|
||||
'b724fbdc205bae3b1d7511304ec4b576af563f93'
|
||||
],
|
||||
['1', '356a192b7913b04c54574d18c28d46e6395428ab']
|
||||
])('SHA1(%s) should return %s', (input, expected) => {
|
||||
expect(SHA1(input)).toBe(expected)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,138 @@
|
||||
/* eslint-disable camelcase */
|
||||
/**
|
||||
* Basic hashing function, to avoid dependencies and crazy build processes
|
||||
* @param msg
|
||||
* @returns
|
||||
*/
|
||||
export function SHA1(msg: string) {
|
||||
function rotate_left(n: number, s: number) {
|
||||
const t4 = (n << s) | (n >>> (32 - s))
|
||||
return t4
|
||||
}
|
||||
function cvt_hex(val: number) {
|
||||
let str = ''
|
||||
let i
|
||||
let v
|
||||
for (i = 7; i >= 0; i--) {
|
||||
v = (val >>> (i * 4)) & 0x0f
|
||||
str += v.toString(16)
|
||||
}
|
||||
return str
|
||||
}
|
||||
function Utf8Encode(string: string) {
|
||||
string = string.replace(/\r\n/g, '\n')
|
||||
let utftext = ''
|
||||
for (let n = 0; n < string.length; n++) {
|
||||
const c = string.charCodeAt(n)
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c)
|
||||
} else if (c > 127 && c < 2048) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192)
|
||||
utftext += String.fromCharCode((c & 63) | 128)
|
||||
} else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224)
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128)
|
||||
utftext += String.fromCharCode((c & 63) | 128)
|
||||
}
|
||||
}
|
||||
return utftext
|
||||
}
|
||||
let blockstart
|
||||
let i, j
|
||||
const W = new Array(80)
|
||||
let H0 = 0x67452301
|
||||
let H1 = 0xefcdab89
|
||||
let H2 = 0x98badcfe
|
||||
let H3 = 0x10325476
|
||||
let H4 = 0xc3d2e1f0
|
||||
let A, B, C, D, E
|
||||
let temp
|
||||
msg = Utf8Encode(msg)
|
||||
const msg_len = msg.length
|
||||
const word_array = [] as unknown[]
|
||||
for (i = 0; i < msg_len - 3; i += 4) {
|
||||
j =
|
||||
(msg.charCodeAt(i) << 24) |
|
||||
(msg.charCodeAt(i + 1) << 16) |
|
||||
(msg.charCodeAt(i + 2) << 8) |
|
||||
msg.charCodeAt(i + 3)
|
||||
word_array.push(j)
|
||||
}
|
||||
switch (msg_len % 4) {
|
||||
case 0:
|
||||
i = 0x080000000
|
||||
break
|
||||
case 1:
|
||||
i = (msg.charCodeAt(msg_len - 1) << 24) | 0x0800000
|
||||
break
|
||||
case 2:
|
||||
i =
|
||||
(msg.charCodeAt(msg_len - 2) << 24) |
|
||||
(msg.charCodeAt(msg_len - 1) << 16) |
|
||||
0x08000
|
||||
break
|
||||
case 3:
|
||||
i =
|
||||
(msg.charCodeAt(msg_len - 3) << 24) |
|
||||
(msg.charCodeAt(msg_len - 2) << 16) |
|
||||
(msg.charCodeAt(msg_len - 1) << 8) |
|
||||
0x80
|
||||
break
|
||||
}
|
||||
word_array.push(i)
|
||||
while (word_array.length % 16 !== 14) word_array.push(0)
|
||||
word_array.push(msg_len >>> 29)
|
||||
word_array.push((msg_len << 3) & 0x0ffffffff)
|
||||
for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
|
||||
for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i]
|
||||
for (i = 16; i <= 79; i++)
|
||||
W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1)
|
||||
A = H0
|
||||
B = H1
|
||||
C = H2
|
||||
D = H3
|
||||
E = H4
|
||||
for (i = 0; i <= 19; i++) {
|
||||
temp =
|
||||
(rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5a827999) & 0x0ffffffff
|
||||
E = D
|
||||
D = C
|
||||
C = rotate_left(B, 30)
|
||||
B = A
|
||||
A = temp
|
||||
}
|
||||
for (i = 20; i <= 39; i++) {
|
||||
temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ed9eba1) & 0x0ffffffff
|
||||
E = D
|
||||
D = C
|
||||
C = rotate_left(B, 30)
|
||||
B = A
|
||||
A = temp
|
||||
}
|
||||
for (i = 40; i <= 59; i++) {
|
||||
temp =
|
||||
(rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8f1bbcdc) &
|
||||
0x0ffffffff
|
||||
E = D
|
||||
D = C
|
||||
C = rotate_left(B, 30)
|
||||
B = A
|
||||
A = temp
|
||||
}
|
||||
for (i = 60; i <= 79; i++) {
|
||||
temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xca62c1d6) & 0x0ffffffff
|
||||
E = D
|
||||
D = C
|
||||
C = rotate_left(B, 30)
|
||||
B = A
|
||||
A = temp
|
||||
}
|
||||
H0 = (H0 + A) & 0x0ffffffff
|
||||
H1 = (H1 + B) & 0x0ffffffff
|
||||
H2 = (H2 + C) & 0x0ffffffff
|
||||
H3 = (H3 + D) & 0x0ffffffff
|
||||
H4 = (H4 + E) & 0x0ffffffff
|
||||
}
|
||||
const h = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4)
|
||||
return h.toLowerCase().substring(0, 40)
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["node_modules", "dist", "coverage"],
|
||||
"include": ["src", "vite.config.ts", "vitest.config.ts"]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/// <reference types="vitest" />
|
||||
import pkg from './package.json'
|
||||
import { defineConfig } from 'vite'
|
||||
import { resolve } from 'path'
|
||||
import dts from 'vite-plugin-dts'
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: resolve(__dirname, './src/index.ts'),
|
||||
name: 'objectsender',
|
||||
fileName: 'objectsender',
|
||||
formats: ['es', 'cjs']
|
||||
},
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
external: Object.keys(pkg.dependencies || {})
|
||||
}
|
||||
},
|
||||
plugins: [dts()]
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
import { coverageConfigDefaults, defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
coverage: {
|
||||
exclude: ['**/src/examples/**', ...coverageConfigDefaults.exclude]
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -46,7 +46,11 @@
|
||||
},
|
||||
{
|
||||
"path": "packages/objectloader",
|
||||
"name": "🌐 objectloader"
|
||||
"name": "⬇️ objectloader"
|
||||
},
|
||||
{
|
||||
"path": "packages/objectsender",
|
||||
"name": "⬆️ objectsender"
|
||||
},
|
||||
{
|
||||
"path": "packages/shared",
|
||||
@@ -134,6 +138,6 @@
|
||||
"graphql.vscode-graphql-syntax"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": ["octref.vetur", "vscode.typescript-language-features"]
|
||||
"unwantedRecommendations": ["octref.vetur"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@ampproject/remapping@npm:^2.2.1":
|
||||
version: 2.3.0
|
||||
resolution: "@ampproject/remapping@npm:2.3.0"
|
||||
dependencies:
|
||||
"@jridgewell/gen-mapping": ^0.3.5
|
||||
"@jridgewell/trace-mapping": ^0.3.24
|
||||
checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@antfu/install-pkg@npm:^0.1.1":
|
||||
version: 0.1.1
|
||||
resolution: "@antfu/install-pkg@npm:0.1.1"
|
||||
@@ -4692,7 +4702,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/parser@npm:^7.24.7":
|
||||
"@babel/parser@npm:^7.24.4, @babel/parser@npm:^7.24.7":
|
||||
version: 7.24.7
|
||||
resolution: "@babel/parser@npm:7.24.7"
|
||||
bin:
|
||||
@@ -13275,7 +13285,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
|
||||
"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
|
||||
version: 0.3.25
|
||||
resolution: "@jridgewell/trace-mapping@npm:0.3.25"
|
||||
dependencies:
|
||||
@@ -13446,6 +13456,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@microsoft/api-extractor-model@npm:7.28.13":
|
||||
version: 7.28.13
|
||||
resolution: "@microsoft/api-extractor-model@npm:7.28.13"
|
||||
dependencies:
|
||||
"@microsoft/tsdoc": 0.14.2
|
||||
"@microsoft/tsdoc-config": ~0.16.1
|
||||
"@rushstack/node-core-library": 4.0.2
|
||||
checksum: 0ac8236c670da4fe831a2b2fee94b4c9e4b881ba04e3c7807774db3f47e87c8d62dd5a5fd9b9a3f8bd56aa9ce2d75307338558c83063a912f230824e08f15e89
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@microsoft/api-extractor-model@npm:7.28.2":
|
||||
version: 7.28.2
|
||||
resolution: "@microsoft/api-extractor-model@npm:7.28.2"
|
||||
@@ -13457,6 +13478,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@microsoft/api-extractor@npm:7.43.0":
|
||||
version: 7.43.0
|
||||
resolution: "@microsoft/api-extractor@npm:7.43.0"
|
||||
dependencies:
|
||||
"@microsoft/api-extractor-model": 7.28.13
|
||||
"@microsoft/tsdoc": 0.14.2
|
||||
"@microsoft/tsdoc-config": ~0.16.1
|
||||
"@rushstack/node-core-library": 4.0.2
|
||||
"@rushstack/rig-package": 0.5.2
|
||||
"@rushstack/terminal": 0.10.0
|
||||
"@rushstack/ts-command-line": 4.19.1
|
||||
lodash: ~4.17.15
|
||||
minimatch: ~3.0.3
|
||||
resolve: ~1.22.1
|
||||
semver: ~7.5.4
|
||||
source-map: ~0.6.1
|
||||
typescript: 5.4.2
|
||||
bin:
|
||||
api-extractor: bin/api-extractor
|
||||
checksum: 7015bbd529782209f0d8e5728ae7699707ea60a696a60b2bc688ec88fec62430e82ac77629e59fc40d3b287ea0135a1050509c7436de648bb656e882c97fae3c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@microsoft/api-extractor@npm:^7.38.0":
|
||||
version: 7.38.3
|
||||
resolution: "@microsoft/api-extractor@npm:7.38.3"
|
||||
@@ -15574,6 +15618,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rushstack/node-core-library@npm:4.0.2":
|
||||
version: 4.0.2
|
||||
resolution: "@rushstack/node-core-library@npm:4.0.2"
|
||||
dependencies:
|
||||
fs-extra: ~7.0.1
|
||||
import-lazy: ~4.0.0
|
||||
jju: ~1.4.0
|
||||
resolve: ~1.22.1
|
||||
semver: ~7.5.4
|
||||
z-schema: ~5.0.2
|
||||
peerDependencies:
|
||||
"@types/node": "*"
|
||||
peerDependenciesMeta:
|
||||
"@types/node":
|
||||
optional: true
|
||||
checksum: 318cbe9c17514dd18948d63fc170eeea5167d877734385e2351ba844ebb96f3b1cfced8d73ed2a0fdb89eb7013367be6e1f9409ae0ede71fe6e35cfdb6bf8e5b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rushstack/rig-package@npm:0.5.1":
|
||||
version: 0.5.1
|
||||
resolution: "@rushstack/rig-package@npm:0.5.1"
|
||||
@@ -15584,6 +15647,31 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rushstack/rig-package@npm:0.5.2":
|
||||
version: 0.5.2
|
||||
resolution: "@rushstack/rig-package@npm:0.5.2"
|
||||
dependencies:
|
||||
resolve: ~1.22.1
|
||||
strip-json-comments: ~3.1.1
|
||||
checksum: cdfbca218d85f0daf865b308a8f1ad572835e465b64a2efa74e8ee0025d31bb7da8d77a5f2c34af7fd8993eb0e317ea14cce14557dcbe0fe3041020d4141704b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rushstack/terminal@npm:0.10.0":
|
||||
version: 0.10.0
|
||||
resolution: "@rushstack/terminal@npm:0.10.0"
|
||||
dependencies:
|
||||
"@rushstack/node-core-library": 4.0.2
|
||||
supports-color: ~8.1.1
|
||||
peerDependencies:
|
||||
"@types/node": "*"
|
||||
peerDependenciesMeta:
|
||||
"@types/node":
|
||||
optional: true
|
||||
checksum: 1a62b2bd26f501608ae0c482b4597c4266752501e6ca61ffa7a00344b396382dbb5a8a6766dd93af9b5aecfbcf861c065f00b3c70461b48ec168feefc9515d9f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rushstack/ts-command-line@npm:4.17.1":
|
||||
version: 4.17.1
|
||||
resolution: "@rushstack/ts-command-line@npm:4.17.1"
|
||||
@@ -15596,6 +15684,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rushstack/ts-command-line@npm:4.19.1":
|
||||
version: 4.19.1
|
||||
resolution: "@rushstack/ts-command-line@npm:4.19.1"
|
||||
dependencies:
|
||||
"@rushstack/terminal": 0.10.0
|
||||
"@types/argparse": 1.0.38
|
||||
argparse: ~1.0.9
|
||||
string-argv: ~0.3.1
|
||||
checksum: db9ee56563e6c628fe7203153213a7db92a9aeed509f36a0c87882d9ccc46bdd6474ef870b1fc1d68f7980676b30e327bd1b6ef5e529847bbe60f5de49e81b2a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/core@npm:6.19.7":
|
||||
version: 6.19.7
|
||||
resolution: "@sentry/core@npm:6.19.7"
|
||||
@@ -16774,6 +16874,28 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@speckle/objectsender@workspace:packages/objectsender":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@speckle/objectsender@workspace:packages/objectsender"
|
||||
dependencies:
|
||||
"@speckle/shared": "workspace:^"
|
||||
"@types/lodash": ^4.17.5
|
||||
"@types/lodash-es": ^4.17.12
|
||||
"@typescript-eslint/eslint-plugin": ^7.12.0
|
||||
"@typescript-eslint/parser": ^7.12.0
|
||||
"@vitest/coverage-v8": ^1.6.0
|
||||
eslint: ^9.4.0
|
||||
eslint-config-prettier: ^9.1.0
|
||||
lodash: ^4.17.21
|
||||
lodash-es: ^4.17.21
|
||||
prettier: ^3.3.2
|
||||
typescript: ^5.2.2
|
||||
vite: ^5.2.0
|
||||
vite-plugin-dts: ^3.9.1
|
||||
vitest: ^1.6.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@speckle/preview-service@workspace:packages/preview-service":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@speckle/preview-service@workspace:packages/preview-service"
|
||||
@@ -19736,6 +19858,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/lodash@npm:^4.17.5":
|
||||
version: 4.17.5
|
||||
resolution: "@types/lodash@npm:4.17.5"
|
||||
checksum: 3c9bb15772509f0ecb40428531863dbc3f064f2bf34bbccc2ce2b2923c69fb0868aec7e357b1d97fd0d7f7e435a014ea5c1adef8a64715529887179c97a5a823
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/long@npm:^4.0.0":
|
||||
version: 4.0.2
|
||||
resolution: "@types/long@npm:4.0.2"
|
||||
@@ -20907,6 +21036,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/coverage-v8@npm:^1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "@vitest/coverage-v8@npm:1.6.0"
|
||||
dependencies:
|
||||
"@ampproject/remapping": ^2.2.1
|
||||
"@bcoe/v8-coverage": ^0.2.3
|
||||
debug: ^4.3.4
|
||||
istanbul-lib-coverage: ^3.2.2
|
||||
istanbul-lib-report: ^3.0.1
|
||||
istanbul-lib-source-maps: ^5.0.4
|
||||
istanbul-reports: ^3.1.6
|
||||
magic-string: ^0.30.5
|
||||
magicast: ^0.3.3
|
||||
picocolors: ^1.0.0
|
||||
std-env: ^3.5.0
|
||||
strip-literal: ^2.0.0
|
||||
test-exclude: ^6.0.0
|
||||
peerDependencies:
|
||||
vitest: 1.6.0
|
||||
checksum: f5f29ec8768bc221f01f0183f7b326fc88113c6f1cdf215713f4ee00a47d01fd3ce446d1cd38935a005caab17f560490b351927e7e939669d39dbdf5ddf29360
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/expect@npm:1.3.1":
|
||||
version: 1.3.1
|
||||
resolution: "@vitest/expect@npm:1.3.1"
|
||||
@@ -20929,6 +21081,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/expect@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "@vitest/expect@npm:1.6.0"
|
||||
dependencies:
|
||||
"@vitest/spy": 1.6.0
|
||||
"@vitest/utils": 1.6.0
|
||||
chai: ^4.3.10
|
||||
checksum: f3a9959ea387622297efed9e3689fd405044a813df5d5923302eaaea831e250d8d6a0ccd44fb387a95c19963242695ed803afc7c46ae06c48a8e06f194951984
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/runner@npm:1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "@vitest/runner@npm:1.4.0"
|
||||
@@ -20940,6 +21103,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/runner@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "@vitest/runner@npm:1.6.0"
|
||||
dependencies:
|
||||
"@vitest/utils": 1.6.0
|
||||
p-limit: ^5.0.0
|
||||
pathe: ^1.1.1
|
||||
checksum: 2dcd953477d5effc051376e35a7f2c2b28abbe07c54e61157c9a6d6f01c880e079592c959397b3a55471423256ab91709c150881a33632558b81b1e251a0bf9c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/snapshot@npm:1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "@vitest/snapshot@npm:1.4.0"
|
||||
@@ -20951,6 +21125,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/snapshot@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "@vitest/snapshot@npm:1.6.0"
|
||||
dependencies:
|
||||
magic-string: ^0.30.5
|
||||
pathe: ^1.1.1
|
||||
pretty-format: ^29.7.0
|
||||
checksum: c4249fbf3ce310de86a19529a0a5c10b1bde4d8d8a678029c632335969b86cbdbf51cedc20d5e9c9328afee834d13cec1b8de5d0fd58139bf8e2dd8dcd0797f4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/spy@npm:1.3.1":
|
||||
version: 1.3.1
|
||||
resolution: "@vitest/spy@npm:1.3.1"
|
||||
@@ -20969,6 +21154,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/spy@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "@vitest/spy@npm:1.6.0"
|
||||
dependencies:
|
||||
tinyspy: ^2.2.0
|
||||
checksum: 0201975232255e1197f70fc6b23a1ff5e606138a5b96598fff06077d5b747705391013ee98f951affcfd8f54322e4ae1416200393248bb6a9c794f4ef663a066
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/ui@npm:^1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "@vitest/ui@npm:1.4.0"
|
||||
@@ -21010,6 +21204,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/utils@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "@vitest/utils@npm:1.6.0"
|
||||
dependencies:
|
||||
diff-sequences: ^29.6.3
|
||||
estree-walker: ^3.0.3
|
||||
loupe: ^2.3.7
|
||||
pretty-format: ^29.7.0
|
||||
checksum: a4749533a48e7e4bbc8eafee0fee0e9a0d4eaa4910fbdb490d34e16f8ebcce59a2b38529b9e6b4578e3b4510ea67b29384c93165712b0a19f2e71946922d2c56
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/language-core@npm:1.10.1, @volar/language-core@npm:~1.10.0":
|
||||
version: 1.10.1
|
||||
resolution: "@volar/language-core@npm:1.10.1"
|
||||
@@ -21028,6 +21234,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/language-core@npm:1.11.1, @volar/language-core@npm:~1.11.1":
|
||||
version: 1.11.1
|
||||
resolution: "@volar/language-core@npm:1.11.1"
|
||||
dependencies:
|
||||
"@volar/source-map": 1.11.1
|
||||
checksum: 7f98fbeb96ff1093dbaa47e790575a98d1fd2103d9bb1598ec7b0ae787fc6af2ffcea12fdea0f0a4e057f38f6ee3a60bd54f2af3985159319021771f79df9451
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/language-core@npm:1.4.0-alpha.4":
|
||||
version: 1.4.0-alpha.4
|
||||
resolution: "@volar/language-core@npm:1.4.0-alpha.4"
|
||||
@@ -21073,6 +21288,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/source-map@npm:1.11.1, @volar/source-map@npm:~1.11.1":
|
||||
version: 1.11.1
|
||||
resolution: "@volar/source-map@npm:1.11.1"
|
||||
dependencies:
|
||||
muggle-string: ^0.3.1
|
||||
checksum: 1ec1034432ee51a0afe187ba9158292dd607a90d01120ee8a36cf27f5d464da5282c8fe7b0de82f52f45474a840c63eba666254c5c21ca5466dc02d0c95cd147
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/source-map@npm:1.4.0-alpha.4":
|
||||
version: 1.4.0-alpha.4
|
||||
resolution: "@volar/source-map@npm:1.4.0-alpha.4"
|
||||
@@ -21128,6 +21352,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/typescript@npm:~1.11.1":
|
||||
version: 1.11.1
|
||||
resolution: "@volar/typescript@npm:1.11.1"
|
||||
dependencies:
|
||||
"@volar/language-core": 1.11.1
|
||||
path-browserify: ^1.0.1
|
||||
checksum: 0db2fc32db133e493f05dbafd248560a6d4e5b071a0d80422c67b1875bd36980c113915d876a83e855d55c2880b2e7b9f04f803ce3504a4d6fafcc0b801c621b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/typescript@npm:~2.1.3":
|
||||
version: 2.1.6
|
||||
resolution: "@volar/typescript@npm:2.1.6"
|
||||
@@ -21959,6 +22193,28 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/language-core@npm:1.8.27, @vue/language-core@npm:^1.8.27":
|
||||
version: 1.8.27
|
||||
resolution: "@vue/language-core@npm:1.8.27"
|
||||
dependencies:
|
||||
"@volar/language-core": ~1.11.1
|
||||
"@volar/source-map": ~1.11.1
|
||||
"@vue/compiler-dom": ^3.3.0
|
||||
"@vue/shared": ^3.3.0
|
||||
computeds: ^0.0.1
|
||||
minimatch: ^9.0.3
|
||||
muggle-string: ^0.3.1
|
||||
path-browserify: ^1.0.1
|
||||
vue-template-compiler: ^2.7.14
|
||||
peerDependencies:
|
||||
typescript: "*"
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 8660c05319be8dc5daacc2cd929171434215d29f3ad5bfbe0038d1967db05b8bf640286b25f338845cc1e3890b4aaa239ac9e8cb832cc8a50a5bbdff31b2edd1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/language-core@npm:1.8.8":
|
||||
version: 1.8.8
|
||||
resolution: "@vue/language-core@npm:1.8.8"
|
||||
@@ -29384,7 +29640,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0, esbuild@npm:^0.20.2":
|
||||
"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0, esbuild@npm:^0.20.1, esbuild@npm:^0.20.2":
|
||||
version: 0.20.2
|
||||
resolution: "esbuild@npm:0.20.2"
|
||||
dependencies:
|
||||
@@ -34836,6 +35092,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-lib-coverage@npm:^3.2.2":
|
||||
version: 3.2.2
|
||||
resolution: "istanbul-lib-coverage@npm:3.2.2"
|
||||
checksum: 2367407a8d13982d8f7a859a35e7f8dd5d8f75aae4bb5484ede3a9ea1b426dc245aff28b976a2af48ee759fdd9be374ce2bd2669b644f31e76c5f46a2e29a831
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-lib-hook@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "istanbul-lib-hook@npm:3.0.0"
|
||||
@@ -34909,6 +35172,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-lib-report@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "istanbul-lib-report@npm:3.0.1"
|
||||
dependencies:
|
||||
istanbul-lib-coverage: ^3.0.0
|
||||
make-dir: ^4.0.0
|
||||
supports-color: ^7.1.0
|
||||
checksum: fd17a1b879e7faf9bb1dc8f80b2a16e9f5b7b8498fe6ed580a618c34df0bfe53d2abd35bf8a0a00e628fb7405462576427c7df20bbe4148d19c14b431c974b21
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-lib-source-maps@npm:^4.0.0":
|
||||
version: 4.0.1
|
||||
resolution: "istanbul-lib-source-maps@npm:4.0.1"
|
||||
@@ -34920,6 +35194,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-lib-source-maps@npm:^5.0.4":
|
||||
version: 5.0.4
|
||||
resolution: "istanbul-lib-source-maps@npm:5.0.4"
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping": ^0.3.23
|
||||
debug: ^4.1.1
|
||||
istanbul-lib-coverage: ^3.0.0
|
||||
checksum: f34550c75b957312787eaa86a6c115b269f090905c0128f8acdb553a8d9b6562581be0e7c0b68247d97172fdfd6445517cbe46651f984453cce3c517b2e931ad
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-reports@npm:^3.0.2":
|
||||
version: 3.1.4
|
||||
resolution: "istanbul-reports@npm:3.1.4"
|
||||
@@ -34940,6 +35225,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"istanbul-reports@npm:^3.1.6":
|
||||
version: 3.1.7
|
||||
resolution: "istanbul-reports@npm:3.1.7"
|
||||
dependencies:
|
||||
html-escaper: ^2.0.0
|
||||
istanbul-lib-report: ^3.0.0
|
||||
checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iterall@npm:^1.2.1, iterall@npm:^1.3.0":
|
||||
version: 1.3.0
|
||||
resolution: "iterall@npm:1.3.0"
|
||||
@@ -38020,6 +38315,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magicast@npm:^0.3.3":
|
||||
version: 0.3.4
|
||||
resolution: "magicast@npm:0.3.4"
|
||||
dependencies:
|
||||
"@babel/parser": ^7.24.4
|
||||
"@babel/types": ^7.24.0
|
||||
source-map-js: ^1.2.0
|
||||
checksum: 9cc84b8424d2c9b03533c16abec5b29f3897619a07714232c602382660867140858f54f482da2b9968ba4b89e198e66578f483415256c4eb2656ae7265bbb2de
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-dir@npm:^2.0.0, make-dir@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "make-dir@npm:2.1.0"
|
||||
@@ -38039,6 +38345,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-dir@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "make-dir@npm:4.0.0"
|
||||
dependencies:
|
||||
semver: ^7.5.3
|
||||
checksum: bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-error@npm:^1.1.1, make-error@npm:^1.3.6":
|
||||
version: 1.3.6
|
||||
resolution: "make-error@npm:1.3.6"
|
||||
@@ -38618,7 +38933,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:~3.0.4":
|
||||
"minimatch@npm:~3.0.3, minimatch@npm:~3.0.4":
|
||||
version: 3.0.8
|
||||
resolution: "minimatch@npm:3.0.8"
|
||||
dependencies:
|
||||
@@ -43933,6 +44248,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss@npm:^8.4.38":
|
||||
version: 8.4.38
|
||||
resolution: "postcss@npm:8.4.38"
|
||||
dependencies:
|
||||
nanoid: ^3.3.7
|
||||
picocolors: ^1.0.0
|
||||
source-map-js: ^1.2.0
|
||||
checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postgres-array@npm:~2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "postgres-array@npm:2.0.0"
|
||||
@@ -47512,6 +47838,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"source-map-js@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "source-map-js@npm:1.2.0"
|
||||
checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"source-map-support@npm:0.5.13":
|
||||
version: 0.5.13
|
||||
resolution: "source-map-support@npm:0.5.13"
|
||||
@@ -48507,7 +48840,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"supports-color@npm:8.1.1, supports-color@npm:^8.0.0, supports-color@npm:^8.1.0, supports-color@npm:^8.1.1":
|
||||
"supports-color@npm:8.1.1, supports-color@npm:^8.0.0, supports-color@npm:^8.1.0, supports-color@npm:^8.1.1, supports-color@npm:~8.1.1":
|
||||
version: 8.1.1
|
||||
resolution: "supports-color@npm:8.1.1"
|
||||
dependencies:
|
||||
@@ -49248,6 +49581,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinypool@npm:^0.8.3":
|
||||
version: 0.8.4
|
||||
resolution: "tinypool@npm:0.8.4"
|
||||
checksum: d40c40e062d5eeae85dadc39294dde6bc7b9a7a7cf0c972acbbe5a2b42491dfd4c48381c1e48bbe02aff4890e63de73d115b2e7de2ce4c81356aa5e654a43caf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinyspy@npm:^2.2.0":
|
||||
version: 2.2.1
|
||||
resolution: "tinyspy@npm:2.2.1"
|
||||
@@ -51329,6 +51669,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-node@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "vite-node@npm:1.6.0"
|
||||
dependencies:
|
||||
cac: ^6.7.14
|
||||
debug: ^4.3.4
|
||||
pathe: ^1.1.1
|
||||
picocolors: ^1.0.0
|
||||
vite: ^5.0.0
|
||||
bin:
|
||||
vite-node: vite-node.mjs
|
||||
checksum: ce111c5c7a4cf65b722baa15cbc065b7bfdbf1b65576dd6372995f6a72b2b93773ec5df59f6c5f08cfe1284806597b44b832efcea50d5971102428159ff4379f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-node@npm:^0.33.0":
|
||||
version: 0.33.0
|
||||
resolution: "vite-node@npm:0.33.0"
|
||||
@@ -51467,6 +51822,27 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-plugin-dts@npm:^3.9.1":
|
||||
version: 3.9.1
|
||||
resolution: "vite-plugin-dts@npm:3.9.1"
|
||||
dependencies:
|
||||
"@microsoft/api-extractor": 7.43.0
|
||||
"@rollup/pluginutils": ^5.1.0
|
||||
"@vue/language-core": ^1.8.27
|
||||
debug: ^4.3.4
|
||||
kolorist: ^1.8.0
|
||||
magic-string: ^0.30.8
|
||||
vue-tsc: ^1.8.27
|
||||
peerDependencies:
|
||||
typescript: "*"
|
||||
vite: "*"
|
||||
peerDependenciesMeta:
|
||||
vite:
|
||||
optional: true
|
||||
checksum: e048b509995ae4ed883aa4cc2397d8ab7929865b70ba3710ed853d5d37de1c7f49389f7e2dc89404a729624f4d2738dc9616450f868eef8e2861ebc6673099e5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-plugin-inspect@npm:^0.7.15":
|
||||
version: 0.7.16
|
||||
resolution: "vite-plugin-inspect@npm:0.7.16"
|
||||
@@ -51633,6 +52009,46 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:^5.2.0":
|
||||
version: 5.2.13
|
||||
resolution: "vite@npm:5.2.13"
|
||||
dependencies:
|
||||
esbuild: ^0.20.1
|
||||
fsevents: ~2.3.3
|
||||
postcss: ^8.4.38
|
||||
rollup: ^4.13.0
|
||||
peerDependencies:
|
||||
"@types/node": ^18.0.0 || >=20.0.0
|
||||
less: "*"
|
||||
lightningcss: ^1.21.0
|
||||
sass: "*"
|
||||
stylus: "*"
|
||||
sugarss: "*"
|
||||
terser: ^5.4.0
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
peerDependenciesMeta:
|
||||
"@types/node":
|
||||
optional: true
|
||||
less:
|
||||
optional: true
|
||||
lightningcss:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
sugarss:
|
||||
optional: true
|
||||
terser:
|
||||
optional: true
|
||||
bin:
|
||||
vite: bin/vite.js
|
||||
checksum: 79620413e45804494bedb81f2b78b48ca1d26fb026894a114a2f40cb1a3ad9b6783e777bc8969a51f8711e168b4db93a9563a5af027c80eecf000ef9b675a3be
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:~4.3.9":
|
||||
version: 4.3.9
|
||||
resolution: "vite@npm:4.3.9"
|
||||
@@ -51720,6 +52136,56 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vitest@npm:^1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "vitest@npm:1.6.0"
|
||||
dependencies:
|
||||
"@vitest/expect": 1.6.0
|
||||
"@vitest/runner": 1.6.0
|
||||
"@vitest/snapshot": 1.6.0
|
||||
"@vitest/spy": 1.6.0
|
||||
"@vitest/utils": 1.6.0
|
||||
acorn-walk: ^8.3.2
|
||||
chai: ^4.3.10
|
||||
debug: ^4.3.4
|
||||
execa: ^8.0.1
|
||||
local-pkg: ^0.5.0
|
||||
magic-string: ^0.30.5
|
||||
pathe: ^1.1.1
|
||||
picocolors: ^1.0.0
|
||||
std-env: ^3.5.0
|
||||
strip-literal: ^2.0.0
|
||||
tinybench: ^2.5.1
|
||||
tinypool: ^0.8.3
|
||||
vite: ^5.0.0
|
||||
vite-node: 1.6.0
|
||||
why-is-node-running: ^2.2.2
|
||||
peerDependencies:
|
||||
"@edge-runtime/vm": "*"
|
||||
"@types/node": ^18.0.0 || >=20.0.0
|
||||
"@vitest/browser": 1.6.0
|
||||
"@vitest/ui": 1.6.0
|
||||
happy-dom: "*"
|
||||
jsdom: "*"
|
||||
peerDependenciesMeta:
|
||||
"@edge-runtime/vm":
|
||||
optional: true
|
||||
"@types/node":
|
||||
optional: true
|
||||
"@vitest/browser":
|
||||
optional: true
|
||||
"@vitest/ui":
|
||||
optional: true
|
||||
happy-dom:
|
||||
optional: true
|
||||
jsdom:
|
||||
optional: true
|
||||
bin:
|
||||
vitest: vitest.mjs
|
||||
checksum: a9b9b97e5685d630e5d8d221e6d6cd2e1e9b5b2dd61e82042839ef11549c8d2d780cf696307de406dce804bf41c1219398cb20b4df570b3b47ad1e53af6bfe51
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"void-elements@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "void-elements@npm:3.1.0"
|
||||
@@ -52168,6 +52634,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vue-tsc@npm:^1.8.27":
|
||||
version: 1.8.27
|
||||
resolution: "vue-tsc@npm:1.8.27"
|
||||
dependencies:
|
||||
"@volar/typescript": ~1.11.1
|
||||
"@vue/language-core": 1.8.27
|
||||
semver: ^7.5.4
|
||||
peerDependencies:
|
||||
typescript: "*"
|
||||
bin:
|
||||
vue-tsc: bin/vue-tsc.js
|
||||
checksum: 98c2986df01000a3245b5f08b9db35d0ead4f46fb12f4fe771257b4aa61aa4c26dda359aaa0e6c484a6240563d5188aaa6ed312dd37cc2315922d5e079260001
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vue-tsc@npm:^1.8.8":
|
||||
version: 1.8.8
|
||||
resolution: "vue-tsc@npm:1.8.8"
|
||||
|
||||
Reference in New Issue
Block a user