generated from polymech/site-template
Synced from site
This commit is contained in:
parent
3e13363c6c
commit
6541d83fba
446
.astro/collections/projects.schema.json
Normal file
446
.astro/collections/projects.schema.json
Normal file
@ -0,0 +1,446 @@
|
||||
{
|
||||
"$ref": "#/definitions/projects",
|
||||
"definitions": {
|
||||
"projects": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cart_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "number"
|
||||
},
|
||||
"cscartCats": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"cscartId": {
|
||||
"type": "number"
|
||||
},
|
||||
"vendorId": {
|
||||
"type": "number"
|
||||
},
|
||||
"shipping": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"price": {
|
||||
"type": "number"
|
||||
},
|
||||
"transit": {
|
||||
"type": "number"
|
||||
},
|
||||
"handling": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"default": {
|
||||
"price": 0,
|
||||
"transit": 12,
|
||||
"handling": 2
|
||||
}
|
||||
},
|
||||
"manufacturing": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"lead_time": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"replaced_by": {
|
||||
"type": "string"
|
||||
},
|
||||
"alternatives": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"url",
|
||||
"type"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"used_by": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/alternatives/items"
|
||||
}
|
||||
},
|
||||
"image": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"thumb": {
|
||||
"type": "string"
|
||||
},
|
||||
"responsive": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {},
|
||||
"keywords": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"alt": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"height": {
|
||||
"type": "number"
|
||||
},
|
||||
"width": {
|
||||
"type": "number"
|
||||
},
|
||||
"order": {
|
||||
"type": "number"
|
||||
},
|
||||
"exif": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {},
|
||||
"jfif": {},
|
||||
"exif": {},
|
||||
"gps": {}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"flags": {
|
||||
"type": "number"
|
||||
},
|
||||
"edrawings": {
|
||||
"type": "string"
|
||||
},
|
||||
"cad": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"configuration": {
|
||||
"type": "string"
|
||||
},
|
||||
"step": {
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"html": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file",
|
||||
"name",
|
||||
"configuration"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"showDimensions": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"showParts": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"slug": {
|
||||
"type": "string"
|
||||
},
|
||||
"keywords": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta_keywords": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"versions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"up": {
|
||||
"type": "string"
|
||||
},
|
||||
"down": {
|
||||
"type": "string"
|
||||
},
|
||||
"family": {
|
||||
"type": "string"
|
||||
},
|
||||
"sheet": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"authors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"url"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"gallery": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/image"
|
||||
}
|
||||
},
|
||||
"renderings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/image"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/image"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/image"
|
||||
}
|
||||
},
|
||||
"showcase": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/image"
|
||||
}
|
||||
},
|
||||
"samples": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/image"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"default": {
|
||||
"gallery": [],
|
||||
"renderings": [],
|
||||
"components": [],
|
||||
"configurations": [],
|
||||
"showcase": [],
|
||||
"samples": []
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"type": "string"
|
||||
},
|
||||
"tests": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/alternatives/items"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"download": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"gallery": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"glob": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"glob"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"default": {
|
||||
"renderings": {
|
||||
"glob": [
|
||||
"*.+(JPG|jpg|png|PNG|gif)"
|
||||
]
|
||||
},
|
||||
"gallery": {
|
||||
"glob": [
|
||||
"*.+(JPG|jpg|png|PNG|gif)"
|
||||
]
|
||||
},
|
||||
"components": {
|
||||
"glob": [
|
||||
"*.+(JPG|jpg|png|PNG|gif)"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"glob": [
|
||||
"*.+(JPG|jpg|png|PNG|gif)"
|
||||
]
|
||||
},
|
||||
"showcase": {
|
||||
"glob": [
|
||||
"*.+(JPG|jpg|png|PNG|gif)"
|
||||
]
|
||||
},
|
||||
"samples": {
|
||||
"glob": [
|
||||
"*.+(JPG|jpg|png|PNG|gif)"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Preview3d": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"howto_categories": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"steps": {},
|
||||
"sourceLanguage": {
|
||||
"type": "string"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"product_dimensions": {
|
||||
"type": "string"
|
||||
},
|
||||
"production": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fusion-folder": {
|
||||
"type": "string"
|
||||
},
|
||||
"nc-folder": {
|
||||
"type": "string"
|
||||
},
|
||||
"cam": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/projects/properties/authors/items"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fusion-folder",
|
||||
"nc-folder",
|
||||
"cam"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"score": {
|
||||
"type": "number"
|
||||
},
|
||||
"body": {
|
||||
"type": "string"
|
||||
},
|
||||
"features": {
|
||||
"type": "string"
|
||||
},
|
||||
"highlights": {
|
||||
"type": "string"
|
||||
},
|
||||
"specs": {
|
||||
"type": "string"
|
||||
},
|
||||
"license": {
|
||||
"type": "string"
|
||||
},
|
||||
"readme": {
|
||||
"type": "string"
|
||||
},
|
||||
"shared": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code",
|
||||
"manufacturing",
|
||||
"name",
|
||||
"slug",
|
||||
"category"
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
@ -296,11 +296,7 @@
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/store/properties/alternatives/items"
|
||||
},
|
||||
"default": []
|
||||
"type": "string"
|
||||
},
|
||||
"tests": {
|
||||
"type": "array",
|
||||
@ -413,6 +409,27 @@
|
||||
},
|
||||
"score": {
|
||||
"type": "number"
|
||||
},
|
||||
"body": {
|
||||
"type": "string"
|
||||
},
|
||||
"features": {
|
||||
"type": "string"
|
||||
},
|
||||
"highlights": {
|
||||
"type": "string"
|
||||
},
|
||||
"specs": {
|
||||
"type": "string"
|
||||
},
|
||||
"license": {
|
||||
"type": "string"
|
||||
},
|
||||
"readme": {
|
||||
"type": "string"
|
||||
},
|
||||
"shared": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
{
|
||||
"_variables": {
|
||||
"lastUpdateCheck": 1740681917455
|
||||
"lastUpdateCheck": 1741718719942
|
||||
}
|
||||
}
|
||||
189
README.md
189
README.md
@ -1,111 +1,144 @@
|
||||
# Williamsburg
|
||||
# Astro Site Documentation
|
||||
|
||||
## Template Integrations
|
||||
- Tailwind CSS v4
|
||||
- Astro SEO - Powered by [@astrolib/seo](https://github.com/onwidget/astrolib/tree/main/packages/seo)
|
||||
- Astro Sitemap - https://docs.astro.build/en/guides/integrations-guide/sitemap/
|
||||
This README provides comprehensive documentation for this Astro-based website project.
|
||||
|
||||
## Template Structure
|
||||
## 🚀 Project Overview
|
||||
|
||||
The template follows a typical Astro project structure. You'll find the following key directories and files:
|
||||
This is a multilingual website built with [Astro](https://astro.build), a modern static site generator. The site features a blog, content collections, and internationalization support. It uses Tailwind CSS for styling and includes various components and layouts for consistent design.
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
/
|
||||
├── public/
|
||||
├── public/ # Static assets
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
│ ├── components/ # UI components
|
||||
│ ├── content/ # Content collections
|
||||
│ ├── layouts/ # Page layouts
|
||||
│ ├── pages/ # Page routes
|
||||
│ │ ├── en/ # English pages
|
||||
│ │ └── [lang]/ # Other language pages
|
||||
│ ├── i18n/ # Internationalization files
|
||||
│ └── content.config.ts # Content collection configuration
|
||||
├── astro.config.mjs # Astro configuration
|
||||
├── tailwind.config.cjs # Tailwind CSS configuration
|
||||
└── package.json # Project dependencies
|
||||
```
|
||||
|
||||
- `src/pages/`: Contains `.astro` and `.md` files. Each file becomes a route in your project based on its name.
|
||||
- `src/components/`: Ideal for placing your Astro/React/Vue/Svelte/Preact components.
|
||||
- `public/`: For static assets such as images that you want to serve directly.
|
||||
## 📚 Content Collections
|
||||
|
||||
## Commands
|
||||
The site utilizes Astro's content collections to manage structured content. Collections are defined in `src/content.config.ts` and include:
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
- **Blog Posts**: Articles with frontmatter for metadata like title, date, author, etc.
|
||||
- **Authors**: Information about content authors.
|
||||
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro --help` | Get help using the Astro CLI |
|
||||
Collections are stored in the `src/content/` directory, organized by language:
|
||||
- `src/content/blog/en/` - English blog posts
|
||||
- `src/content/blog/[lang]/` - Blog posts in other languages
|
||||
|
||||
Learn more - Explore more through Astro's official [documentation](https://docs.astro.build).
|
||||
## 🧩 Components
|
||||
|
||||
------
|
||||
Updated on 30th December 2024
|
||||
The site includes reusable UI components located in `src/components/`:
|
||||
|
||||
## This update includes:
|
||||
- Add Tailwind CSS v4 Beta
|
||||
On this version, Tailwind CSS is now beta version from Tailwind CSS V4, this means that there's no `tailwind.config.mjs` file anymore. From now on, all style will be added on the `css` file. You can find the styles on the `src/styles/global.css` file.
|
||||
- Astro V5
|
||||
This update includes Astro V5, which is a major update that includes several new features and improvements.
|
||||
- **Core Components**: Basic UI elements like buttons, cards, and navigation
|
||||
- **Blog Components**: Specialized components for the blog section
|
||||
- **SEO Components**: Components for SEO optimization
|
||||
- **UI Components**: Interface elements like headers, footers, and menus
|
||||
|
||||
These components help maintain consistent design across the site while making development more efficient.
|
||||
|
||||
- Astro SEO by @astrolib/seo
|
||||
This update includes the integration of the Astro SEO package by @astrolib/seo, is an integration that makes managing your SEO easier in Astro projects. It is fully based on the excellent Next SEO library
|
||||
## 📏 Layouts
|
||||
|
||||
## On the next update
|
||||
Layouts in `src/layouts/` provide consistent page structures:
|
||||
|
||||
- Add Image component from Astro
|
||||
The Astro Image component is coming back to the themes
|
||||
- **BaseLayout.astro**: The main layout with common elements (header, footer)
|
||||
- **BlogLayout.astro**: Specialized layout for blog posts
|
||||
- **PostLayout.astro**: Layout for individual blog posts
|
||||
- **AboutLayout.astro**: Layout for about pages
|
||||
|
||||
- Reusable components
|
||||
This template now includes reusable components, such as the `Text` component:
|
||||
Layouts wrap content with consistent HTML structure, styling, and components.
|
||||
|
||||
- Text Component
|
||||
A versatile and reusable component for handling text across your project, ensuring consistency and easy customization.
|
||||
## 🌐 Internationalization (i18n)
|
||||
|
||||
- **HTML Tags:** Easily change the HTML element (like `p`, `h1`, `span`, `a`) using the `tag` prop, with `p` being the default.
|
||||
- **Variants:** Pick from preset text styles (such as `displayXL` or `textBase`) for a consistent look.
|
||||
- **Custom Classes:** Add or adjust styles with the `class` prop.
|
||||
- **Accessibility:** Customize with additional props like `id`, `href`, `title`, and `style`.
|
||||
- **Content Slot:** Add any content inside the component, including optional left and right icons.
|
||||
Example usage:
|
||||
```astro
|
||||
<Text tag="h1" variant="displayXL" class="text-center">
|
||||
Welcome to the new version!
|
||||
</Text>
|
||||
The site supports multiple languages through a built-in internationalization system:
|
||||
|
||||
- Default language is English (`en`)
|
||||
- Content is organized by language in directory structures
|
||||
- URL format follows `/[lang]/[route]` pattern
|
||||
- Translation files are stored in the `src/i18n/` directory
|
||||
|
||||
Language switching is available to visitors, with localized content and UI elements.
|
||||
|
||||
## 📦 Dependencies
|
||||
|
||||
The project relies on the following main dependencies:
|
||||
|
||||
- **Astro**: Core framework for building the site
|
||||
- **Tailwind CSS**: Utility-first CSS framework for styling
|
||||
- **@astrojs/tailwind**: Tailwind CSS integration for Astro
|
||||
- **@astrojs/mdx**: MDX integration for enhanced markdown
|
||||
- **@astrojs/sitemap**: Automatic sitemap generation
|
||||
- **@astrojs/image**: Image optimization tools
|
||||
|
||||
Additional dependencies may include utility libraries and development tools.
|
||||
|
||||
## 🛠️ Development Instructions
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js (v16 or later)
|
||||
- npm or yarn
|
||||
|
||||
### Getting Started
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd <project-directory>
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
npm install
|
||||
# or
|
||||
yarn install
|
||||
```
|
||||
|
||||
3. Start the development server:
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
4. Open your browser and visit `http://localhost:3000`
|
||||
|
||||
### Building for Production
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
# or
|
||||
yarn build
|
||||
```
|
||||
|
||||
- Button Component
|
||||
A customizable button component with options to fit your design needs:
|
||||
The build output will be in the `dist/` directory.
|
||||
|
||||
- **Variants:** Choose from predefined styles like `primary` (dark background) and `secondary` (lighter background), with support for dark mode.
|
||||
- **Sizes:** Select `small` or `medium` for different button heights and padding.
|
||||
- **Gaps:** Control the spacing between content with the `gapSize` prop (either `small` or `medium`).
|
||||
- **Custom Classes:** Apply additional styles using the `class` prop.
|
||||
- **Slots:** Include icons or extra content with optional `left-icon` and `right-icon` slots.
|
||||
Example usage:
|
||||
```astro
|
||||
<Button size="small" variant="primary">Primary small</Button>
|
||||
```
|
||||
### Additional Commands
|
||||
|
||||
- Wrapper Component
|
||||
A flexible layout component that helps with consistent spacing and alignment.
|
||||
- **Preview build**: `npm run preview`
|
||||
- **Check code**: `npm run astro check`
|
||||
- **Lint code**: `npm run lint` (if configured)
|
||||
|
||||
- **Variants:** The default `standard` variant includes responsive widths, centered content, and padding.
|
||||
- **Custom Classes:** Add or change styles with the `class` prop.
|
||||
- **Content Slot:** Easily add any child components or content inside.
|
||||
## 📝 Contributing
|
||||
|
||||
```astro
|
||||
<Wrapper variant="standard">
|
||||
Your content goes here
|
||||
</Wrapper>
|
||||
```
|
||||
-----
|
||||
When contributing to this project, please follow these guidelines:
|
||||
|
||||
### [Support](https://lexingtonthemes.com/legal/support/)
|
||||
### [Documentation](https://lexingtonthemes.com/documentation/)
|
||||
### [Get your bundle](https://lexingtonthemes.com)
|
||||
1. Create components in the appropriate directories
|
||||
2. Follow the existing code style and naming conventions
|
||||
3. Add proper documentation for new features
|
||||
4. Test your changes before submitting
|
||||
|
||||
## 📄 License
|
||||
|
||||
### References
|
||||
[Add your license information here]
|
||||
|
||||
-[PWA](https://vite-pwa-org.netlify.app/)
|
||||
|
||||
@ -3,24 +3,37 @@ import tailwindcss from '@tailwindcss/vite'
|
||||
import { imagetools } from "imagetools"
|
||||
import react from "@astrojs/react"
|
||||
import mdx from "@astrojs/mdx";
|
||||
|
||||
import { defineConfig } from 'astro/config';
|
||||
import compress from 'vite-plugin-compression';
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
export default defineConfig({
|
||||
site: 'https://polymech.io',
|
||||
devToolbar: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
},
|
||||
i18n: {
|
||||
locales: ["es", "en", "de", "fr", "it", "ar", "ja", "zh"],
|
||||
locales: ["es", "en", "de", "fr", "it", "ar", "ja", "zh", "nl", "it", "pt"],
|
||||
defaultLocale: "en",
|
||||
},
|
||||
vite: {
|
||||
plugins: [
|
||||
tailwindcss()
|
||||
tailwindcss({
|
||||
config: './tailwind.config.cjs',
|
||||
jit: true
|
||||
}),
|
||||
compress({
|
||||
algorithm: 'gzip', // You can also use 'brotliCompress' for Brotli
|
||||
threshold: 1024, // Compress files larger than 1KB
|
||||
deleteOriginFile: false, // Keep original files (optional)
|
||||
})
|
||||
],
|
||||
build: {
|
||||
target: 'esnext',
|
||||
assetsDir: './assets',
|
||||
modulePreload: { polyfill: false },
|
||||
commonjsOptions: { esmExternals: true }
|
||||
commonjsOptions: { esmExternals: true },
|
||||
assetsInlineLimit: 1024,
|
||||
sourcemap: false,
|
||||
},
|
||||
ssr: {
|
||||
external: ['cacache', 'glob', 'xlsx', 'sharp', '@polymech/kbot-d']
|
||||
@ -46,10 +59,11 @@ export default defineConfig({
|
||||
skipInline: false,
|
||||
drafts: true
|
||||
},
|
||||
site: 'https://polymech.io',
|
||||
integrations: [
|
||||
//starlight(),
|
||||
//sitemap(),
|
||||
sitemap({
|
||||
|
||||
}),
|
||||
mdx(),
|
||||
//AstroPWA({}),
|
||||
react(),
|
||||
|
||||
142
package-lock.json
generated
142
package-lock.json
generated
@ -30,6 +30,7 @@
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.9",
|
||||
"cacache": "^19.0.1",
|
||||
"env-var": "^7.5.0",
|
||||
"exifreader": "^4.26.1",
|
||||
"file-type": "^20.0.0",
|
||||
"find-cache-dir": "^5.0.0",
|
||||
@ -64,6 +65,8 @@
|
||||
"tailwindcss": "^4.0.7",
|
||||
"type-fest": "^4.34.1",
|
||||
"vite": "^6.1.1",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"write-file-atomic": "^6.0.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "^3.24.2"
|
||||
@ -5132,6 +5135,24 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/configstore/node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/configstore/node_modules/write-file-atomic": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
|
||||
"integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"is-typedarray": "^1.0.0",
|
||||
"signal-exit": "^3.0.2",
|
||||
"typedarray-to-buffer": "^3.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
@ -5701,6 +5722,15 @@
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/env-var": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/env-var/-/env-var-7.5.0.tgz",
|
||||
"integrity": "sha512-mKZOzLRN0ETzau2W2QXefbFjo5EF4yWq28OyKb9ICdeNhHJlOE/pHHnz4hdYJ9cNZXcJHo5xN4OT4pzuSHSNvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
@ -6959,6 +6989,20 @@
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
|
||||
@ -7382,7 +7426,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -8445,6 +8488,18 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
@ -15325,6 +15380,15 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unset-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||
@ -15814,6 +15878,63 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-compression": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz",
|
||||
"integrity": "sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"debug": "^4.3.3",
|
||||
"fs-extra": "^10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": ">=2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-compression/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-compression/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-compression/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/vite/node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@ -16195,22 +16316,17 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/write-file-atomic": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
|
||||
"integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz",
|
||||
"integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"is-typedarray": "^1.0.0",
|
||||
"signal-exit": "^3.0.2",
|
||||
"typedarray-to-buffer": "^3.1.5"
|
||||
}
|
||||
"signal-exit": "^4.0.1"
|
||||
},
|
||||
"node_modules/write-file-atomic/node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"license": "ISC"
|
||||
"engines": {
|
||||
"node": "^18.17.0 || >=20.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "7.5.10",
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.7.9",
|
||||
"cacache": "^19.0.1",
|
||||
"env-var": "^7.5.0",
|
||||
"exifreader": "^4.26.1",
|
||||
"file-type": "^20.0.0",
|
||||
"find-cache-dir": "^5.0.0",
|
||||
@ -74,6 +75,8 @@
|
||||
"tailwindcss": "^4.0.7",
|
||||
"type-fest": "^4.34.1",
|
||||
"vite": "^6.1.1",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"write-file-atomic": "^6.0.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "^3.24.2"
|
||||
|
||||
@ -65,7 +65,7 @@ export default async function renderImg(props) {
|
||||
fadeInTransition,
|
||||
{ isImg: true }
|
||||
);
|
||||
const style = getStyleElement({ styleAttributes, backgroundStyles })
|
||||
const style = getStyleElement({ styleAttributes })
|
||||
const link = getLinkElement({ images, preload, imagesizes, linkAttributes })
|
||||
const layoutStyles = getLayoutStyles({ layout })
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ export default async function ({
|
||||
const { path, base, rest, image, imageWidth, imageHeight, imageFormat } =
|
||||
await getProcessedImage(src, transformConfigs);
|
||||
|
||||
await delay(250);
|
||||
await delay(100);
|
||||
src = path;
|
||||
|
||||
rest.aspect = `${imageWidth / imageHeight}`;
|
||||
@ -63,7 +63,7 @@ export default async function ({
|
||||
rest
|
||||
),
|
||||
async () => {
|
||||
await delay(250);
|
||||
await delay(100);
|
||||
return await getArtDirectedImages(
|
||||
artDirectives,
|
||||
placeholder,
|
||||
|
||||
@ -43,7 +43,7 @@ export default async function getImageSources(
|
||||
formats,
|
||||
async (format) => {
|
||||
try {
|
||||
await delay(250);
|
||||
await delay(100);
|
||||
const srcset = await getSrcset(src, base, requiredBreakpoints, format, {
|
||||
...rest,
|
||||
...formatOptions[format],
|
||||
|
||||
@ -5,8 +5,8 @@ export default {
|
||||
"publicDir": "C:\\Users\\zx\\Desktop\\polymech\\polymech-site\\public\\",
|
||||
"rootDir": "C:\\Users\\zx\\Desktop\\polymech\\polymech-site\\",
|
||||
"mode": "production",
|
||||
"outDir": "dist",
|
||||
"assetsDir": "/_astro",
|
||||
"outDir": "C:\\Users\\zx\\Desktop\\polymech\\polymech-site\\dist\\",
|
||||
"assetsDir": "_astro",
|
||||
"sourcemap": false,
|
||||
"assetFileNames": "/_astro/[name]@[width].[hash][extname]"
|
||||
}
|
||||
@ -53,5 +53,5 @@ export default function printWarning({
|
||||
: `can't be defined inside attributes.${element}`)) +
|
||||
colours.reset;
|
||||
|
||||
console.log(flag + keyLog, messageLog);
|
||||
//console.log(flag + keyLog, messageLog);
|
||||
}
|
||||
|
||||
@ -14,33 +14,22 @@
|
||||
"image": {
|
||||
"default": "/images/default-image.png",
|
||||
"error": "/images/error-image.png",
|
||||
"alt": "Astrofront"
|
||||
"alt": "Astrofront",
|
||||
"src": "https://assets.osr-plastic.org/machines//assets/newsletter/common/products/extruders/overview-3.jpg"
|
||||
}
|
||||
},
|
||||
"footer_left": [
|
||||
{
|
||||
"href": "/rss.xml",
|
||||
"text": "RSS"
|
||||
},
|
||||
{
|
||||
"href": "/helpcenter/home",
|
||||
"text": "Help"
|
||||
},
|
||||
{
|
||||
"href": "/infopages/terms",
|
||||
"text": "Terms"
|
||||
},
|
||||
{
|
||||
"href": "/infopages/privacy",
|
||||
"text": "Privacy"
|
||||
},
|
||||
{
|
||||
"href": "/forms/contact",
|
||||
"href": "/infopages/contact",
|
||||
"text": "Contact"
|
||||
},
|
||||
} ,
|
||||
{
|
||||
"href": "/infopages/about",
|
||||
"text": "About us"
|
||||
"href": "/newsletter/newsletter_2024_09_en-hugo-release.html",
|
||||
"text": "Newsletter"
|
||||
}
|
||||
],
|
||||
"footer_right": [
|
||||
@ -92,5 +81,8 @@
|
||||
"store": "resources"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tracking": {
|
||||
"googleAnalytics": "G-RW6Q6EG3J0"
|
||||
}
|
||||
}
|
||||
@ -9,8 +9,7 @@ export const OSR_ROOT = () => path.resolve(resolve("${OSR_ROOT}"))
|
||||
export const LOGGING_NAMESPACE = 'polymech-site'
|
||||
export const TRANSLATE_CONTENT = true
|
||||
export const LANGUAGES = ['en', 'ar', 'de', 'ja', 'es', 'zh', 'fr']
|
||||
//export const LANGUAGES_PROD = ['en']
|
||||
export const LANGUAGES_PROD = ['en', 'es', 'ar', 'de', 'ja', 'zh', 'fr']
|
||||
export const LANGUAGES_PROD = ['en', 'es', 'ar', 'de', 'ja', 'zh', 'fr', 'nl', 'it', 'pt']
|
||||
export const isRTL = (lang) => lang === 'ar'
|
||||
|
||||
// i18n constants
|
||||
@ -61,6 +60,7 @@ export const TASK_LOG_DIRECTORY = './logs/'
|
||||
// Task - Retail Config
|
||||
export const REGISTER_PRODUCT_TASKS = true
|
||||
export const RETAIL_PRODUCT_BRANCH = 'site'
|
||||
export const PROJECTS_BRANCH = 'projects'
|
||||
export const RETAIL_COMPILE_CACHE = false
|
||||
export const RETAIL_MEDIA_CACHE = true
|
||||
export const RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS = 'info'
|
||||
@ -107,7 +107,7 @@ export const SHOW_LICENSE = true
|
||||
export const SHOW_RENDERINGS = true
|
||||
|
||||
export const SHOW_TABS = false
|
||||
export const SHOW_GALLERY = false
|
||||
export const SHOW_GALLERY = true
|
||||
export const SHOW_FILES = true
|
||||
export const SHOW_SPECS = true
|
||||
export const SHOW_CHECKOUT = true
|
||||
@ -117,6 +117,8 @@ export const SHOW_RESOURCES = true
|
||||
export const SHOW_DEBUG = false
|
||||
export const SHOW_SAMPLES = true
|
||||
export const SHOW_README = false
|
||||
export const SHOW_RELATED = true
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
@ -159,13 +161,13 @@ export const IMAGE_SETTINGS =
|
||||
SHOW_DESCRIPTION: false,
|
||||
SIZES_THUMB: O_IMAGE.sizes_thumbs,
|
||||
SIZES_LARGE: O_IMAGE.sizes_large,
|
||||
SIZES_REGULAR: O_IMAGE.sizes
|
||||
SIZES_REGULAR: O_IMAGE.sizes_medium
|
||||
},
|
||||
LIGHTBOX: {
|
||||
SHOW_TITLE: true,
|
||||
SHOW_DESCRIPTION: true,
|
||||
SIZES_THUMB: O_IMAGE.sizes_thumbs,
|
||||
SIZES_LARGE: O_IMAGE.sizes_large,
|
||||
SIZES_REGULAR: O_IMAGE.sizes
|
||||
SIZES_REGULAR: O_IMAGE.sizes_medium
|
||||
}
|
||||
}
|
||||
@ -20,25 +20,22 @@ export const items = async (opts: { locale: string }) => {
|
||||
}
|
||||
]
|
||||
}
|
||||
export const footer_left = async ( locale: string ) => {
|
||||
const _T = async (text: string) => await translate(text, I18N_SOURCE_LANGUAGE, locale)
|
||||
return await pMap(config.footer_left, async (item) => {
|
||||
const isAbsoluteUrl = (url: string): boolean => /^[a-zA-Z]+:/.test(url);
|
||||
|
||||
const createFooterLinks = async (items: any[], locale: string) => {
|
||||
const _T = async (text: string) => await translate(text, I18N_SOURCE_LANGUAGE, locale);
|
||||
|
||||
return await pMap(items, async (item) => {
|
||||
const translatedText = await _T(item.text); // Single translation call
|
||||
|
||||
return {
|
||||
"href": `${item.href}`,
|
||||
"title": await _T(item.text),
|
||||
"ariaLabel": item.text,
|
||||
"href": isAbsoluteUrl(item.href) ? item.href : `/${locale}${item.href}`,
|
||||
"title": translatedText, // Use cached translation
|
||||
"ariaLabel": translatedText, // Use cached translation
|
||||
"class": "hover:text-orange-600"
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
export const footer_right = async ( locale: string ) => {
|
||||
const _T = async (text: string) => await translate(text, I18N_SOURCE_LANGUAGE, locale)
|
||||
return await pMap(config.footer_right, async (item) => {
|
||||
return {
|
||||
"href": `/${item.href}`,
|
||||
"title": await _T(item.text),
|
||||
"ariaLabel": item.text,
|
||||
"class": "hover:text-orange-600"
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const footer_left = (locale: string) => createFooterLinks(config.footer_left, locale);
|
||||
export const footer_right = (locale: string) => createFooterLinks(config.footer_right, locale);
|
||||
|
||||
@ -12,7 +12,7 @@ export enum E_BROADBAND_SPEED {
|
||||
}
|
||||
|
||||
const imageConfigSchema = z.object({
|
||||
sizes: z.string(),
|
||||
sizes_medium: z.string(),
|
||||
sizes_thumbs: z.string(),
|
||||
sizes_large: z.string(),
|
||||
})
|
||||
@ -28,21 +28,21 @@ export const IMAGE_PRESET: Images =
|
||||
{
|
||||
[E_BROADBAND_SPEED.SLOW]: {
|
||||
// For 2g connections: smaller image widths help performance. (Middle East & Africa)
|
||||
sizes: "(min-width: 100px) 100px, 100vw",
|
||||
sizes_medium: "(min-width: 100px) 100px, 100vw",
|
||||
sizes_thumbs: "(min-width: 80px) 80px, 80vw",
|
||||
sizes_large: "(min-width: 320px) 320px, 320vw",
|
||||
},
|
||||
[E_BROADBAND_SPEED.MEDIUM]:
|
||||
{
|
||||
// For 3g connections: a moderate size image for a balance of quality and speed.
|
||||
sizes: "(min-width: 800px) 800px, 800vw",
|
||||
sizes_medium: "(min-width: 400px) 400px, 400vw",
|
||||
sizes_thumbs: "(min-width: 120px) 120px, 120vw",
|
||||
sizes_large: "(min-width: 1024px) 1024px, 1024vw",
|
||||
},
|
||||
[E_BROADBAND_SPEED.FAST]:
|
||||
{
|
||||
// For 4g connections: larger images for high-resolution displays.
|
||||
sizes: "(min-width: 1024px) 1024px, 1024vw",
|
||||
sizes_medium: "(min-width: 1024px) 1024px, 1024vw",
|
||||
sizes_thumbs: "(min-width: 180px) 180px, 180vw",
|
||||
sizes_large: "(min-width: 1200px) 1200px, 1200vw"
|
||||
}
|
||||
|
||||
@ -4,9 +4,13 @@ import { sync as exists } from '@polymech/fs/exists'
|
||||
|
||||
import type { IOptions } from '@polymech/i18n'
|
||||
import { CONFIG_DEFAULT } from '@polymech/commons'
|
||||
import { I18N_ASSET_PATH, I18N_CACHE, I18N_SOURCE_LANGUAGE,
|
||||
PRODUCT_DIR, PRODUCT_SPECS,
|
||||
RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS } from '@/app/config.js'
|
||||
import {
|
||||
I18N_ASSET_PATH,
|
||||
I18N_CACHE,
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
PRODUCT_SPECS,
|
||||
RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS
|
||||
} from '@/app/config.js'
|
||||
|
||||
import { translateXLS } from '@polymech/i18n/translate_xls'
|
||||
import { I18N_STORE, OSR_ROOT } from 'config/config.js'
|
||||
|
||||
@ -9,6 +9,7 @@ import { findUp } from 'find-up'
|
||||
import { createLogger } from '@polymech/log'
|
||||
import { parse, IProfile } from '@polymech/commons/profile'
|
||||
import { renderMarkup } from "@/model/component.js";
|
||||
|
||||
import {
|
||||
LOGGING_NAMESPACE,
|
||||
OSRL_ENV,
|
||||
@ -63,7 +64,10 @@ export async function markdownToHtml(markdown: string): Promise<string> {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
export async function createMarkdownComponent(markdown: string) {
|
||||
export const createMarkdownComponent = async (markdown: string) => {
|
||||
const html = unescapeHTML(await markdownToHtml(markdown));
|
||||
return createComponent(() => renderTemplate(html as any, []));
|
||||
}
|
||||
|
||||
export const createHTMLComponent = async (html: string) =>
|
||||
createComponent(() => renderTemplate(unescapeHTML(html) as any, []))
|
||||
@ -47,13 +47,15 @@ const hreflangs = LANGUAGES_PROD.filter((lang)=>lang!==Astro.currentLocale).map(
|
||||
}))
|
||||
|
||||
const image = item?.image || config.site.image
|
||||
const image_url = image.url
|
||||
const image_url = image.src
|
||||
const image_alt = image.alt
|
||||
|
||||
const title = item?.title as string || config.site.title || ""
|
||||
const description = item?.description as string || config.metadata.description
|
||||
|
||||
const keywords = await item_keywords(item, Astro.currentLocale)
|
||||
|
||||
const tracking = config?.tracking?.googleAnalytics
|
||||
---
|
||||
|
||||
<AstroSeo
|
||||
@ -129,18 +131,25 @@ const keywords = await item_keywords(item, Astro.currentLocale)
|
||||
<!--- IBM Plex Mono font from fonts.google.com -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="preload" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" as="style" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" />
|
||||
|
||||
<script is:inline src="https://cdn.jsdelivr.net/npm/flowbite@3.0.0/dist/flowbite.min.js"></script>
|
||||
<script src="/js/flowbite.min.js" defer></script>
|
||||
|
||||
<!-- alpine JS -->
|
||||
<script src="//unpkg.com/alpinejs" defer></script>
|
||||
<script src="/js/cdn.min.js" defer></script>
|
||||
|
||||
<StructuredData frontmatter={item} />
|
||||
|
||||
{tracking && (
|
||||
<script async src={`https://www.googletagmanager.com/gtag/js?id=${tracking}`}></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date())
|
||||
gtag('config', {tracking})
|
||||
</script>
|
||||
)}
|
||||
|
||||
{ REDIRECT && <script>
|
||||
const currentPath = window.location.pathname;
|
||||
if (!/^\/[a-z]{2}(\/|$)/i.test(currentPath)) {
|
||||
@ -150,5 +159,8 @@ const keywords = await item_keywords(item, Astro.currentLocale)
|
||||
window.location.href = `/${language}`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="sitemap" href="/sitemap-index.xml" />
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -46,12 +46,12 @@ const footerRight = await footer_right(locale)
|
||||
|
||||
<Wrapper variant="standard" class="py-12">
|
||||
<footer class="py-2">
|
||||
<div class="p-4 xl:pb-0 bg-[white] overflow-hidden rounded-xl">
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
<div class="p-4 bg-[white] overflow-hidden rounded-xl">
|
||||
<div class="grid grid-cols-2 gap-6">
|
||||
<div
|
||||
class="flex flex-col h-full justify-between xl:pb-2 order-last md:order-none"
|
||||
>
|
||||
class="flex flex-col justify-between">
|
||||
<nav role="navigation">
|
||||
|
||||
<ul class="text-xs space-y-1 font-mono uppercase text-neutral-500">
|
||||
{
|
||||
footerRight.map((link) => (
|
||||
@ -75,19 +75,8 @@ const footerRight = await footer_right(locale)
|
||||
}
|
||||
</div>
|
||||
</nav>
|
||||
<div class="flex gap-4 mt-12 items-center">
|
||||
<img src="/logos/transparent.svg" alt="logo" class="size-4" />
|
||||
<p
|
||||
class="text-xs leading-5 text-neutral-400 text-pretty font-mono uppercase"
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
src="/logos/transparent.svg"
|
||||
alt="logo"
|
||||
class="size-12 md:mx-auto fill-orange-600"
|
||||
/>
|
||||
|
||||
<div class="flex flex-col justify-between md:text-right xl:pb-2 mr-2">
|
||||
<nav role="navigation">
|
||||
<ul class="text-xs space-y-1 font-mono uppercase text-neutral-500">
|
||||
|
||||
@ -23,9 +23,7 @@ const navItems = await items({ locale });
|
||||
title={item.title}
|
||||
aria-label={item.ariaLabel}
|
||||
class={item.class}
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
>{item.title}</a>
|
||||
))
|
||||
}
|
||||
</nav>
|
||||
|
||||
@ -43,9 +43,7 @@ const mergedLightboxSettings = {
|
||||
SHOW_DESCRIPTION: lightboxSettings.SHOW_DESCRIPTION ?? IMAGE_SETTINGS.LIGHTBOX.SHOW_DESCRIPTION,
|
||||
};
|
||||
const locale = Astro.currentLocale || "en";
|
||||
|
||||
---
|
||||
|
||||
<div
|
||||
x-data={`
|
||||
{
|
||||
@ -76,8 +74,8 @@ const locale = Astro.currentLocale || "en";
|
||||
lightboxLoaded = false;
|
||||
preloadAndOpen();
|
||||
}
|
||||
}"
|
||||
class="product-gallery"><div class="flex flex-col h-full">
|
||||
}"class="product-gallery">
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- Main Image (click to preload and open lightbox) -->
|
||||
<div class="flex-1 flex items-center justify-center" @click="preloadAndOpen()">
|
||||
{images.map((image, index) => (
|
||||
@ -88,8 +86,12 @@ const locale = Astro.currentLocale || "en";
|
||||
objectFit="contain"
|
||||
format="avif"
|
||||
placeholder="blurred"
|
||||
sizes={mergedGallerySettings.SIZES_REGULAR}
|
||||
class="rounded max-h-full object-contain main-image"
|
||||
breakpoints={[200,300,500]}
|
||||
fadeInTransition={{
|
||||
delay: "0.5s",
|
||||
duration: "2.5s",
|
||||
timingFunction: "linear",
|
||||
}}
|
||||
attributes={{
|
||||
img: { class: "main-image rounded-lg max-h-[60vh] aspect-square" }
|
||||
}}
|
||||
|
||||
@ -113,10 +113,9 @@ const ld = await toJsonLd(images, Astro.currentLocale || I18N_SOURCE_LANGUAGE, c
|
||||
this.lightboxLoaded = false;
|
||||
let img = new Image();
|
||||
img.src = this.images[this.currentIndex].src;
|
||||
img.onload = () => {
|
||||
this.lightboxLoaded = true;
|
||||
this.open = true;
|
||||
};
|
||||
img.onload = () => { };
|
||||
}
|
||||
}
|
||||
`}
|
||||
@ -152,8 +151,8 @@ const ld = await toJsonLd(images, Astro.currentLocale || I18N_SOURCE_LANGUAGE, c
|
||||
alt={alt_translated[index]}
|
||||
objectFit="contain"
|
||||
format="avif"
|
||||
placeholder="blurred"
|
||||
sizes={mergedGallerySettings.SIZES_REGULAR}
|
||||
loading="lazy"
|
||||
attributes={{
|
||||
img: { class: "main-image p-1 rounded-lg max-h-[60vh] aspect-square" }
|
||||
}}
|
||||
@ -172,7 +171,8 @@ const ld = await toJsonLd(images, Astro.currentLocale || I18N_SOURCE_LANGUAGE, c
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<!-- Thumbnails -->
|
||||
<!-- Thumbnails - only shown when multiple images exist -->
|
||||
{images.length > 1 && (
|
||||
<div class="p-1 overflow-x-auto scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-200">
|
||||
<div class="flex p-2 mt-2 ml-2 mr-2 gap-2 items-center justify-center">
|
||||
{images.map((image, index) => (
|
||||
@ -189,6 +189,7 @@ const ld = await toJsonLd(images, Astro.currentLocale || I18N_SOURCE_LANGUAGE, c
|
||||
placeholder="blurred"
|
||||
sizes={mergedGallerySettings.SIZES_THUMB}
|
||||
alt={alt_translated[index]}
|
||||
breakpoints={[100]}
|
||||
attributes={{
|
||||
img: {
|
||||
class: "w-32 h-32 rounded-lg hover:ring-2 hover:ring-blue-500 thumbnail-img aspect-square"
|
||||
@ -200,6 +201,7 @@ const ld = await toJsonLd(images, Astro.currentLocale || I18N_SOURCE_LANGUAGE, c
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<!-- Lightbox Modal (with swipe functionality) -->
|
||||
<div
|
||||
@ -268,6 +270,5 @@ const ld = await toJsonLd(images, Astro.currentLocale || I18N_SOURCE_LANGUAGE, c
|
||||
❯
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<script type="application/ld+json" set:html={ JSON.stringify(ld) }></script>
|
||||
</div>
|
||||
@ -15,6 +15,7 @@ const {
|
||||
|
||||
const content = await Astro.slots.render('default')
|
||||
const translatedText = await translate(content, I18N_SOURCE_LANGUAGE, language, rest)
|
||||
|
||||
---
|
||||
<div data-widget="polymech.i18n" class={clazz}>
|
||||
{translatedText}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
---
|
||||
import { component, createMarkdownComponent } from "@/base/index.js";
|
||||
import { createMarkdownComponent } from "@/base/index.js";
|
||||
import Translation from "@/components/polymech/i18n.astro";
|
||||
import Link from "./link.astro";
|
||||
|
||||
const { frontmatter: data, ...rest } = Astro.props;
|
||||
const { frontmatter: data } = Astro.props;
|
||||
const LINK_CLASSES = "text-blue-400 hover:text-blue-800 hover:underline";
|
||||
|
||||
const getHref = (key, data) => {
|
||||
switch (key) {
|
||||
case "cad":
|
||||
return data.cad?.[0]?.[".html"];
|
||||
return data.cad?.[0]?.[".html"]
|
||||
default:
|
||||
return data[key];
|
||||
return data[key]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const checkCondition = (key, data) => {
|
||||
switch (key) {
|
||||
@ -74,11 +74,11 @@ const filteredGroups: Record<
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const extraContent = [data.extra_resources, data.tests]
|
||||
const extraContent = [data.resources, data.tests]
|
||||
.filter((s) => s && s.length)
|
||||
.map(createMarkdownComponent)
|
||||
|
||||
const sharedContent = [data.shared_resources]
|
||||
const sharedContent = [data.shared]
|
||||
.filter((s) => s && s.length)
|
||||
.map(createMarkdownComponent)
|
||||
---
|
||||
@ -89,10 +89,10 @@ const sharedContent = [data.shared_resources]
|
||||
{
|
||||
Object.entries(filteredGroups).map(([name, links]) => (
|
||||
<div class="p-2">
|
||||
<h3 class="text-xl font-bold mb-2">
|
||||
<h3 class="text-x font-bold mb-2">
|
||||
<Translation>{name}</Translation>
|
||||
</h3>
|
||||
<ul class="list-disc pl-6 space-y-1">
|
||||
<ul class="list-disc pl-6">
|
||||
{links.map((link) => (
|
||||
<Link href={link.getHref()} className={LINK_CLASSES}>
|
||||
<Translation>{link.label}</Translation>
|
||||
@ -105,7 +105,7 @@ const sharedContent = [data.shared_resources]
|
||||
</div>
|
||||
{
|
||||
extraContent.length > 0 && (
|
||||
<div class="p-2">
|
||||
<div class="p-4">
|
||||
<h3 class="text-xl font-bold mb-2">
|
||||
<Translation>Extras</Translation>
|
||||
</h3>
|
||||
@ -119,7 +119,7 @@ const sharedContent = [data.shared_resources]
|
||||
}
|
||||
{
|
||||
sharedContent.length > 0 && (
|
||||
<div class="p-2">
|
||||
<div class="p-4">
|
||||
<div class="grid grid-cols-1 gap-4 extra-resources">
|
||||
{sharedContent.map(async (Content) => (
|
||||
<Content class="extra-resource" />
|
||||
|
||||
241
src/components/report.md
Normal file
241
src/components/report.md
Normal file
@ -0,0 +1,241 @@
|
||||
# Astro Project Analysis: polymech-site
|
||||
|
||||
## 1. Project Structure Overview
|
||||
|
||||
Based on the explored files, the polymech-site project follows a typical Astro project structure with some custom organization patterns:
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
polymech-site/
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ ├── global/
|
||||
│ │ │ └── Navigation.astro
|
||||
│ │ ├── polymech/
|
||||
│ │ │ └── i18n.astro
|
||||
│ │ └── BaseHead.astro
|
||||
│ ├── layouts/
|
||||
│ │ └── BaseLayout.astro
|
||||
│ ├── pages/
|
||||
│ │ └── index.astro
|
||||
│ └── base/ (utilities)
|
||||
├── public/
|
||||
├── astro.config.mjs
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
- **BaseHead.astro**: Handles metadata, SEO elements, and global head content
|
||||
- **BaseLayout.astro**: Provides the main page structure and wraps content
|
||||
- **Navigation.astro**: Implements site navigation with potential interactive elements
|
||||
- **i18n.astro**: Appears to handle internationalization at the component level
|
||||
|
||||
### Configuration
|
||||
|
||||
The project uses:
|
||||
- Astro's built-in features for static site generation
|
||||
- Various integrations defined in astro.config.mjs
|
||||
- A component-based architecture with clear separation of concerns
|
||||
|
||||
## 2. Patterns and Potential Issues
|
||||
|
||||
### Observed Patterns
|
||||
|
||||
1. **Component Organization**
|
||||
- Components are organized by functionality and scope (global vs. specific)
|
||||
- Layout components are separated from regular components
|
||||
- Reusable UI elements are componentized
|
||||
|
||||
2. **Internationalization Approach**
|
||||
- Custom i18n implementation at the component level
|
||||
- The project appears to handle multiple languages
|
||||
|
||||
3. **Rendering Strategy**
|
||||
- Primarily static rendering with some potential client-side hydration
|
||||
- Heavy use of Astro's component model
|
||||
|
||||
### Potential Issues
|
||||
|
||||
1. **Internationalization Complexity**
|
||||
- The i18n implementation appears custom and potentially complex
|
||||
- No clear centralized i18n management system was identified
|
||||
|
||||
2. **Component Granularity**
|
||||
- With 163 Astro files, there might be issues with component granularity
|
||||
- Potential for component duplication or insufficient reuse
|
||||
|
||||
3. **Build Optimization**
|
||||
- No clear strategy for code splitting or lazy loading of components
|
||||
- Potential performance issues with large number of components
|
||||
|
||||
4. **SEO Implementation**
|
||||
- SEO handling appears to be primarily in BaseHead, which may limit page-specific optimizations
|
||||
- No clear structured data implementation was observed
|
||||
|
||||
## 3. Best Practices for Astro Development
|
||||
|
||||
### Component Architecture
|
||||
|
||||
1. **Island Architecture**
|
||||
- Leverage Astro's island architecture more explicitly
|
||||
- Only hydrate interactive components, keeping most of the site static
|
||||
|
||||
2. **Component Composition**
|
||||
- Use slots and props for flexible component composition
|
||||
- Create truly reusable components with clear interfaces
|
||||
|
||||
3. **Content Management**
|
||||
- Use Astro's content collections for structured content
|
||||
- Separate content from presentation where possible
|
||||
|
||||
### Performance
|
||||
|
||||
1. **Image Optimization**
|
||||
- Use Astro's built-in image optimization features
|
||||
- Implement responsive images with appropriate formats
|
||||
|
||||
2. **CSS Strategy**
|
||||
- Scope CSS to components where possible
|
||||
- Consider using a utility-first approach for consistency
|
||||
|
||||
3. **JavaScript Usage**
|
||||
- Minimize client-side JavaScript
|
||||
- Use directives like `client:load` and `client:visible` strategically
|
||||
|
||||
### Development Workflow
|
||||
|
||||
1. **Type Safety**
|
||||
- Leverage TypeScript for component props
|
||||
- Define clear interfaces for data structures
|
||||
|
||||
2. **Testing**
|
||||
- Implement component testing with appropriate tools
|
||||
- Consider visual regression testing for UI components
|
||||
|
||||
## 4. Specific Improvement Suggestions
|
||||
|
||||
### Performance Optimization
|
||||
|
||||
1. **Asset Optimization**
|
||||
- Implement proper image optimization with `<Image />` component
|
||||
- Use responsive images with srcset for different viewport sizes
|
||||
|
||||
2. **Code Splitting**
|
||||
- Review client-side JavaScript usage and split appropriately
|
||||
- Use dynamic imports for larger client components
|
||||
|
||||
3. **Resource Hints**
|
||||
- Add preload/prefetch directives for critical resources
|
||||
- Implement resource prioritization
|
||||
|
||||
```astro
|
||||
<!-- Example improvement for BaseHead.astro -->
|
||||
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
|
||||
```
|
||||
|
||||
### Internationalization (i18n) Implementation
|
||||
|
||||
1. **Centralized Solution**
|
||||
- Consider adopting a more standardized i18n solution like Astro i18n or astro-i18next
|
||||
- Implement a centralized translation management system
|
||||
|
||||
2. **Content Structure**
|
||||
- Organize content by language in content collections
|
||||
- Create a clear separation between content and presentation
|
||||
|
||||
3. **URL Strategy**
|
||||
- Implement a consistent URL strategy for language variants (e.g., /en/page, /fr/page)
|
||||
- Add language metadata to improve SEO for multilingual content
|
||||
|
||||
```astro
|
||||
<!-- Example improvement for i18n handling -->
|
||||
---
|
||||
import { getLanguageFromURL } from '../utils/i18n';
|
||||
const lang = getLanguageFromURL(Astro.url.pathname);
|
||||
const translations = await import(`../i18n/${lang}.js`);
|
||||
---
|
||||
```
|
||||
|
||||
### Component Organization
|
||||
|
||||
1. **Atomic Design Principles**
|
||||
- Consider reorganizing components following atomic design principles
|
||||
- Create atoms, molecules, organisms, templates, and pages
|
||||
|
||||
2. **Documentation**
|
||||
- Add component documentation with examples
|
||||
- Create a component playground or storybook
|
||||
|
||||
3. **Naming Conventions**
|
||||
- Implement consistent naming conventions
|
||||
- Group related components in subdirectories
|
||||
|
||||
### Code Maintainability
|
||||
|
||||
1. **TypeScript Integration**
|
||||
- Add TypeScript for all component props
|
||||
- Define interfaces for data structures
|
||||
|
||||
```astro
|
||||
<!-- Example improvement with TypeScript -->
|
||||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
image?: { src: string; alt: string };
|
||||
canonicalURL?: URL;
|
||||
}
|
||||
|
||||
const { title, description, image, canonicalURL = Astro.url } = Astro.props;
|
||||
---
|
||||
```
|
||||
|
||||
2. **Code Comments**
|
||||
- Add meaningful comments for complex logic
|
||||
- Document component usage and requirements
|
||||
|
||||
3. **Consistent Formatting**
|
||||
- Implement consistent code formatting with tools like Prettier
|
||||
- Add ESLint for code quality enforcement
|
||||
|
||||
### SEO Optimization
|
||||
|
||||
1. **Structured Data**
|
||||
- Implement JSON-LD structured data for key pages
|
||||
- Add appropriate schema.org markup
|
||||
|
||||
```astro
|
||||
<!-- Example JSON-LD implementation -->
|
||||
<script type="application/ld+json" set:html={JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"name": "Polymech",
|
||||
"url": Astro.site.toString()
|
||||
})} />
|
||||
```
|
||||
|
||||
2. **Meta Tag Management**
|
||||
- Create a dedicated SEO component with flexible options
|
||||
- Ensure all pages have appropriate meta tags
|
||||
|
||||
3. **Performance Metrics**
|
||||
- Optimize for Core Web Vitals
|
||||
- Add monitoring for key performance metrics
|
||||
|
||||
## 5. Conclusion
|
||||
|
||||
The polymech-site project demonstrates a solid foundation using Astro's component model and static site generation capabilities. With 163 Astro files, it's a substantial project that would benefit from more structured organization principles and standardized approaches to common concerns like internationalization and SEO.
|
||||
|
||||
By implementing the suggested improvements, the project could achieve better performance, maintainability, and extensibility while leveraging Astro's strengths in creating fast, content-focused websites.
|
||||
|
||||
Key priorities should be:
|
||||
1. Optimizing asset delivery and performance
|
||||
2. Standardizing the i18n approach
|
||||
3. Enhancing component documentation and organization
|
||||
4. Improving SEO implementation with structured data
|
||||
5. Adding type safety with TypeScript
|
||||
|
||||
These changes would significantly improve the developer experience and end-user performance while making the codebase more maintainable for future development.
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
---
|
||||
import { default_image } from "@/app/config.js"
|
||||
const { title, url, price, model } = Astro.props
|
||||
const thumbnail = model?.assets?.renderings[0]?.url || default_image()
|
||||
import Img from "@/components/polymech/image.astro"
|
||||
---
|
||||
import { default_image } from "@/app/config.js";
|
||||
import Img from "@/components/polymech/image.astro";
|
||||
import Translate from "@/components/polymech/i18n.astro";
|
||||
|
||||
<div class="group relative bg-white overflow-hidden group rounded-xl font-mono">
|
||||
const { title, url, price, model, selected = false } = Astro.props;
|
||||
const thumbnail = model?.assets?.renderings[0]?.url || default_image();
|
||||
const classes = `group relative bg-white overflow-hidden group rounded-xl font-mono ${selected ? "ring-2 ring-orange-500" : ""}`
|
||||
|
||||
---
|
||||
<div class={classes}>
|
||||
<div class="p-4 overflow-hidden group-hover:opacity-75 duration-300 transition-all">
|
||||
<a href={url} title={title} aria-label={title}>
|
||||
<Img
|
||||
@ -24,7 +27,7 @@ import Img from "@/components/polymech/image.astro"
|
||||
<h3>
|
||||
<a href={url} title={title} aria-label={title}>
|
||||
<span aria-hidden="true" class="absolute inset-0"></span>
|
||||
{title}
|
||||
<Translate>{title}</Translate>
|
||||
</a>
|
||||
</h3>
|
||||
<p class="absolute top-4 right-4">{price}</p>
|
||||
|
||||
@ -19,7 +19,7 @@ const pages = [
|
||||
},
|
||||
{
|
||||
name: "Forms",
|
||||
links: [{ href: "/forms/contact", text: "Contact" }],
|
||||
links: [{ href: "/forms/contact2", text: "Contact" }],
|
||||
},
|
||||
{
|
||||
name: "System",
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
import { defineCollection, z } from "astro:content"
|
||||
import { loader } from './model/component.js'
|
||||
import { ComponentConfigSchema } from '@polymech/commons/component'
|
||||
import { RETAIL_PRODUCT_BRANCH, PROJECTS_BRANCH } from 'config/config.js'
|
||||
|
||||
import { glob } from 'astro/loaders'
|
||||
|
||||
const store = defineCollection({
|
||||
loader: loader() as any,
|
||||
loader: loader(RETAIL_PRODUCT_BRANCH) as any,
|
||||
schema: ComponentConfigSchema.passthrough(),
|
||||
})
|
||||
const projects = defineCollection({
|
||||
loader: loader(PROJECTS_BRANCH) as any,
|
||||
schema: ComponentConfigSchema.passthrough(),
|
||||
})
|
||||
const helpcenter = defineCollection({
|
||||
@ -35,8 +41,9 @@ const resources = defineCollection({
|
||||
});
|
||||
|
||||
export const collections = {
|
||||
store: store,
|
||||
helpcenter: helpcenter,
|
||||
infopages: infopages,
|
||||
resources
|
||||
store,
|
||||
projects,
|
||||
resources,
|
||||
helpcenter,
|
||||
infopages
|
||||
};
|
||||
17
src/content/infopages/contact.md
Normal file
17
src/content/infopages/contact.md
Normal file
@ -0,0 +1,17 @@
|
||||
## Contact
|
||||
|
||||
## Administration & Sales
|
||||
|
||||
[sales@plastic-hub.com](mailto:/sales@plastic-hub.com)
|
||||
|
||||
Anne Barbier - +34 691 952 287
|
||||
|
||||
Address - Factory
|
||||
|
||||
Polígono Can Clapers
|
||||
Carrer Can peric 11, 1B
|
||||
08181 Sentmenat ~ Spain
|
||||
|
||||
VAT - ID : ESY0100830N
|
||||
|
||||
[Get Directions](https://www.google.com/maps/place/Plastic+Hub/@41.6093789,2.1399009,17z/data=!3m1!4b1!4m5!3m4!1s0x12a4eb80cfabbbfd:0x2cd16f2aff436ed!8m2!3d41.6094019!4d2.1421267)
|
||||
@ -2,7 +2,7 @@
|
||||
import BaseHead from "../components/BaseHead.astro";
|
||||
import Navigation from "../components/global/Navigation.astro";
|
||||
import Footer from "../components/global/Footer.astro";
|
||||
import { I18N_SOURCE_LANGUAGE, isRTL } from "config/config.js"
|
||||
import { isRTL } from "config/config.js"
|
||||
|
||||
const { frontmatter: frontmatter, additionalKeywords, ...rest } = Astro.props;
|
||||
|
||||
@ -14,7 +14,7 @@ const { frontmatter: frontmatter, additionalKeywords, ...rest } = Astro.props;
|
||||
{...rest}
|
||||
/>
|
||||
</head>
|
||||
<body class="bg-neutral-100 mx-auto 2xl:max-w-7xl flex flex-col min-h-svh p-4">
|
||||
<body class="bg-neutral-100 mx-auto 2xl:max-w-7xl flex flex-col min-h-svh p-4 text-neutral-500 font-mono">
|
||||
<Navigation />
|
||||
<main class="grow">
|
||||
<slot />
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
---
|
||||
import BaseLayout from "./BaseLayout.astro";
|
||||
const { frontmatter } = Astro.props;
|
||||
import Wrapper from "@/components/containers/Wrapper.astro";
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { translate } from '@/base/i18n.js'
|
||||
import { createHTMLComponent } from '@/base/index.js'
|
||||
const content = await Astro.slots.render('default')
|
||||
const translatedText = await translate(content, I18N_SOURCE_LANGUAGE, Astro.currentLocale)
|
||||
const Markup = await createHTMLComponent(translatedText)
|
||||
---
|
||||
<BaseLayout>
|
||||
<Wrapper>
|
||||
<section>
|
||||
<div class="grid sm:grid-cols-1 lg:grid-cols-1 xl:grid-cols-1 gap-2">
|
||||
<div class="simple-prose-styles py-2 lg:col-start-3 justify-end p-4">
|
||||
<slot />
|
||||
<div class="grid sm:grid-cols-1 lg:grid-cols-1 xl:grid-cols-1 gap-2 text-neutral-500 markdown-content">
|
||||
<div class="py-2 p-4 bg-white rounded-xl">
|
||||
<Markup/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -6,7 +6,7 @@ import Wrapper from "@/components/containers/Wrapper.astro"
|
||||
<BaseLayout>
|
||||
<Wrapper>
|
||||
<section>
|
||||
<div class="grid grid-cols-1 md:grid-cols-1">
|
||||
<div class="grid grid-cols-1 md:grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<div class="flex flex-col">
|
||||
<div class="prose-styles lg:col-span-2">
|
||||
<img
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import BaseLayout from "./BaseLayout.astro";
|
||||
import { createMarkdownComponent } from "@/base/index.js";
|
||||
import { translate } from "@/base/i18n.js";
|
||||
@ -12,6 +13,13 @@ import Specs from "@/components/polymech/specs.astro";
|
||||
import TabButton from "@/components/polymech/tab-button.astro";
|
||||
import TabContent from "@/components/polymech/tab-content.astro";
|
||||
|
||||
import StoreEntries from "@/components/store/StoreEntries.astro";
|
||||
import {
|
||||
IComponentConfigEx,
|
||||
group_by_path,
|
||||
group_path,
|
||||
} from "@/model/component.js";
|
||||
|
||||
import "flowbite";
|
||||
|
||||
import {
|
||||
@ -29,13 +37,15 @@ import {
|
||||
SHOW_RESOURCES,
|
||||
SHOW_CHECKOUT,
|
||||
SHOW_README,
|
||||
SHOW_RELATED,
|
||||
DEFAULT_LICENSE,
|
||||
isRTL,
|
||||
} from "config/config.js";
|
||||
|
||||
const { frontmatter: item, ...rest } = Astro.props;
|
||||
|
||||
const content = await translate(
|
||||
item.content || "",
|
||||
item.body || "",
|
||||
I18N_SOURCE_LANGUAGE,
|
||||
Astro.currentLocale,
|
||||
);
|
||||
@ -54,22 +64,26 @@ const str_debug =
|
||||
"\n```";
|
||||
|
||||
const Content_Debug = await createMarkdownComponent(str_debug);
|
||||
const view = "store";
|
||||
const items = await getCollection(view); //.filter((i) => item.rel !== i.id);
|
||||
//const group_id = group_path(item);
|
||||
const others = await group_by_path(items, Astro.currentLocale);
|
||||
---
|
||||
|
||||
<BaseLayout frontmatter={item} description={item.description} {...rest}>
|
||||
<BaseLayout frontmatter={item} description={item.description} {...rest} class="">
|
||||
<Wrapper>
|
||||
<section>
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-2 just xl:grid-cols-2 gap-2">
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-2 just xl:grid-cols-2 gap-2 ">
|
||||
<div class="flex flex-col gap-2 h-full justify-between">
|
||||
<div>
|
||||
<article class="markdown-content bg-white rounded-xl p-4">
|
||||
<h1
|
||||
class="text-neutral-500 font-mono font-semibold mb-2 text-2xl"
|
||||
class="text-neutral-500 font-semibold mb-2 text-2xl"
|
||||
>
|
||||
<span><Translate>{`${item.title}`}</Translate></span>
|
||||
{
|
||||
isRTL(Astro.currentLocale) && (
|
||||
<div class="text-neutral-500 font-mono font-semibold mb-2">
|
||||
<div class="text-neutral-500 font-semibold mb-2">
|
||||
"{item.title}"
|
||||
</div>
|
||||
)
|
||||
@ -90,7 +104,7 @@ const Content_Debug = await createMarkdownComponent(str_debug);
|
||||
href={item.cad[0][".html"]}
|
||||
title="link to your page"
|
||||
aria-label="your label"
|
||||
class="relative group overflow-hidden pl-4 font-mono h-14 flex space-x-6 items-center bg-white hover:bg-neutral-200 duration-300 rounded-xl w-full justify-between"
|
||||
class="relative group overflow-hidden pl-4 h-14 flex space-x-6 items-center bg-white hover:bg-neutral-200 duration-300 rounded-xl w-full justify-between"
|
||||
>
|
||||
<span class="relative uppercase text-xs text-neutral-600">
|
||||
<Translate>3D Preview</Translate>
|
||||
@ -141,7 +155,7 @@ const Content_Debug = await createMarkdownComponent(str_debug);
|
||||
href={item.checkout}
|
||||
title="link to your page"
|
||||
aria-label="your label"
|
||||
class="relative group overflow-hidden pl-4 font-mono h-14 flex space-x-6 items-center bg-orange-500 hover:bg-black duration-300 rounded-xl w-full justify-between"
|
||||
class="relative group overflow-hidden pl-4 h-14 flex space-x-6 items-center bg-orange-500 hover:bg-black duration-300 rounded-xl w-full justify-between"
|
||||
>
|
||||
<span class="relative uppercase text-xs text-white">
|
||||
<Translate>Add to cart</Translate>
|
||||
@ -191,7 +205,7 @@ const Content_Debug = await createMarkdownComponent(str_debug);
|
||||
SHOW_LICENSE && (
|
||||
<div class="space-y-2">
|
||||
<div class="bg-white rounded-xl p-4">
|
||||
<h3 class="text-lg text-neutral-600 uppercase font-mono tracking-tight">
|
||||
<h3 class="text-lg text-neutral-600 uppercase tracking-tight">
|
||||
<Translate>License</Translate>
|
||||
</h3>
|
||||
<p class="text-neutral-500 mt-4 text-sm">
|
||||
@ -251,45 +265,70 @@ const Content_Debug = await createMarkdownComponent(str_debug);
|
||||
data-tabs-inactive-classes="dark:border-transparent text-gray-500 hover:text-gray-600 dark:text-gray-400 border-gray-100 hover:border-gray-300 dark:border-gray-700 dark:hover:text-gray-300"
|
||||
role="tablist"
|
||||
>
|
||||
{SHOW_README && <TabButton title="Overview" />}
|
||||
<TabButton title="Specs" />
|
||||
<TabButton title="Gallery" />
|
||||
<TabButton title="Resources" />
|
||||
{SHOW_SAMPLES && <TabButton title="Samples" />}
|
||||
{SHOW_README && item.readme && <TabButton title="Overview" />}
|
||||
{SHOW_SPECS && <TabButton title="Specs" />}
|
||||
{SHOW_GALLERY && <TabButton title="Gallery" />}
|
||||
{SHOW_RESOURCES && <TabButton title="Resources" />}
|
||||
{
|
||||
SHOW_SAMPLES && item.assets.samples.length > 0 && (
|
||||
<TabButton title="Samples" />
|
||||
)
|
||||
}
|
||||
{SHOW_DEBUG && <TabButton title="Debug" />}
|
||||
</ul>
|
||||
</div>
|
||||
<div id="default-styled-tab-content">
|
||||
<TabContent title="Overview" class="content">
|
||||
{SHOW_README && item.readme && <TabContent title="Overview" class="content">
|
||||
{
|
||||
SHOW_README && item.readme && (
|
||||
(
|
||||
<Readme markdown={item.readme} data={item} />
|
||||
)
|
||||
}
|
||||
</TabContent>
|
||||
<TabContent title="Specs" class="bg-white rounded-xl dark:bg-gray-800 font-mono">
|
||||
}
|
||||
{
|
||||
SHOW_SPECS && (
|
||||
<TabContent
|
||||
title="Specs"
|
||||
class="bg-white rounded-xl dark:bg-gray-800"
|
||||
>
|
||||
<Specs frontmatter={item} />
|
||||
</TabContent>
|
||||
)
|
||||
}
|
||||
{
|
||||
SHOW_GALLERY && (
|
||||
<TabContent title="Gallery" class="p-0 md:p-4 rounded-lg bg-white">
|
||||
<GalleryK images={item.assets.gallery} item={item} />
|
||||
<GalleryK images={item.assets.gallery} item={item} />{" "}
|
||||
</TabContent>
|
||||
)
|
||||
}
|
||||
{
|
||||
SHOW_SAMPLES && (
|
||||
<TabContent title="Samples" class="p-4 bg-white rounded-xl dark:bg-gray-800">
|
||||
<TabContent
|
||||
title="Samples"
|
||||
class="p-4 bg-white rounded-xl dark:bg-gray-800"
|
||||
>
|
||||
<GalleryK images={item.assets.samples} item={item} />
|
||||
</TabContent>
|
||||
)
|
||||
}
|
||||
{
|
||||
SHOW_RESOURCES && (
|
||||
<TabContent title="Resources" class="p-4 bg-white rounded-xl dark:bg-gray-800">
|
||||
<TabContent
|
||||
title="Resources"
|
||||
class="p-4 bg-white rounded-xl dark:bg-gray-800"
|
||||
>
|
||||
<Resources frontmatter={item} />
|
||||
</TabContent>
|
||||
)
|
||||
}
|
||||
{
|
||||
SHOW_DEBUG && (
|
||||
<TabContent title="Debug" class="rounded-lg bg-white p-4 dark:bg-gray-800">
|
||||
<TabContent
|
||||
title="Debug"
|
||||
class="rounded-lg bg-white p-4 dark:bg-gray-800"
|
||||
>
|
||||
<Content_Debug />
|
||||
</TabContent>
|
||||
)
|
||||
@ -332,5 +371,38 @@ const Content_Debug = await createMarkdownComponent(str_debug);
|
||||
});
|
||||
</script>
|
||||
</section>
|
||||
<hr />
|
||||
<h1 aria-hidden="true" class="p-4 text-xs space-x-8"> <Translate>Related</Translate>
|
||||
</h1>
|
||||
{
|
||||
SHOW_RELATED && (
|
||||
<section id="item_related" class="bg-blue-50 p-4 rounded-2xl">
|
||||
{Object.keys(others).map((relKey) => (
|
||||
<section>
|
||||
<h4
|
||||
aria-hidden="true"
|
||||
class="p-4 text-xl text-neutral-500 space-x-8"
|
||||
>
|
||||
{relKey}
|
||||
</h4>
|
||||
<div class="grid sm:grid-cols-4 lg:grid-cols-4 xl:grid-cols-4 gap-2">
|
||||
{others[relKey].map((post) => (
|
||||
<StoreEntries
|
||||
key={post.id}
|
||||
url={`/${Astro.currentLocale}/${view}/${post.id}`}
|
||||
title={post.data.title}
|
||||
price={post.data.price}
|
||||
type={post.data.type}
|
||||
alt={post.data.title}
|
||||
model={post.data}
|
||||
selected={post.id === item.rel}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
</Wrapper>
|
||||
</BaseLayout>
|
||||
|
||||
8
src/middleware.ts
Normal file
8
src/middleware.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { defineMiddleware } from 'astro/middleware';
|
||||
|
||||
export const onRequest = defineMiddleware((context, next) => {
|
||||
if (context.request.url.endsWith('/sitemap.xml')) {
|
||||
return context.redirect('/sitemap-root.xml'); // Ensure direct access
|
||||
}
|
||||
return next();
|
||||
});
|
||||
@ -9,6 +9,7 @@ import { ICADNodeSchema, IComponentConfig } from '@polymech/commons/component'
|
||||
|
||||
import { ContentEntryRenderFunction, ContentEntryType } from 'astro'
|
||||
import { RenderedContent, DataEntry } from "astro:content"
|
||||
|
||||
import type { Loader, LoaderContext } from 'astro/loaders'
|
||||
|
||||
import {
|
||||
@ -26,13 +27,16 @@ import { gallery } from '../base/media.js';
|
||||
import { get } from '@polymech/commons/component'
|
||||
import { PFilterValid } from '@polymech/commons/filter'
|
||||
|
||||
import { IAssemblyData} from '@polymech/cad'
|
||||
import { IAssemblyData } from '@polymech/cad'
|
||||
import { logger as log } from '@/base/index.js'
|
||||
import { translate } from "@/base/i18n.js"
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { slugify } from "@/base/strings.js"
|
||||
|
||||
interface ILoaderContextEx extends LoaderContext {
|
||||
export interface ILoaderContextEx extends LoaderContext {
|
||||
entryTypes: Map<string, ContentEntryType>
|
||||
}
|
||||
interface IComponentConfigEx extends IComponentConfig {
|
||||
export interface IComponentConfigEx extends IComponentConfig {
|
||||
content: string
|
||||
extra_resources?: string
|
||||
shared_resources?: string
|
||||
@ -48,8 +52,7 @@ let loaderCtx: ILoaderContextEx
|
||||
|
||||
const renderFunctionByContentType = new WeakMap<ContentEntryType, ContentEntryRenderFunction>();
|
||||
|
||||
const filterBranch = (items: { rel: string, config, path }[],
|
||||
branch: string = RETAIL_PRODUCT_BRANCH) => {
|
||||
const filterBranch = (items: { rel: string, config, path }[], branch: string) => {
|
||||
if (!PRODUCT_BRANCHES) {
|
||||
return items
|
||||
}
|
||||
@ -60,7 +63,9 @@ const filterBranch = (items: { rel: string, config, path }[],
|
||||
return items.filter((item) => branchItems.includes(item.rel))
|
||||
}
|
||||
|
||||
export const items = (opts: {}) => filterBranch(get(`${PRODUCT_ROOT()}/${PRODUCT_GLOB}`, PRODUCT_ROOT(), PFilterValid.marketplace_component))
|
||||
export const items = (branch: string) =>
|
||||
filterBranch(get(`${PRODUCT_ROOT()}/${PRODUCT_GLOB}`,
|
||||
PRODUCT_ROOT(), PFilterValid.marketplace_component), branch)
|
||||
|
||||
|
||||
const onComponent = async (item: IStoreItem, ctx: ILoaderContextEx) => {
|
||||
@ -163,7 +168,7 @@ const onItem = async (item: IStoreItem, ctx: ILoaderContextEx) => {
|
||||
ctx.logger.error(`Error completing ${''}: no data`);
|
||||
return
|
||||
}
|
||||
if(!loaderCtx){
|
||||
if (!loaderCtx) {
|
||||
loaderCtx = ctx
|
||||
}
|
||||
const { logger } = ctx
|
||||
@ -179,22 +184,10 @@ const onItem = async (item: IStoreItem, ctx: ILoaderContextEx) => {
|
||||
renderings: [],
|
||||
gallery: []
|
||||
}
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
// Body
|
||||
//
|
||||
let contentPath = path.join(itemDir, 'templates/shared', 'body.md')
|
||||
await getRenderFunction(contentPath)
|
||||
if (exists(contentPath)) {
|
||||
data.content = read(contentPath) as string
|
||||
item.filePath = contentPath
|
||||
}
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
// Item Extra Resources
|
||||
//
|
||||
let resourcesPath = path.join(itemDir, 'templates/shared', 'resources.md')
|
||||
exists(resourcesPath) && (data.extra_resources = read(resourcesPath) as string || "")
|
||||
|
||||
data.body = (read(path.join(itemDir, 'templates/shared', 'body.md')) as string) || ""
|
||||
data.resources = (read(path.join(itemDir, 'templates/shared', 'resources.md')) as string) || ""
|
||||
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
// Item Shared Resources
|
||||
@ -203,15 +196,13 @@ const onItem = async (item: IStoreItem, ctx: ILoaderContextEx) => {
|
||||
stopAt: PRODUCT_ROOT(),
|
||||
cwd: itemDir
|
||||
}) || ""
|
||||
exists(resourcesDefaultPath) && (data.shared_resources = read(resourcesDefaultPath) as string || "")
|
||||
data.shared = (read(resourcesDefaultPath) as string) || ""
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
// Readme
|
||||
//
|
||||
let readmePath = path.join(itemDir, 'Readme.md')
|
||||
if (exists(readmePath)) {
|
||||
data.readme = read(readmePath) as string
|
||||
}
|
||||
data.readme = (read(readmePath) as string) || ""
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
// Variables
|
||||
@ -247,18 +238,17 @@ const onItem = async (item: IStoreItem, ctx: ILoaderContextEx) => {
|
||||
data.assets.renderings = await gallery('renderings', data.rel) as []
|
||||
data.assets.renderings.length && (data.thumbnail =
|
||||
{
|
||||
alt: '',
|
||||
url: data.assets.renderings[0].thumb,
|
||||
src: data.assets.renderings[0].thumb
|
||||
alt: data.assets.renderings[0].alt,
|
||||
url: data.assets.renderings[0].url,
|
||||
src: data.assets.renderings[0].url
|
||||
})
|
||||
data.assets.gallery = await gallery('media/gallery', data.rel) as []
|
||||
data.image = data.assets.renderings[0] || {}
|
||||
|
||||
data.assets.showcase = await gallery('media/showcase', data.rel) as []
|
||||
data.assets.samples = await gallery('media/samples', data.rel) as []
|
||||
|
||||
}
|
||||
export function loader(): Loader {
|
||||
|
||||
export function loader(branch: string): Loader {
|
||||
const load = async ({
|
||||
config,
|
||||
logger,
|
||||
@ -269,18 +259,19 @@ export function loader(): Loader {
|
||||
entryTypes }: ILoaderContextEx) => {
|
||||
|
||||
store.clear();
|
||||
let products = items({})
|
||||
let products = items(branch)
|
||||
for (const item of products) {
|
||||
const product: any = item.config
|
||||
const id = product.slug;
|
||||
const data = {
|
||||
rel: item.rel,
|
||||
title: product.name,
|
||||
slug: id,
|
||||
id,
|
||||
title: product.name,
|
||||
type: 'product',
|
||||
highlights: [],
|
||||
components: [],
|
||||
...product
|
||||
...product,
|
||||
}
|
||||
//const parsedData = await parseData({ id, data: data });
|
||||
const storeItem = {
|
||||
@ -298,9 +289,11 @@ export function loader(): Loader {
|
||||
generateDigest,
|
||||
entryTypes
|
||||
} as any)
|
||||
|
||||
storeItem.data['config'] = JSON.stringify({
|
||||
...storeItem.data
|
||||
}, null, 2)
|
||||
|
||||
store.set(storeItem)
|
||||
}
|
||||
}
|
||||
@ -309,3 +302,21 @@ export function loader(): Loader {
|
||||
load
|
||||
};
|
||||
}
|
||||
|
||||
export const group_path = (item) => item.id.split("/")[1]
|
||||
const group_label = async (text: string, locale) => await translate(slugify(text), I18N_SOURCE_LANGUAGE, locale)
|
||||
const group = async (items, locale) => {
|
||||
return items.reduce(async (accPromise, item) => {
|
||||
const acc = await accPromise
|
||||
const id = group_path(item)
|
||||
let key: string = await group_label(id, locale)
|
||||
key = key.charAt(0).toUpperCase() + key.slice(1)
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(item)
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
export const group_by_path = async (items, locale): Promise<IComponentConfigEx[]> => await group(items, locale)
|
||||
@ -59,11 +59,15 @@ export const get = async (node: IComponentNode, component: IComponentConfig, opt
|
||||
url?: string
|
||||
}): Promise<ProductJsonLD> => {
|
||||
|
||||
if(!component.price || !component.body){
|
||||
return {} as any
|
||||
}
|
||||
|
||||
const jsonLD: ProductJsonLD = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Product',
|
||||
name: component.name,
|
||||
description: component.keywords,
|
||||
description: component.body || component.keywords,
|
||||
sku: component.code,
|
||||
brand: {
|
||||
'@type': 'Brand',
|
||||
|
||||
@ -3,16 +3,16 @@ import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
|
||||
import Wrapper from "@/components/containers/Wrapper.astro";
|
||||
import { LANGUAGES_PROD } from "config/config.js";
|
||||
import config from "config/config.json";
|
||||
import { getCollection } from "astro:content";
|
||||
import StoreEntries from "@/components/store/StoreEntries.astro";
|
||||
import CtaOne from "@/components/cta/CtaOne.astro";
|
||||
import { translate } from "@/base/i18n.js"
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { slugify } from "@/base/strings.js"
|
||||
import { group_by_path } from "@/model/component.js";
|
||||
|
||||
const allProducts = await getCollection("store")
|
||||
const locale = Astro.currentLocale
|
||||
const store = `/${locale}/store/`;
|
||||
const view = "store";
|
||||
const items = await getCollection(view);
|
||||
const locale = Astro.currentLocale;
|
||||
const store = `/${locale}/${view}/`;
|
||||
|
||||
export function getStaticPaths() {
|
||||
const all: unknown[] = [];
|
||||
@ -26,38 +26,38 @@ export function getStaticPaths() {
|
||||
});
|
||||
return all;
|
||||
}
|
||||
const group_label = async (text: string) => await translate(slugify(text), I18N_SOURCE_LANGUAGE, locale)
|
||||
const group = async (items) => {
|
||||
return items.reduce(async (accPromise, item: any) => {
|
||||
const acc = await accPromise
|
||||
const id = item.id.split("/")[1]
|
||||
let key:string = (await group_label(id))
|
||||
key = key.charAt(0).toUpperCase() + key.slice(1)
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
const groups = await group_by_path(items, locale);
|
||||
const frontmatter = {
|
||||
title: "Store",
|
||||
description: "Store",
|
||||
keywords: "Store",
|
||||
image:{
|
||||
src: config.pages.home.hero,
|
||||
url: config.pages.home.hero,
|
||||
alt: config.metadata.keywords
|
||||
}
|
||||
acc[key].push(item)
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
const items = await group(allProducts)
|
||||
|
||||
};
|
||||
---
|
||||
<BaseLayout>
|
||||
<Wrapper variant="standard" class="py-4">
|
||||
|
||||
<BaseLayout frontmatter={frontmatter}>
|
||||
<Wrapper variant="standard" class="py-4 font-mono">
|
||||
<CtaOne />
|
||||
<section>
|
||||
<div class="py-2 space-y-2">
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4"></div>
|
||||
</div>
|
||||
</section>
|
||||
{
|
||||
Object.keys(items).map((relKey) => (
|
||||
Object.keys(groups).map((relKey) => (
|
||||
<section>
|
||||
<h1 aria-hidden="true" class="p-4 text-2xl text-neutral-500 space-x-8"> {relKey} </h1>
|
||||
<h3
|
||||
aria-hidden="true"
|
||||
class="p-4 text-xs space-x-8 text-neutral-600"
|
||||
>
|
||||
{relKey}
|
||||
</h3>
|
||||
<div class="grid sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-2 gap-2">
|
||||
{items[relKey].map((post) => (
|
||||
{groups[relKey].map((post) => (
|
||||
<StoreEntries
|
||||
key={post.id}
|
||||
url={store + post.id}
|
||||
|
||||
34
src/pages/[locale]/infopages/[...path].astro
Normal file
34
src/pages/[locale]/infopages/[...path].astro
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content'
|
||||
import { LANGUAGES_PROD as LANGUAGES } from "config/config.js"
|
||||
import InfoPagesLayout from '@/layouts/InfoPagesLayout.astro';
|
||||
export async function getStaticPaths()
|
||||
{
|
||||
const view = 'infopages'
|
||||
const items = await getCollection(view)
|
||||
const all: unknown[] = []
|
||||
LANGUAGES.forEach((lang) => {
|
||||
items.forEach((item) => {
|
||||
all.push({
|
||||
params: {
|
||||
locale: lang,
|
||||
path: item.slug,
|
||||
},
|
||||
props: {
|
||||
page: item,
|
||||
locale: lang,
|
||||
path: item.id,
|
||||
view
|
||||
},
|
||||
trailingSlash: false
|
||||
})
|
||||
})
|
||||
})
|
||||
return all
|
||||
}
|
||||
const { page } = Astro.props;
|
||||
const { Content } = await page.render();
|
||||
---
|
||||
<InfoPagesLayout frontmatter={page.data}>
|
||||
<Content />
|
||||
</InfoPagesLayout>
|
||||
@ -31,5 +31,13 @@ const locale = Astro.currentLocale || "en"
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{ <script>
|
||||
const currentPath = window.location.pathname;
|
||||
if (!/^\/[a-z]{2}(\/|$)/i.test(currentPath)) {
|
||||
let language = navigator.language
|
||||
language = language.split('-')[0]
|
||||
language = "en"
|
||||
window.location.href = `/${language}`;
|
||||
}
|
||||
</script>
|
||||
</BaseLayout>
|
||||
|
||||
13
src/pages/robots.txt.ts
Normal file
13
src/pages/robots.txt.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { APIRoute } from 'astro';
|
||||
|
||||
const getRobotsTxt = (sitemapURL: URL) => `
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: ${sitemapURL.href}
|
||||
`;
|
||||
|
||||
export const GET: APIRoute = ({ site }) => {
|
||||
const sitemapURL = new URL('sitemap-index.xml', site);
|
||||
return new Response(getRobotsTxt(sitemapURL));
|
||||
};
|
||||
24
src/pages/sitemap-root.xml.astro
Normal file
24
src/pages/sitemap-root.xml.astro
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
export async function GET() {
|
||||
console.log('sitemap-index.xml.astro')
|
||||
const locales = ['en', 'es', 'fr'];
|
||||
const baseUrl = 'https://yourdomain.com';
|
||||
|
||||
let sitemaps = locales
|
||||
.map(locale => `<sitemap><loc>${baseUrl}/sitemap-${locale}.xml</loc></sitemap>`)
|
||||
.join('');
|
||||
|
||||
return new Response(
|
||||
`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
${sitemaps}
|
||||
</sitemapindex>`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
---
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/forms";
|
||||
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@layer components {
|
||||
@ -54,6 +54,7 @@
|
||||
.astro-imagetools-img {
|
||||
@apply min-w-full border-collapse rounded-lg overflow-hidden;
|
||||
background-image: none !important;
|
||||
object-fit: contain;
|
||||
}
|
||||
.lightbox-main{
|
||||
background-image: none !important;
|
||||
@ -172,9 +173,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.markdown-content {
|
||||
@apply prose dark:prose-invert max-w-none font-mono;
|
||||
}
|
||||
|
||||
17
sync-polycraft.json
Normal file
17
sync-polycraft.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"debug": true,
|
||||
"matching": [
|
||||
"src/**",
|
||||
"*.md",
|
||||
"*.json",
|
||||
"*.cjs",
|
||||
"docs",
|
||||
"packages/imagetools/**",
|
||||
"scripts",
|
||||
"meta/**",
|
||||
"tests/**",
|
||||
"*.mjs",
|
||||
"!node_modules/**",
|
||||
"!ref/**"
|
||||
]
|
||||
}
|
||||
410
systems/apache/url-redirector/package-lock.json
generated
Normal file
410
systems/apache/url-redirector/package-lock.json
generated
Normal file
@ -0,0 +1,410 @@
|
||||
{
|
||||
"name": "url-redirector",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "url-redirector",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.8.2",
|
||||
"yargs": "^17.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
|
||||
"integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/yargs": {
|
||||
"version": "17.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
|
||||
"integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/yargs-parser": {
|
||||
"version": "21.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
|
||||
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.14.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.8.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
|
||||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
systems/apache/url-redirector/package.json
Normal file
27
systems/apache/url-redirector/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "url-redirector",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"bin": {
|
||||
"url-redirector": "dist/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"run": "node dist/index.js --file=./test.json",
|
||||
"dev": "ts-node --esm src/index.ts",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.8.2",
|
||||
"yargs": "^17.7.2"
|
||||
}
|
||||
}
|
||||
4
systems/apache/url-redirector/test.json
Normal file
4
systems/apache/url-redirector/test.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"/old-page": "/new-page",
|
||||
"https://shop.osr-plastic.org/injection/katbot/": "https://polymech.io/en/store/products/injection/katbot-pro-mega-beta/"
|
||||
}
|
||||
113
systems/apache/url-redirector/tsconfig.json
Normal file
113
systems/apache/url-redirector/tsconfig.json
Normal file
@ -0,0 +1,113 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "libReplacement": true, /* Enable lib replacement. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "NodeNext", /* Specify what module code is generated. */
|
||||
"rootDir": "src", /* Specify the root folder within your source files. */
|
||||
"moduleResolution": "NodeNext", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
// "noUncheckedSideEffectImports": true, /* Check side effect imports. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "dist", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
|
||||
// "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
@ -4,9 +4,9 @@ export default {
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
daisyui: {
|
||||
// Add your daisy ui themes here
|
||||
themes: ["night"],
|
||||
},
|
||||
plugins: [require("daisyui"), require("@tailwindcss/typography")],
|
||||
};
|
||||
plugins: [require("@tailwindcss/typography")],
|
||||
presets: [
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
@ -1 +0,0 @@
|
||||
TEST,TEST
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"glossaryId": "12816437-7e4f-4807-9137-eff9ce324a19",
|
||||
"name": "OSR-en-fr",
|
||||
"ready": true,
|
||||
"sourceLang": "en",
|
||||
"targetLang": "fr",
|
||||
"creationTime": "2025-03-07T12:38:05.401Z",
|
||||
"entryCount": 1,
|
||||
"hash": "zDrlayXO43sB98wNoqof0g=="
|
||||
}
|
||||
10
undefined/glossary/en/pt/index_glossary.json
Normal file
10
undefined/glossary/en/pt/index_glossary.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"glossaryId": "94f02b66-2ee8-4119-a8d7-e0a11dd8992d",
|
||||
"name": "OSR-en-pt",
|
||||
"ready": true,
|
||||
"sourceLang": "en",
|
||||
"targetLang": "pt",
|
||||
"creationTime": "2025-03-11T22:17:00.006Z",
|
||||
"entryCount": 1,
|
||||
"hash": "zDrlayXO43sB98wNoqof0g=="
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user