initial commit
This commit is contained in:
commit
18eaa2daaa
44
.gitea/workflows/publish.yaml
Normal file
44
.gitea/workflows/publish.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: 'https://registry.npmjs.org/'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run type check
|
||||
run: npm run type-check
|
||||
|
||||
- name: Build library
|
||||
run: npm run build
|
||||
|
||||
- name: Determine npm tag
|
||||
id: determine_tag
|
||||
run: |
|
||||
IS_PRERELEASE=${{ github.event.release.prerelease }}
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
if [[ "$VERSION" =~ -(alpha|beta|rc|dev) ]]; then
|
||||
echo "NPM_TAG=dev" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "NPM_TAG=latest" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Publish to npm
|
||||
run: npm publish --access public --tag ${{ steps.determine_tag.outputs.NPM_TAG }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@ -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?
|
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
324
README.md
Normal file
324
README.md
Normal file
@ -0,0 +1,324 @@
|
||||
# @openharbor/vue-data
|
||||
|
||||
A Vue 3 Composition API library for simplified data management with CQRS backends, powered by a flexible builder pattern. This library helps you effortlessly connect your Vue components to backend services using a POST-centric interaction model, providing reactive data, loading states, and robust error handling.
|
||||
|
||||
## Features
|
||||
|
||||
* **Vue 3 Composition API:** Fully integrated with Vue's reactivity system.
|
||||
* **CQRS-Oriented:** Designed for backends that use POST requests for both queries and commands.
|
||||
* **Flexible Data Source Builders:** Configure data fetching and command execution with a fluent API.
|
||||
* **Reactive State Management:** Automatically tracks `data`/`items`, `total`, `loading` status, and `error` states.
|
||||
* **Pluggable Commands:** Easily define domain-specific commands (e.g., `AddProduct`, `RemoveProduct`, `UpdateProductDetails`, `PlaceOrder`).
|
||||
* **Standardized Error Handling:** Consistent approach to backend error messages and validation errors.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
To use this library in your Vue 3 project, you need to install it via npm or Yarn. Remember that `vue` is a peer dependency, so ensure you have Vue 3 installed in your project.
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm install @openharbor/vue-data
|
||||
|
||||
# Using Yarn
|
||||
yarn add @openharbor/vue-data
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The library provides three main composables: `useHttpDataSource`, `useSingleDataSource`, and `useListDataSource`, each tailored for different data interaction patterns.
|
||||
|
||||
### Core Concepts
|
||||
|
||||
* **Query Criteria (`IQueryCriteria`):** An object defining the parameters for your data requests (e.g., filters, pagination, sorting).
|
||||
* **Models (`TModel`):** The shape of the data objects you are fetching or sending as commands.
|
||||
* **Commands (`ICommand`):** The data payload sent to your backend for actions (e.g., `AddProductCommand`, `RemoveProductCommand`, `UpdateProductDetailsCommand`).
|
||||
* **`keyResolver`:** A function `(model: TModel) => TModel[keyof TModel]` that extracts a unique identifier (like an `id`) from your model. This is crucial for `useSingleDataSource` and for certain command resolution scenarios.
|
||||
* **`autoFetch`:** A boolean option to automatically trigger a `read` operation when the component mounts or when `criteria` changes.
|
||||
|
||||
### `useHttpDataSource`
|
||||
|
||||
This is the most generic data source composable. It's suitable for a wide range of querying and commanding needs where the structure isn't strictly a single item or a traditional list.
|
||||
|
||||
```typescript
|
||||
// Example: src/views/MyGenericDataComponent.vue
|
||||
<script setup lang="ts">
|
||||
import { ref, watchEffect } from 'vue';
|
||||
import { useHttpDataSource, type IQueryCriteria } from '@openharbor/vue-data'; // <-- Updated import path
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
name: string;
|
||||
price: number;
|
||||
}
|
||||
|
||||
interface ProductQueryCriteria extends IQueryCriteria {
|
||||
searchText?: string;
|
||||
minPrice?: number;
|
||||
}
|
||||
|
||||
const productDataSource = useHttpDataSource<ProductQueryCriteria, Product>({
|
||||
queryUrl: '/api/products/query', // Your backend's POST endpoint for querying products
|
||||
keyResolver: (product) => product.id,
|
||||
commands: {
|
||||
// Command to add a new product
|
||||
'addProduct': {
|
||||
url: '/api/products/add', // Your backend's POST endpoint for adding a product
|
||||
},
|
||||
// Command to update product details
|
||||
'updateProductDetails': {
|
||||
url: '/api/products/update', // Your backend's POST endpoint for updating
|
||||
},
|
||||
// Command to remove a product
|
||||
'removeProduct': {
|
||||
url: '/api/products/remove', // Your backend's POST endpoint for removing
|
||||
}
|
||||
},
|
||||
defaultCriteria: {
|
||||
searchText: '',
|
||||
minPrice: 0
|
||||
},
|
||||
autoFetch: true // Fetch data on mount and when criteria changes
|
||||
});
|
||||
|
||||
// Access reactive state
|
||||
const { data, total, loading, error, criteria, read, executeCommand } = productDataSource;
|
||||
|
||||
// Modify criteria to trigger a re-fetch (if autoFetch is true)
|
||||
criteria.value.searchText = 'new search term';
|
||||
|
||||
// Manually trigger a read (overrides current reactive criteria for this call)
|
||||
// await read({ searchText: 'specific term' });
|
||||
|
||||
// Execute an 'addProduct' command
|
||||
const addProduct = async () => {
|
||||
try {
|
||||
const newProduct = await executeCommand('addProduct', {
|
||||
name: 'New Gadget',
|
||||
price: 99.99
|
||||
});
|
||||
console.log('Product added:', newProduct);
|
||||
// After adding, you might want to refresh the list manually
|
||||
await read();
|
||||
} catch (e) {
|
||||
console.error('Error adding product:', e);
|
||||
}
|
||||
};
|
||||
|
||||
// Execute a 'removeProduct' command
|
||||
const removeProductById = async (id: string) => {
|
||||
try {
|
||||
// Assuming your removeProduct command expects an object like { productId: '...' } as payload
|
||||
await executeCommand('removeProduct', { productId: id });
|
||||
console.log('Product removed:', id);
|
||||
// After removing, autoFetch might re-trigger, or you can manually read()
|
||||
} catch (e) {
|
||||
console.error('Error removing product:', e);
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (error.value) {
|
||||
console.error('Data source error:', error.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>Products</h1>
|
||||
<input v-model="criteria.searchText" placeholder="Search products" />
|
||||
<p v-if="loading">Loading products...</p>
|
||||
<p v-if="error">Error: {{ error.message }}</p>
|
||||
<ul v-if="data">
|
||||
<li v-for="product in data" :key="product.id">
|
||||
{{ product.name }} - ${{ product.price }}
|
||||
<button @click="removeProductById(product.id)">Remove</button>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-if="total !== null">Total products: {{ total }}</p>
|
||||
<button @click="addProduct">Add New Product</button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### `useSingleDataSource`
|
||||
|
||||
Best for managing a single entity (e.g., editing a product details page, displaying a user profile). It requires a `keyResolver` and can easily set up common CQRS commands for a single entity.
|
||||
|
||||
```typescript
|
||||
// Example: src/views/ProductDetailComponent.vue
|
||||
<script setup lang="ts">
|
||||
import { ref, watchEffect } from 'vue';
|
||||
import { useSingleDataSource, type IQueryCriteria } from '@openharbor/vue-data'; // <-- Updated import path
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
interface ProductDetailQueryCriteria extends IQueryCriteria {
|
||||
productId: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{ id: string }>();
|
||||
|
||||
// Define reactive form data for editing
|
||||
const editedProduct = ref<Product | null>(null);
|
||||
|
||||
const productDetailSource = useSingleDataSource<ProductDetailQueryCriteria, Product>({
|
||||
queryUrl: '/api/products/detail', // Endpoint to fetch single product details
|
||||
keyResolver: (product) => product.id,
|
||||
defaultCriteria: {
|
||||
productId: props.id // Initial query based on prop
|
||||
},
|
||||
// Automatically add common commands for a single entity
|
||||
addStandardRestCommands: { // NOTE: This option name can be changed to 'addStandardCqrsCommands'
|
||||
route: '/api/commands/products' // A single command endpoint for product-related commands
|
||||
},
|
||||
autoFetch: true // Fetch details on mount
|
||||
});
|
||||
|
||||
const { data, loading, error, criteria, read, executeCommand } = productDetailSource;
|
||||
|
||||
// Watch for changes in the fetched data to populate the form
|
||||
watchEffect(() => {
|
||||
if (data.value) {
|
||||
editedProduct.value = { ...data.value }; // Create a copy for editing
|
||||
}
|
||||
});
|
||||
|
||||
// Update criteria if props.id changes
|
||||
watch(() => props.id, (newId) => {
|
||||
if (newId) {
|
||||
criteria.value.productId = newId;
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
const saveProductChanges = async () => {
|
||||
if (!editedProduct.value) return;
|
||||
try {
|
||||
// Assuming 'update' command expects the full product object as payload
|
||||
// Command type would likely be inferred by the backend from the payload, or a specific command object.
|
||||
const updated = await executeCommand('update', editedProduct.value);
|
||||
console.log('Product updated:', updated);
|
||||
// After update, data.value will automatically be updated by the composable
|
||||
} catch (e) {
|
||||
console.error('Error saving product changes:', e);
|
||||
}
|
||||
};
|
||||
|
||||
const removeSelectedProduct = async () => {
|
||||
if (!data.value) return;
|
||||
if (!confirm(`Are you sure you want to remove ${data.value.name}?`)) return;
|
||||
|
||||
try {
|
||||
// Assuming 'delete' (now 'removeProduct') command expects the product object or its ID in the payload
|
||||
await executeCommand('delete', { productId: data.value.id }); // Using 'delete' as internal key for addStandardRestCommands
|
||||
console.log('Product removed!');
|
||||
// After remove, data.value will be set to null by the composable
|
||||
// You might want to redirect the user after removal
|
||||
} catch (e) {
|
||||
console.error('Error removing product:', e);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 v-if="loading">Loading Product Details...</h1>
|
||||
<p v-if="error">Error: {{ error.message }}</p>
|
||||
|
||||
<div v-if="editedProduct">
|
||||
<h2>Edit Product: {{ editedProduct.name }}</h2>
|
||||
<label>Name: <input v-model="editedProduct.name" /></label><br />
|
||||
<label>Description: <textarea v-model="editedProduct.description"></textarea></label><br />
|
||||
<button @click="saveProductChanges">Save Changes</button>
|
||||
<button @click="removeSelectedProduct">Remove Product</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### `useListDataSource`
|
||||
|
||||
Ideal for displaying collections of data, such as tables, grids, or paginated lists. It functions as a semantic wrapper around `useHttpDataSource` for clarity.
|
||||
|
||||
```typescript
|
||||
// Example: src/views/ProductListingComponent.vue
|
||||
<script setup lang="ts">
|
||||
import { ref, watchEffect } from 'vue';
|
||||
import { useListDataSource, type IQueryCriteria } from '@openharbor/vue-data'; // <-- Updated import path
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
name: string;
|
||||
category: string;
|
||||
}
|
||||
|
||||
interface ProductsListQueryCriteria extends IQueryCriteria {
|
||||
pageNumber: number;
|
||||
pageSize: number;
|
||||
sortBy: string;
|
||||
filterByCategory?: string;
|
||||
}
|
||||
|
||||
const paginationCriteria = ref<ProductsListQueryCriteria>({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
sortBy: 'name'
|
||||
});
|
||||
|
||||
const productsListSource = useListDataSource<ProductsListQueryCriteria, Product>({
|
||||
queryUrl: '/api/products/list', // Your backend's POST endpoint for listing products
|
||||
defaultCriteria: paginationCriteria.value,
|
||||
autoFetch: true // Fetch when criteria changes
|
||||
});
|
||||
|
||||
const { items, total, loading, error, criteria, read } = productsListSource;
|
||||
|
||||
const nextPage = () => {
|
||||
if (total.value && criteria.value.pageNumber * criteria.value.pageSize < total.value) {
|
||||
criteria.value.pageNumber++;
|
||||
}
|
||||
};
|
||||
|
||||
const prevPage = () => {
|
||||
if (criteria.value.pageNumber > 1) {
|
||||
criteria.value.pageNumber--;
|
||||
}
|
||||
};
|
||||
|
||||
// You can still add commands here if needed for list-level operations (e.g., bulk remove)
|
||||
// productsListSource.executeCommand('bulkRemove', { productIds: ['id1', 'id2'] });
|
||||
|
||||
watchEffect(() => {
|
||||
if (error.value) {
|
||||
console.error('Product list error:', error.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>Product Catalog</h1>
|
||||
<p v-if="loading">Loading products...</p>
|
||||
<p v-if="error">Error: {{ error.message }}</p>
|
||||
|
||||
<div v-if="items">
|
||||
<ul>
|
||||
<li v-for="product in items" :key="product.id">
|
||||
{{ product.name }} ({{ product.category }})
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<button @click="prevPage" :disabled="criteria.pageNumber === 1">Previous</button>
|
||||
<span>Page {{ criteria.pageNumber }} of {{ total ? Math.ceil(total / criteria.pageSize) : 1 }}</span>
|
||||
<button @click="nextPage" :disabled="total ? criteria.value.pageNumber * criteria.value.pageSize >= total : true">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!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>Vite + Vue + TS</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
47
package.json
Normal file
47
package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "@openharbor/vue-data",
|
||||
"author": "Open Harbor",
|
||||
"private": false,
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"description": "Vue 3 Composition API implementation for OpenHarbor data management.",
|
||||
"type": "module",
|
||||
"main": "./dist/vue-openharbor-data.umd.cjs",
|
||||
"module": "./dist/vue-openharbor-data.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/vue-openharbor-data.js",
|
||||
"require": "./dist/vue-openharbor-data.umd.cjs"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"type-check": "vue-tsc --noEmit --composite false"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue": {
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.6",
|
||||
"@types/node": "^24.0.3",
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"typescript": "~5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vue": "^3.5.13",
|
||||
"vue-tsc": "^2.2.8"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
|
||||
}
|
0
src/composables/index.ts
Normal file
0
src/composables/index.ts
Normal file
157
src/composables/use-http-data-source.ts
Normal file
157
src/composables/use-http-data-source.ts
Normal file
@ -0,0 +1,157 @@
|
||||
// src/composables/use-http-data-source.ts
|
||||
|
||||
import { ref, readonly, watch, type Ref } from 'vue';
|
||||
import {
|
||||
type IQueryCriteria,
|
||||
type ICommand,
|
||||
type IQueryExecutionResult,
|
||||
type IQueryExecutionGroupResult,
|
||||
type IDataSourceError,
|
||||
type IDataSourceOptions,
|
||||
type IResolveCommandModelEvent
|
||||
} from '../core/types';
|
||||
import { HttpDataSourceBuilder } from '../core/http-data-source-builder.ts';
|
||||
|
||||
|
||||
export interface UseHttpDataSourceOptions<TQuery extends IQueryCriteria, TModel extends ICommand> {
|
||||
queryUrl?: string;
|
||||
queryHandler?: (query: TQuery) => Promise<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>;
|
||||
beforeRead?: (query: IQueryCriteria) => Promise<TQuery>;
|
||||
defaultCriteria?: TQuery;
|
||||
|
||||
keyResolver?: (model: TModel) => TModel[keyof TModel];
|
||||
|
||||
commands?: {
|
||||
[name: string]: {
|
||||
url?: string;
|
||||
handler?: (command: any) => Promise<any>;
|
||||
resolveCommandModel?: (event: IResolveCommandModelEvent<TModel>) => Promise<any>;
|
||||
beforeCommand?: (command: any) => Promise<any>;
|
||||
};
|
||||
};
|
||||
|
||||
autoFetch?: boolean;
|
||||
}
|
||||
|
||||
export function useHttpDataSource<TQuery extends IQueryCriteria = IQueryCriteria, TModel extends ICommand = any>(
|
||||
options: UseHttpDataSourceOptions<TQuery, TModel>
|
||||
) {
|
||||
const data: Ref<TModel[] | null> = ref(null);
|
||||
const total: Ref<number | null> = ref(null);
|
||||
const loading = ref(false);
|
||||
const error: Ref<IDataSourceError | null> = ref(null);
|
||||
|
||||
const criteria: Ref<TQuery> = ref(options.defaultCriteria || {} as TQuery) as Ref<TQuery>;
|
||||
|
||||
const builder = new HttpDataSourceBuilder<TQuery, TModel>();
|
||||
|
||||
if (options.keyResolver) {
|
||||
builder.keyResolver(options.keyResolver);
|
||||
}
|
||||
if (options.defaultCriteria) {
|
||||
builder.defaultCriteria(options.defaultCriteria);
|
||||
}
|
||||
if (options.beforeRead) {
|
||||
builder.beforeRead(options.beforeRead);
|
||||
}
|
||||
|
||||
if (options.queryUrl) {
|
||||
builder.queryUrl(options.queryUrl);
|
||||
} else if (options.queryHandler) {
|
||||
builder.queryHandler(options.queryHandler);
|
||||
} else {
|
||||
console.warn("useHttpDataSource: No queryUrl or queryHandler provided. Data will not be fetched.");
|
||||
}
|
||||
|
||||
if (options.commands) {
|
||||
for (const name in options.commands) {
|
||||
if (Object.prototype.hasOwnProperty.call(options.commands, name)) {
|
||||
const commandOptions = options.commands[name];
|
||||
if (commandOptions.handler) {
|
||||
builder.addCommandByCallback(name, commandOptions.handler, commandOptions.resolveCommandModel);
|
||||
} else if (commandOptions.url) {
|
||||
builder.addCommandByUrl(name, commandOptions.url, commandOptions.resolveCommandModel, commandOptions.beforeCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const dataSourceOptions: IDataSourceOptions<TQuery, TModel> = builder.createOptions();
|
||||
|
||||
const _read = async (query?: TQuery) => {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
data.value = null;
|
||||
total.value = null;
|
||||
|
||||
try {
|
||||
const finalQuery = query || criteria.value;
|
||||
const result = await dataSourceOptions.transport.query.adapter.handle(finalQuery);
|
||||
data.value = result.items;
|
||||
total.value = result.total;
|
||||
} catch (e: any) {
|
||||
error.value = e as IDataSourceError;
|
||||
console.error("Data source query failed:", e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const read = async (overrideQuery?: TQuery) => {
|
||||
if (overrideQuery) {
|
||||
criteria.value = overrideQuery;
|
||||
}
|
||||
await _read(criteria.value);
|
||||
};
|
||||
|
||||
const executeCommand = async (commandName: string, commandData: any): Promise<any> => {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
|
||||
try {
|
||||
const commandAdapter = dataSourceOptions.transport.commands[commandName];
|
||||
if (!commandAdapter) {
|
||||
throw new Error(`Command "${commandName}" is not defined for this data source.`);
|
||||
}
|
||||
|
||||
let finalCommandData = commandData;
|
||||
if (commandAdapter.resolveCommandModel) {
|
||||
const modelToResolveFrom = options.keyResolver && data.value && data.value.length > 0
|
||||
? data.value.find(item => options.keyResolver!(item) === options.keyResolver!(commandData))
|
||||
: null;
|
||||
|
||||
finalCommandData = await commandAdapter.resolveCommandModel({
|
||||
model: modelToResolveFrom || commandData,
|
||||
data: commandData
|
||||
});
|
||||
}
|
||||
|
||||
const result = await commandAdapter.adapter.handle(finalCommandData);
|
||||
return result;
|
||||
} catch (e: any) {
|
||||
error.value = e as IDataSourceError;
|
||||
console.error(`Data source command '${commandName}' failed:`, e);
|
||||
throw e;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (options.autoFetch) {
|
||||
watch(criteria, async () => {
|
||||
await _read();
|
||||
}, { immediate: true, deep: true });
|
||||
}
|
||||
|
||||
return {
|
||||
data: readonly(data),
|
||||
total: readonly(total),
|
||||
loading: readonly(loading),
|
||||
error: readonly(error),
|
||||
|
||||
criteria,
|
||||
|
||||
read,
|
||||
executeCommand,
|
||||
};
|
||||
}
|
45
src/composables/use-list-data-source.ts
Normal file
45
src/composables/use-list-data-source.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import {
|
||||
type IQueryCriteria,
|
||||
type ICommand,
|
||||
type IQueryExecutionResult,
|
||||
type IQueryExecutionGroupResult,
|
||||
type IResolveCommandModelEvent
|
||||
} from '../core/types';
|
||||
import { useHttpDataSource } from './use-http-data-source.ts';
|
||||
|
||||
|
||||
export interface UseListDataSourceOptions<TQuery extends IQueryCriteria, TModel extends ICommand> {
|
||||
queryUrl?: string;
|
||||
queryHandler?: (query: TQuery) => Promise<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>;
|
||||
beforeRead?: (query: IQueryCriteria) => Promise<TQuery>;
|
||||
defaultCriteria?: TQuery;
|
||||
|
||||
keyResolver?: (model: TModel) => TModel[keyof TModel];
|
||||
|
||||
commands?: {
|
||||
[name: string]: {
|
||||
url?: string;
|
||||
handler?: (command: any) => Promise<any>;
|
||||
resolveCommandModel?: (event: IResolveCommandModelEvent<TModel>) => Promise<any>;
|
||||
beforeCommand?: (command: any) => Promise<any>;
|
||||
};
|
||||
};
|
||||
|
||||
autoFetch?: boolean;
|
||||
}
|
||||
|
||||
export function useListDataSource<TQuery extends IQueryCriteria = IQueryCriteria, TModel extends ICommand = any>(
|
||||
options: UseListDataSourceOptions<TQuery, TModel>
|
||||
) {
|
||||
const { data, total, loading, error, criteria, read, executeCommand } = useHttpDataSource(options);
|
||||
|
||||
return {
|
||||
items: data,
|
||||
total,
|
||||
loading,
|
||||
error,
|
||||
criteria,
|
||||
read,
|
||||
executeCommand,
|
||||
};
|
||||
}
|
169
src/composables/use-single-data-source.ts
Normal file
169
src/composables/use-single-data-source.ts
Normal file
@ -0,0 +1,169 @@
|
||||
// src/composables/use-single-data-source.ts
|
||||
|
||||
import { ref, readonly, watch, type Ref } from 'vue';
|
||||
import {
|
||||
type IQueryCriteria,
|
||||
type ICommand,
|
||||
type IQueryExecutionResult,
|
||||
type IDataSourceError,
|
||||
type IResolveCommandModelEvent,
|
||||
type IDataSourceOptions,
|
||||
type IQueryExecutionGroupResult
|
||||
} from '../core/types';
|
||||
import { SingleDataSourceBuilder } from '../core/single-data-source-builder';
|
||||
|
||||
|
||||
export interface UseSingleDataSourceOptions<TQuery extends IQueryCriteria, TModel extends ICommand> {
|
||||
queryUrl?: string;
|
||||
queryHandler?: (query: TQuery) => Promise<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>;
|
||||
beforeRead?: (query: IQueryCriteria) => Promise<TQuery>;
|
||||
defaultCriteria?: TQuery;
|
||||
|
||||
keyResolver: (model: TModel) => TModel[keyof TModel];
|
||||
|
||||
commands?: {
|
||||
[name: string]: {
|
||||
url?: string;
|
||||
handler?: (command: any) => Promise<any>;
|
||||
resolveCommandModel?: (event: IResolveCommandModelEvent<TModel>) => Promise<any>;
|
||||
beforeCommand?: (command: any) => Promise<any>;
|
||||
};
|
||||
};
|
||||
|
||||
addStandardRestCommands?: {
|
||||
route: string;
|
||||
};
|
||||
|
||||
autoFetch?: boolean;
|
||||
}
|
||||
|
||||
export function useSingleDataSource<TQuery extends IQueryCriteria = IQueryCriteria, TModel extends ICommand = any>(
|
||||
options: UseSingleDataSourceOptions<TQuery, TModel>
|
||||
) {
|
||||
const data: Ref<TModel | null> = ref(null);
|
||||
const loading = ref(false);
|
||||
const error: Ref<IDataSourceError | null> = ref(null);
|
||||
|
||||
const criteria: Ref<TQuery> = ref(options.defaultCriteria || {} as TQuery) as Ref<TQuery>;
|
||||
|
||||
const builder = new SingleDataSourceBuilder<TQuery, TModel>();
|
||||
|
||||
if (!options.keyResolver) {
|
||||
throw new Error("useSingleDataSource: 'keyResolver' is mandatory for single data source operations.");
|
||||
}
|
||||
builder.keyResolver(options.keyResolver);
|
||||
|
||||
if (options.defaultCriteria) {
|
||||
builder.defaultCriteria(options.defaultCriteria);
|
||||
}
|
||||
if (options.beforeRead) {
|
||||
builder.beforeRead(options.beforeRead);
|
||||
}
|
||||
|
||||
if (options.queryUrl) {
|
||||
builder.queryUrl(options.queryUrl);
|
||||
} else if (options.queryHandler) {
|
||||
builder.queryHandler(options.queryHandler);
|
||||
} else {
|
||||
console.warn("useSingleDataSource: No queryUrl or queryHandler provided. Data will not be fetched.");
|
||||
}
|
||||
|
||||
if (options.addStandardRestCommands) {
|
||||
builder.addStandardRestCommands(options.addStandardRestCommands.route);
|
||||
}
|
||||
|
||||
if (options.commands) {
|
||||
for (const name in options.commands) {
|
||||
if (Object.prototype.hasOwnProperty.call(options.commands, name)) {
|
||||
const commandOptions = options.commands[name];
|
||||
if (commandOptions.handler) {
|
||||
builder.addCommandByCallback(name, commandOptions.handler, commandOptions.resolveCommandModel);
|
||||
} else if (commandOptions.url) {
|
||||
builder.addCommandByUrl(name, commandOptions.url, commandOptions.resolveCommandModel, commandOptions.beforeCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const dataSourceOptions: IDataSourceOptions<TQuery, TModel> = builder.createOptions();
|
||||
|
||||
const _read = async (query?: TQuery) => {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
data.value = null;
|
||||
|
||||
try {
|
||||
const finalQuery = query || criteria.value;
|
||||
const result = await dataSourceOptions.transport.query.adapter.handle(finalQuery);
|
||||
data.value = result.items && result.items.length > 0 ? result.items[0] : null;
|
||||
} catch (e: any) {
|
||||
error.value = e as IDataSourceError;
|
||||
console.error("Single data source query failed:", e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const read = async (overrideQuery?: TQuery) => {
|
||||
if (overrideQuery) {
|
||||
criteria.value = overrideQuery;
|
||||
}
|
||||
await _read(criteria.value);
|
||||
};
|
||||
|
||||
const executeCommand = async (commandName: string, commandData: any): Promise<any> => {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
|
||||
try {
|
||||
const commandAdapter = dataSourceOptions.transport.commands[commandName];
|
||||
if (!commandAdapter) {
|
||||
throw new Error(`Command "${commandName}" is not defined for this data source.`);
|
||||
}
|
||||
|
||||
let finalCommandData = commandData;
|
||||
if (commandAdapter.resolveCommandModel) {
|
||||
let modelToResolveFrom: TModel | null = null;
|
||||
|
||||
modelToResolveFrom = data.value;
|
||||
|
||||
finalCommandData = await commandAdapter.resolveCommandModel({
|
||||
model: modelToResolveFrom || commandData,
|
||||
data: commandData
|
||||
});
|
||||
}
|
||||
|
||||
const result = await commandAdapter.adapter.handle(finalCommandData);
|
||||
if (commandName === 'create' || commandName === 'update') {
|
||||
data.value = result;
|
||||
}
|
||||
if (commandName === 'delete') {
|
||||
data.value = null;
|
||||
}
|
||||
return result;
|
||||
} catch (e: any) {
|
||||
error.value = e as IDataSourceError;
|
||||
console.error(`Single data source command '${commandName}' failed:`, e);
|
||||
throw e;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (options.autoFetch) {
|
||||
watch(criteria, async () => {
|
||||
await _read();
|
||||
}, { immediate: true, deep: true });
|
||||
}
|
||||
|
||||
return {
|
||||
data: readonly(data),
|
||||
loading: readonly(loading),
|
||||
error: readonly(error),
|
||||
|
||||
criteria,
|
||||
|
||||
read,
|
||||
executeCommand,
|
||||
};
|
||||
}
|
101
src/core/base-datasource-builder.ts
Normal file
101
src/core/base-datasource-builder.ts
Normal file
@ -0,0 +1,101 @@
|
||||
// src/core/base-datasource-builder.ts
|
||||
|
||||
import { httpClient } from './http-client';
|
||||
import {
|
||||
type IQueryCriteria,
|
||||
type IDataSourceCommandAdapterOptions,
|
||||
type IResolveCommandModelEvent,
|
||||
type IDataSourceOptions,
|
||||
type IDataSourceTransportOptions,
|
||||
type IDataSourceError
|
||||
} from './types';
|
||||
|
||||
export abstract class BaseDataSourceBuilder<TQuery extends IQueryCriteria, TModel extends {}> {
|
||||
protected _commands: { [key: string]: IDataSourceCommandAdapterOptions<any>; } = {};
|
||||
protected _keyResolver?: (model: TModel) => TModel[keyof TModel];
|
||||
protected _defaultCriteria!: IQueryCriteria;
|
||||
|
||||
protected constructor() { }
|
||||
|
||||
protected createTransport(): IDataSourceTransportOptions<TQuery, TModel> {
|
||||
return {
|
||||
query: {} as any,
|
||||
commands: this._commands
|
||||
};
|
||||
}
|
||||
|
||||
public keyResolver(resolver: (model: TModel) => TModel[keyof TModel]) {
|
||||
this._keyResolver = resolver;
|
||||
return this;
|
||||
}
|
||||
|
||||
public createOptions(): IDataSourceOptions<TQuery, TModel> { // <--- CHANGED FROM 'protected' to 'public'
|
||||
return {
|
||||
resolveIdField: this._keyResolver,
|
||||
defaultCriteria: this._defaultCriteria,
|
||||
transport: this.createTransport()
|
||||
};
|
||||
}
|
||||
|
||||
protected _handleErrorPipe(error: any): IDataSourceError {
|
||||
if (error && (error.type === 'message' || error.type === 'validation')) {
|
||||
return error as IDataSourceError;
|
||||
}
|
||||
return {
|
||||
type: 'message',
|
||||
message: 'UNEXPECTED_ERROR_MESSAGE',
|
||||
originalError: error,
|
||||
statusCode: 0
|
||||
};
|
||||
}
|
||||
|
||||
public addCommandByCallback<TCommand, TCommandResult>(
|
||||
name: string,
|
||||
commandHandler: (command: TCommand) => Promise<TCommandResult>,
|
||||
resolveCommandModel?: (event: IResolveCommandModelEvent<TModel>) => Promise<TCommand & any>
|
||||
) {
|
||||
const handleWrapper = async (command: TCommand) => {
|
||||
try {
|
||||
return await commandHandler(command);
|
||||
} catch (e) {
|
||||
throw this._handleErrorPipe(e);
|
||||
}
|
||||
};
|
||||
|
||||
this._commands[name] = {
|
||||
adapter: {
|
||||
handle: handleWrapper
|
||||
},
|
||||
resolveCommandModel: resolveCommandModel
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public addCommandByUrl<TCommand, TCommandResult>(
|
||||
name: string,
|
||||
url: string,
|
||||
resolveCommandModel?: (event: IResolveCommandModelEvent<TModel>) => Promise<TCommand & any>,
|
||||
beforeCommand?: (command: TCommand) => Promise<TCommand>
|
||||
) {
|
||||
const handleWrapper = async (command: TCommand) => {
|
||||
const finalBeforeCommand = beforeCommand || (_ => Promise.resolve(command));
|
||||
const processedCommand = await finalBeforeCommand(command);
|
||||
|
||||
try {
|
||||
return await httpClient.post<TCommandResult>(url, processedCommand);
|
||||
} catch (e) {
|
||||
throw this._handleErrorPipe(e);
|
||||
}
|
||||
};
|
||||
|
||||
this._commands[name] = {
|
||||
adapter: {
|
||||
handle: handleWrapper
|
||||
},
|
||||
resolveCommandModel: resolveCommandModel
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
97
src/core/http-client.ts
Normal file
97
src/core/http-client.ts
Normal file
@ -0,0 +1,97 @@
|
||||
export interface HttpError {
|
||||
type: 'message' | 'validation';
|
||||
message?: string;
|
||||
errors?: { [key: string]: string[] };
|
||||
statusCode?: number;
|
||||
originalError?: any;
|
||||
}
|
||||
|
||||
export const httpClient = {
|
||||
async post<TResponse = any>(url: string, data: any): Promise<TResponse> {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
let errorData: any = null;
|
||||
try {
|
||||
errorData = await response.json();
|
||||
} catch (parseError) {
|
||||
errorData = await response.text();
|
||||
}
|
||||
|
||||
throw this._handleHttpError(response.status, errorData);
|
||||
}
|
||||
|
||||
if (response.status === 204 || response.headers.get('content-length') === '0') {
|
||||
return undefined as TResponse;
|
||||
}
|
||||
|
||||
return await response.json() as TResponse;
|
||||
|
||||
} catch (error: any) {
|
||||
if (error && typeof error.type === 'string' && (error.type === 'message' || error.type === 'validation')) {
|
||||
throw error;
|
||||
} else {
|
||||
throw {
|
||||
type: 'message',
|
||||
message: 'NETWORK_ERROR_MESSAGE',
|
||||
originalError: error,
|
||||
statusCode: 0
|
||||
} as HttpError;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_handleHttpError(status: number, errorBody: any): HttpError {
|
||||
if (status === 500) {
|
||||
return {
|
||||
type: 'message',
|
||||
message: 'UNEXPECTED_ERROR_MESSAGE',
|
||||
statusCode: status,
|
||||
originalError: errorBody
|
||||
};
|
||||
}
|
||||
|
||||
if (status === 400) {
|
||||
if (errorBody && errorBody.errors) {
|
||||
return {
|
||||
type: 'validation',
|
||||
errors: errorBody.errors,
|
||||
statusCode: status,
|
||||
originalError: errorBody
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof errorBody === 'object' && (errorBody.Message || errorBody.message)) {
|
||||
return {
|
||||
type: 'message',
|
||||
message: errorBody.Message || errorBody.message,
|
||||
statusCode: status,
|
||||
originalError: errorBody
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof errorBody === 'string') {
|
||||
return {
|
||||
type: 'message',
|
||||
message: errorBody,
|
||||
statusCode: status,
|
||||
originalError: errorBody
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'message',
|
||||
message: 'UNEXPECTED_ERROR_MESSAGE',
|
||||
statusCode: status,
|
||||
originalError: errorBody
|
||||
};
|
||||
}
|
||||
};
|
60
src/core/http-data-source-builder.ts
Normal file
60
src/core/http-data-source-builder.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { httpClient } from './http-client';
|
||||
import {
|
||||
type IQueryCriteria,
|
||||
type IQueryExecutionGroupResult,
|
||||
type IQueryExecutionResult,
|
||||
type IDataSourceQueryAdapterOptions,
|
||||
} from './types';
|
||||
import { BaseDataSourceBuilder } from './base-datasource-builder';
|
||||
|
||||
export class HttpDataSourceBuilder<TQuery extends IQueryCriteria, TModel extends {}> extends BaseDataSourceBuilder<TQuery, TModel>
|
||||
{
|
||||
private _beforeRead?: (query: IQueryCriteria) => Promise<TQuery>;
|
||||
protected _query!: IDataSourceQueryAdapterOptions<TQuery, TModel>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected createTransport() {
|
||||
const baseTransport = super.createTransport();
|
||||
baseTransport.query = this._query;
|
||||
return baseTransport;
|
||||
}
|
||||
|
||||
public beforeRead(beforeRead: (query: IQueryCriteria) => Promise<TQuery>) {
|
||||
this._beforeRead = beforeRead;
|
||||
return this;
|
||||
}
|
||||
|
||||
public queryUrl(url: string) {
|
||||
this._query = {
|
||||
adapter: {
|
||||
handle: async (query: IQueryCriteria) => {
|
||||
const finalBeforeRead = this._beforeRead || (() => Promise.resolve(query as TQuery));
|
||||
const finalQuery = await finalBeforeRead(query);
|
||||
return httpClient.post<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>(url, finalQuery);
|
||||
}
|
||||
}
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
public queryHandler(queryHandler: (query: TQuery) => Promise<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>) {
|
||||
this._query = {
|
||||
adapter: {
|
||||
handle: async (query: TQuery) => {
|
||||
const finalBeforeRead = this._beforeRead || (() => Promise.resolve(query as TQuery));
|
||||
const finalQuery = await finalBeforeRead(query);
|
||||
return queryHandler(finalQuery);
|
||||
}
|
||||
}
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
public defaultCriteria(criteria: IQueryCriteria) {
|
||||
this._defaultCriteria = criteria;
|
||||
return this;
|
||||
}
|
||||
}
|
8
src/core/list-data-source-builder.ts
Normal file
8
src/core/list-data-source-builder.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { HttpDataSourceBuilder } from './http-data-source-builder.ts';
|
||||
import { type IQueryCriteria, type ICommand } from './types';
|
||||
|
||||
export class ListDataSourceBuilder<TQuery extends IQueryCriteria, TModel extends ICommand> extends HttpDataSourceBuilder<TQuery, TModel> {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
35
src/core/single-data-source-builder.ts
Normal file
35
src/core/single-data-source-builder.ts
Normal file
@ -0,0 +1,35 @@
|
||||
// src/core/single-datasource-builder.ts (REVISED - RxJS compatible and delete data fix)
|
||||
|
||||
import { HttpDataSourceBuilder } from './http-data-source-builder.ts';
|
||||
import { type IQueryCriteria, type ICommand } from './types';
|
||||
import { httpClient } from './http-client';
|
||||
|
||||
export class SingleDataSourceBuilder<TQuery extends IQueryCriteria, TModel extends ICommand> extends HttpDataSourceBuilder<TQuery, TModel>
|
||||
{
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public addStandardRestCommands(route: string) {
|
||||
if (!this._keyResolver) {
|
||||
console.warn("A key resolver is recommended for standard commands to help identify models.");
|
||||
}
|
||||
|
||||
this.addCommandByCallback(
|
||||
'create',
|
||||
(command: TModel) => httpClient.post<TModel>(route, command)
|
||||
);
|
||||
|
||||
this.addCommandByCallback(
|
||||
'update',
|
||||
(command: TModel) => httpClient.post<TModel>(route, command)
|
||||
);
|
||||
|
||||
this.addCommandByCallback(
|
||||
'delete',
|
||||
(command: TModel) => httpClient.post<TModel>(route, command)
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
63
src/core/types.ts
Normal file
63
src/core/types.ts
Normal file
@ -0,0 +1,63 @@
|
||||
export interface IQueryCriteria {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface ICommand {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface IQueryExecutionResult<TModel> {
|
||||
items: TModel[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface IQueryExecutionGroupResult { }
|
||||
|
||||
export interface IDataSourceErrorMessage {
|
||||
type: 'message';
|
||||
message: string;
|
||||
statusCode?: number;
|
||||
originalError?: any;
|
||||
}
|
||||
|
||||
export interface IDataSourceValidationError {
|
||||
type: 'validation';
|
||||
errors: { [key: string]: string[] };
|
||||
statusCode?: number;
|
||||
originalError?: any;
|
||||
}
|
||||
|
||||
export type IDataSourceError = IDataSourceErrorMessage | IDataSourceValidationError;
|
||||
|
||||
export interface IResolveCommandModelEvent<TModel> {
|
||||
model: TModel;
|
||||
data: any;
|
||||
}
|
||||
|
||||
export interface IDataSourceCommandAdapterOptions<TModel> {
|
||||
adapter: {
|
||||
handle: (command: any) => Promise<any>;
|
||||
};
|
||||
resolveCommandModel?: (event: IResolveCommandModelEvent<TModel>) => Promise<any>;
|
||||
}
|
||||
|
||||
export interface IDataSourceQueryAdapterOptions<TQuery extends IQueryCriteria, TModel> {
|
||||
adapter: {
|
||||
handle: (query: TQuery) => Promise<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IDataSourceTransportOptions<TQuery extends IQueryCriteria, TModel> {
|
||||
query: IDataSourceQueryAdapterOptions<TQuery, TModel>;
|
||||
commands: { [key: string]: IDataSourceCommandAdapterOptions<TModel> };
|
||||
}
|
||||
|
||||
export interface IDataSourceOptions<TQuery extends IQueryCriteria, TModel> {
|
||||
resolveIdField?: (model: TModel) => TModel[keyof TModel];
|
||||
defaultCriteria?: IQueryCriteria;
|
||||
transport: IDataSourceTransportOptions<TQuery, TModel>;
|
||||
}
|
||||
|
||||
export interface IDataSource<TQuery extends IQueryCriteria, TModel> {
|
||||
read(query?: TQuery): Promise<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult>;
|
||||
}
|
0
src/index.ts
Normal file
0
src/index.ts
Normal file
79
src/style.css
Normal file
79
src/style.css
Normal file
@ -0,0 +1,79 @@
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
32
tsconfig.json
Normal file
32
tsconfig.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"lib": ["esnext", "dom"],
|
||||
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
|
||||
"declaration": true,
|
||||
"declarationDir": "./dist",
|
||||
"emitDeclarationOnly": false,
|
||||
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true, // Good practice
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true,
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "vite.config.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
33
vite.config.ts
Normal file
33
vite.config.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import { resolve } from 'path';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
},
|
||||
build: {
|
||||
lib: {
|
||||
entry: resolve(__dirname, 'src/index.ts'),
|
||||
name: 'VueOpenHarborData',
|
||||
fileName: (format) => `vue-openharbor-data.${format}.js`,
|
||||
},
|
||||
rollupOptions: {
|
||||
|
||||
external: ['vue', '@openharbor/data'],
|
||||
output: {
|
||||
globals: {
|
||||
vue: 'Vue',
|
||||
'@openharbor/data': 'OpenHarborData',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
629
yarn.lock
Normal file
629
yarn.lock
Normal file
@ -0,0 +1,629 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/helper-string-parser@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
|
||||
integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
|
||||
integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
|
||||
|
||||
"@babel/parser@^7.27.5":
|
||||
version "7.27.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.5.tgz#ed22f871f110aa285a6fd934a0efed621d118826"
|
||||
integrity sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.27.3"
|
||||
|
||||
"@babel/types@^7.27.3":
|
||||
version "7.27.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.6.tgz#a434ca7add514d4e646c80f7375c0aa2befc5535"
|
||||
integrity sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.27.1"
|
||||
"@babel/helper-validator-identifier" "^7.27.1"
|
||||
|
||||
"@esbuild/aix-ppc64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18"
|
||||
integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==
|
||||
|
||||
"@esbuild/android-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f"
|
||||
integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==
|
||||
|
||||
"@esbuild/android-arm@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26"
|
||||
integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==
|
||||
|
||||
"@esbuild/android-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff"
|
||||
integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==
|
||||
|
||||
"@esbuild/darwin-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz#49d8bf8b1df95f759ac81eb1d0736018006d7e34"
|
||||
integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==
|
||||
|
||||
"@esbuild/darwin-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418"
|
||||
integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c"
|
||||
integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==
|
||||
|
||||
"@esbuild/freebsd-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f"
|
||||
integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==
|
||||
|
||||
"@esbuild/linux-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8"
|
||||
integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==
|
||||
|
||||
"@esbuild/linux-arm@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911"
|
||||
integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==
|
||||
|
||||
"@esbuild/linux-ia32@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783"
|
||||
integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==
|
||||
|
||||
"@esbuild/linux-loong64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506"
|
||||
integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==
|
||||
|
||||
"@esbuild/linux-mips64el@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96"
|
||||
integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==
|
||||
|
||||
"@esbuild/linux-ppc64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9"
|
||||
integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==
|
||||
|
||||
"@esbuild/linux-riscv64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e"
|
||||
integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==
|
||||
|
||||
"@esbuild/linux-s390x@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d"
|
||||
integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==
|
||||
|
||||
"@esbuild/linux-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4"
|
||||
integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==
|
||||
|
||||
"@esbuild/netbsd-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d"
|
||||
integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==
|
||||
|
||||
"@esbuild/netbsd-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79"
|
||||
integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==
|
||||
|
||||
"@esbuild/openbsd-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd"
|
||||
integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==
|
||||
|
||||
"@esbuild/openbsd-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0"
|
||||
integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==
|
||||
|
||||
"@esbuild/sunos-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5"
|
||||
integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==
|
||||
|
||||
"@esbuild/win32-arm64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e"
|
||||
integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==
|
||||
|
||||
"@esbuild/win32-ia32@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d"
|
||||
integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==
|
||||
|
||||
"@esbuild/win32-x64@0.25.5":
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1"
|
||||
integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==
|
||||
|
||||
"@jridgewell/sourcemap-codec@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz#a3e4e4b2baf0bade6918cf5135c3ef7eee653196"
|
||||
integrity sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==
|
||||
|
||||
"@rollup/rollup-android-arm64@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz#63566b0e76c62d4f96d44448f38a290562280200"
|
||||
integrity sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==
|
||||
|
||||
"@rollup/rollup-darwin-arm64@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz#60a51a61b22b1f4fdf97b4adf5f0f447f492759d"
|
||||
integrity sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==
|
||||
|
||||
"@rollup/rollup-darwin-x64@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz#bfe3059440f7032de11e749ece868cd7f232e609"
|
||||
integrity sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==
|
||||
|
||||
"@rollup/rollup-freebsd-arm64@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz#d5d4c6cd3b8acb7493b76227d8b2b4a2d732a37b"
|
||||
integrity sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==
|
||||
|
||||
"@rollup/rollup-freebsd-x64@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz#cb4e1547b572cd0144c5fbd6c4a0edfed5fe6024"
|
||||
integrity sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz#feb81bd086f6a469777f75bec07e1bdf93352e69"
|
||||
integrity sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz#68bff1c6620c155c9d8f5ee6a83c46eb50486f18"
|
||||
integrity sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz#dbc5036a85e3ca3349887c8bdbebcfd011e460b0"
|
||||
integrity sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz#72efc633aa0b93531bdfc69d70bcafa88e6152fc"
|
||||
integrity sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==
|
||||
|
||||
"@rollup/rollup-linux-loongarch64-gnu@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz#9b6a49afde86c8f57ca11efdf8fd8d7c52048817"
|
||||
integrity sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz#93cb96073efab0cdbf419c8dfc44b5e2bd815139"
|
||||
integrity sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz#028708f73c8130ae924e5c3755de50fe93687249"
|
||||
integrity sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==
|
||||
|
||||
"@rollup/rollup-linux-riscv64-musl@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz#878bfb158b2cf6671b7611fd58e5c80d9144ac6c"
|
||||
integrity sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz#59b4ebb2129d34b7807ed8c462ff0baaefca9ad4"
|
||||
integrity sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz#597d40f60d4b15bedbbacf2491a69c5b67a58e93"
|
||||
integrity sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==
|
||||
|
||||
"@rollup/rollup-linux-x64-musl@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz#0a062d6fee35ec4fbb607b2a9d933a9372ccf63a"
|
||||
integrity sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz#41ffab489857987c75385b0fc8cccf97f7e69d0a"
|
||||
integrity sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz#d9fb61d98eedfa52720b6ed9f31442b3ef4b839f"
|
||||
integrity sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc@4.44.0":
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz#a36e79b6ccece1533f777a1bca1f89c13f0c5f62"
|
||||
integrity sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==
|
||||
|
||||
"@tsconfig/node20@^20.1.6":
|
||||
version "20.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node20/-/node20-20.1.6.tgz#cdf11db8322e1c245d5a4bb2e398239c82ae78b2"
|
||||
integrity sha512-sz+Hqx9zwZDpZIV871WSbUzSqNIsXzghZydypnfgzPKLltVJfkINfUeTct31n/tTSa9ZE1ZOfKdRre1uHHquYQ==
|
||||
|
||||
"@types/estree@1.0.8":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
|
||||
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
|
||||
|
||||
"@types/node@^24.0.3":
|
||||
version "24.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.0.3.tgz#f935910f3eece3a3a2f8be86b96ba833dc286cab"
|
||||
integrity sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==
|
||||
dependencies:
|
||||
undici-types "~7.8.0"
|
||||
|
||||
"@vitejs/plugin-vue@^5.2.3":
|
||||
version "5.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz#9e8a512eb174bfc2a333ba959bbf9de428d89ad8"
|
||||
integrity sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==
|
||||
|
||||
"@volar/language-core@2.4.14", "@volar/language-core@~2.4.11":
|
||||
version "2.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.14.tgz#dac7573014d4f3bafb186cb16888ffea5698be71"
|
||||
integrity sha512-X6beusV0DvuVseaOEy7GoagS4rYHgDHnTrdOj5jeUb49fW5ceQyP9Ej5rBhqgz2wJggl+2fDbbojq1XKaxDi6w==
|
||||
dependencies:
|
||||
"@volar/source-map" "2.4.14"
|
||||
|
||||
"@volar/source-map@2.4.14":
|
||||
version "2.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.14.tgz#cdcecd533c2e767449b2414cc22327d2bda7ef95"
|
||||
integrity sha512-5TeKKMh7Sfxo8021cJfmBzcjfY1SsXsPMMjMvjY7ivesdnybqqS+GxGAoXHAOUawQTwtdUxgP65Im+dEmvWtYQ==
|
||||
|
||||
"@volar/typescript@~2.4.11":
|
||||
version "2.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.14.tgz#b99a1025dd6a8b751e96627ebcb0739ceed0e5f1"
|
||||
integrity sha512-p8Z6f/bZM3/HyCdRNFZOEEzts51uV8WHeN8Tnfnm2EBv6FDB2TQLzfVx7aJvnl8ofKAOnS64B2O8bImBFaauRw==
|
||||
dependencies:
|
||||
"@volar/language-core" "2.4.14"
|
||||
path-browserify "^1.0.1"
|
||||
vscode-uri "^3.0.8"
|
||||
|
||||
"@vue/compiler-core@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.17.tgz#23d291bd01b863da3ef2e26e7db84d8e01a9b4c5"
|
||||
integrity sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.27.5"
|
||||
"@vue/shared" "3.5.17"
|
||||
entities "^4.5.0"
|
||||
estree-walker "^2.0.2"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
"@vue/compiler-dom@3.5.17", "@vue/compiler-dom@^3.5.0":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz#7bc19a20e23b670243a64b47ce3a890239b870be"
|
||||
integrity sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==
|
||||
dependencies:
|
||||
"@vue/compiler-core" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
||||
|
||||
"@vue/compiler-sfc@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.17.tgz#c518871276e26593612bdab36f3f5bcd053b13bf"
|
||||
integrity sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.27.5"
|
||||
"@vue/compiler-core" "3.5.17"
|
||||
"@vue/compiler-dom" "3.5.17"
|
||||
"@vue/compiler-ssr" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
||||
estree-walker "^2.0.2"
|
||||
magic-string "^0.30.17"
|
||||
postcss "^8.5.6"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
"@vue/compiler-ssr@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz#14ba3b7bba6e0e1fd02002316263165a5d1046c7"
|
||||
integrity sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
||||
|
||||
"@vue/compiler-vue2@^2.7.16":
|
||||
version "2.7.16"
|
||||
resolved "https://registry.yarnpkg.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz#2ba837cbd3f1b33c2bc865fbe1a3b53fb611e249"
|
||||
integrity sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.2.0"
|
||||
|
||||
"@vue/language-core@2.2.10":
|
||||
version "2.2.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.2.10.tgz#5ae1e71a4e16dd59d1e4bac167f4b9c8c04d9f17"
|
||||
integrity sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==
|
||||
dependencies:
|
||||
"@volar/language-core" "~2.4.11"
|
||||
"@vue/compiler-dom" "^3.5.0"
|
||||
"@vue/compiler-vue2" "^2.7.16"
|
||||
"@vue/shared" "^3.5.0"
|
||||
alien-signals "^1.0.3"
|
||||
minimatch "^9.0.3"
|
||||
muggle-string "^0.4.1"
|
||||
path-browserify "^1.0.1"
|
||||
|
||||
"@vue/reactivity@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.17.tgz#169b5dcf96c7f23788e5ed9745ec8a7227f2125e"
|
||||
integrity sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==
|
||||
dependencies:
|
||||
"@vue/shared" "3.5.17"
|
||||
|
||||
"@vue/runtime-core@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.17.tgz#b17bd41e13011e85e9b1025545292d43f5512730"
|
||||
integrity sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
||||
|
||||
"@vue/runtime-dom@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.17.tgz#8e325e29cd03097fe179032fc8df384a426fc83a"
|
||||
integrity sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.5.17"
|
||||
"@vue/runtime-core" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
||||
csstype "^3.1.3"
|
||||
|
||||
"@vue/server-renderer@3.5.17":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.17.tgz#9b8fd6a40a3d55322509fafe78ac841ede649fbe"
|
||||
integrity sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==
|
||||
dependencies:
|
||||
"@vue/compiler-ssr" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
||||
|
||||
"@vue/shared@3.5.17", "@vue/shared@^3.5.0":
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.17.tgz#e8b3a41f0be76499882a89e8ed40d86a70fa4b70"
|
||||
integrity sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==
|
||||
|
||||
"@vue/tsconfig@^0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/tsconfig/-/tsconfig-0.7.0.tgz#67044c847b7a137b8cbfd6b23104c36dbaf80d1d"
|
||||
integrity sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==
|
||||
|
||||
alien-signals@^1.0.3:
|
||||
version "1.0.13"
|
||||
resolved "https://registry.yarnpkg.com/alien-signals/-/alien-signals-1.0.13.tgz#8d6db73462f742ee6b89671fbd8c37d0b1727a7e"
|
||||
integrity sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
|
||||
integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
csstype@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
|
||||
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
|
||||
|
||||
entities@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
esbuild@^0.25.0:
|
||||
version "0.25.5"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.5.tgz#71075054993fdfae76c66586f9b9c1f8d7edd430"
|
||||
integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==
|
||||
optionalDependencies:
|
||||
"@esbuild/aix-ppc64" "0.25.5"
|
||||
"@esbuild/android-arm" "0.25.5"
|
||||
"@esbuild/android-arm64" "0.25.5"
|
||||
"@esbuild/android-x64" "0.25.5"
|
||||
"@esbuild/darwin-arm64" "0.25.5"
|
||||
"@esbuild/darwin-x64" "0.25.5"
|
||||
"@esbuild/freebsd-arm64" "0.25.5"
|
||||
"@esbuild/freebsd-x64" "0.25.5"
|
||||
"@esbuild/linux-arm" "0.25.5"
|
||||
"@esbuild/linux-arm64" "0.25.5"
|
||||
"@esbuild/linux-ia32" "0.25.5"
|
||||
"@esbuild/linux-loong64" "0.25.5"
|
||||
"@esbuild/linux-mips64el" "0.25.5"
|
||||
"@esbuild/linux-ppc64" "0.25.5"
|
||||
"@esbuild/linux-riscv64" "0.25.5"
|
||||
"@esbuild/linux-s390x" "0.25.5"
|
||||
"@esbuild/linux-x64" "0.25.5"
|
||||
"@esbuild/netbsd-arm64" "0.25.5"
|
||||
"@esbuild/netbsd-x64" "0.25.5"
|
||||
"@esbuild/openbsd-arm64" "0.25.5"
|
||||
"@esbuild/openbsd-x64" "0.25.5"
|
||||
"@esbuild/sunos-x64" "0.25.5"
|
||||
"@esbuild/win32-arm64" "0.25.5"
|
||||
"@esbuild/win32-ia32" "0.25.5"
|
||||
"@esbuild/win32-x64" "0.25.5"
|
||||
|
||||
estree-walker@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
|
||||
fdir@^6.4.4:
|
||||
version "6.4.6"
|
||||
resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.6.tgz#2b268c0232697063111bbf3f64810a2a741ba281"
|
||||
integrity sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==
|
||||
|
||||
fsevents@~2.3.2, fsevents@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
he@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
magic-string@^0.30.17:
|
||||
version "0.30.17"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
|
||||
integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
minimatch@^9.0.3:
|
||||
version "9.0.5"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
|
||||
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
muggle-string@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328"
|
||||
integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==
|
||||
|
||||
nanoid@^3.3.11:
|
||||
version "3.3.11"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
||||
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
||||
|
||||
path-browserify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
|
||||
|
||||
picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
picomatch@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
|
||||
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
|
||||
|
||||
postcss@^8.5.3, postcss@^8.5.6:
|
||||
version "8.5.6"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
|
||||
integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
|
||||
dependencies:
|
||||
nanoid "^3.3.11"
|
||||
picocolors "^1.1.1"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
rollup@^4.34.9:
|
||||
version "4.44.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.44.0.tgz#0e10b98339b306edad1e612f1e5590a79aef521c"
|
||||
integrity sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==
|
||||
dependencies:
|
||||
"@types/estree" "1.0.8"
|
||||
optionalDependencies:
|
||||
"@rollup/rollup-android-arm-eabi" "4.44.0"
|
||||
"@rollup/rollup-android-arm64" "4.44.0"
|
||||
"@rollup/rollup-darwin-arm64" "4.44.0"
|
||||
"@rollup/rollup-darwin-x64" "4.44.0"
|
||||
"@rollup/rollup-freebsd-arm64" "4.44.0"
|
||||
"@rollup/rollup-freebsd-x64" "4.44.0"
|
||||
"@rollup/rollup-linux-arm-gnueabihf" "4.44.0"
|
||||
"@rollup/rollup-linux-arm-musleabihf" "4.44.0"
|
||||
"@rollup/rollup-linux-arm64-gnu" "4.44.0"
|
||||
"@rollup/rollup-linux-arm64-musl" "4.44.0"
|
||||
"@rollup/rollup-linux-loongarch64-gnu" "4.44.0"
|
||||
"@rollup/rollup-linux-powerpc64le-gnu" "4.44.0"
|
||||
"@rollup/rollup-linux-riscv64-gnu" "4.44.0"
|
||||
"@rollup/rollup-linux-riscv64-musl" "4.44.0"
|
||||
"@rollup/rollup-linux-s390x-gnu" "4.44.0"
|
||||
"@rollup/rollup-linux-x64-gnu" "4.44.0"
|
||||
"@rollup/rollup-linux-x64-musl" "4.44.0"
|
||||
"@rollup/rollup-win32-arm64-msvc" "4.44.0"
|
||||
"@rollup/rollup-win32-ia32-msvc" "4.44.0"
|
||||
"@rollup/rollup-win32-x64-msvc" "4.44.0"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
source-map-js@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
||||
tinyglobby@^0.2.13:
|
||||
version "0.2.14"
|
||||
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d"
|
||||
integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==
|
||||
dependencies:
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
|
||||
typescript@~5.8.3:
|
||||
version "5.8.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
|
||||
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
|
||||
|
||||
undici-types@~7.8.0:
|
||||
version "7.8.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294"
|
||||
integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==
|
||||
|
||||
vite@^6.3.5:
|
||||
version "6.3.5"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-6.3.5.tgz#fec73879013c9c0128c8d284504c6d19410d12a3"
|
||||
integrity sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==
|
||||
dependencies:
|
||||
esbuild "^0.25.0"
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
postcss "^8.5.3"
|
||||
rollup "^4.34.9"
|
||||
tinyglobby "^0.2.13"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
vscode-uri@^3.0.8:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c"
|
||||
integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==
|
||||
|
||||
vue-tsc@^2.2.8:
|
||||
version "2.2.10"
|
||||
resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-2.2.10.tgz#7b51a666cb90788884efd0caedc69fc1fc9c5b78"
|
||||
integrity sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==
|
||||
dependencies:
|
||||
"@volar/typescript" "~2.4.11"
|
||||
"@vue/language-core" "2.2.10"
|
||||
|
||||
vue@^3.5.13:
|
||||
version "3.5.17"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.17.tgz#ea8a6a45abb2b0620e7d479319ce8434b55650cf"
|
||||
integrity sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.5.17"
|
||||
"@vue/compiler-sfc" "3.5.17"
|
||||
"@vue/runtime-dom" "3.5.17"
|
||||
"@vue/server-renderer" "3.5.17"
|
||||
"@vue/shared" "3.5.17"
|
Loading…
Reference in New Issue
Block a user