npm package: @haus-tech/package-size-plugin
Description: Package size plugin for Vendure
Author: Haus Tech
Latest version: 3.0.4

---
name: package-size-plugin
title: Package Size Plugin
description: Vendure plugin that allows you to manage and expose custom package size information for product variants.
version: 3.0.2
---

# Package Size Plugin

This plugin adds package size and optional unit functionality to product variants in Vendure.

## Installation

```bash
yarn add @haus-tech/package-size-plugin
```

## Basic Usage

The plugin must be initialized with configuration options using the `.init()` method:

```typescript
import { VendureConfig } from '@vendure/core'
import { PackageSizePlugin } from '@haus-tech/package-size-plugin'

export const config: VendureConfig = {
  // ... other config
  plugins: [
    PackageSizePlugin.init({
      // Configuration options (see below)
    }),
    // ... other plugins
  ],
}
```

## Configuration Options

### Basic Configuration (Package Size Only)

```typescript
PackageSizePlugin.init({
  // Uses default settings: integer package size, no unit field
})
```

This creates a single custom field:

- `packageSizeInternal`: Integer field with default value `1`

### Float Package Size Support

```typescript
PackageSizePlugin.init({
  packageSizeFieldType: 'float',
})
```

This allows decimal values like `0.5`, `1.25`, `2.75`, etc.

### With Package Size Unit

```typescript
PackageSizePlugin.init({
  usePackageSizeUnit: true,
  defaultUnit: 'kg',
})
```

This adds both fields:

- `packageSizeInternal`: Integer package size
- `packageSizeUnitInternal`: String unit field with text input

### Full Configuration

```typescript
PackageSizePlugin.init({
  packageSizeFieldType: 'float', // Enable decimal values
  usePackageSizeUnit: true, // Enable unit field
  defaultUnit: 'kg', // Set default unit
})
```

## Configuration Reference

| Option                 | Type               | Default | Description                                                              |
| ---------------------- | ------------------ | ------- | ------------------------------------------------------------------------ |
| `packageSizeFieldType` | `'int' \| 'float'` | `'int'` | Data type for package size field                                         |
| `usePackageSizeUnit`   | `boolean`          | `false` | Whether to include the unit field                                        |
| `defaultUnit`          | `string`           | `'st'`  | Default value for unit field (only used if `usePackageSizeUnit` is true) |

## GraphQL API

The plugin dynamically adds fields to the ProductVariant type based on your configuration:

### Integer Package Size Only

```graphql
type ProductVariant {
  packageSize: Int
}
```

### Float Package Size with Unit

```graphql
type ProductVariant {
  packageSize: Float
  packageSizeUnit: String
}
```

## Migration from Previous Versions

If you were using this plugin without the `.init()` method, you'll need to update your configuration:

**Before:**

```typescript
plugins: [PackageSizePlugin]
```

**After:**

```typescript
plugins: [
  PackageSizePlugin.init({
    // Add your desired configuration
    packageSizeFieldType: 'int', // or 'float'
    usePackageSizeUnit: false, // or true if you want units
  }),
]
```

## Database Migration

When changing `packageSizeFieldType` from `'int'` to `'float'`, you'll need to create a database migration:

```bash
npx vendure migration:generate update-package-size-to-float
npx vendure migration:run
```

## Elasticsearch Integration

If you're using Elasticsearch, configure the mappings based on your field type:

### For Integer Package Size

```typescript
const elasticSearchConfig: ElasticsearchOptions = {
  // ... other config
  indexMappingProperties: {
    'variant-packageSize': { type: 'integer' },
    'variant-packageSizeUnit': { type: 'keyword' }, // if using units
  },
  customProductVariantMappings: {
    packageSize: {
      graphQlType: 'Int!',
      valueFn: async (productVariant: ProductVariant) => {
        return productVariant.customFields.packageSizeInternal ?? 1
      },
    },
    packageSizeUnit: {
      // if using units
      graphQlType: 'String!',
      valueFn: async (productVariant: ProductVariant) => {
        return productVariant.customFields.packageSizeUnitInternal ?? 'st'
      },
    },
  },
}
```

### For Float Package Size

```typescript
const elasticSearchConfig: ElasticsearchOptions = {
  // ... other config
  indexMappingProperties: {
    'variant-packageSize': { type: 'float' },
    'variant-packageSizeUnit': { type: 'keyword' }, // if using units
  },
  customProductVariantMappings: {
    packageSize: {
      graphQlType: 'Float!',
      valueFn: async (productVariant: ProductVariant) => {
        return productVariant.customFields.packageSizeInternal ?? 1.0
      },
    },
    packageSizeUnit: {
      // if using units
      graphQlType: 'String!',
      valueFn: async (productVariant: ProductVariant) => {
        return productVariant.customFields.packageSizeUnitInternal ?? 'st'
      },
    },
  },
}
```

## Use Cases

The Package Size Plugin is ideal for:

- E-commerce platforms that require detailed package size information for logistics and shipping calculations.
- Businesses that need to expose package size data to customers or third-party systems via the shop API.
- Scenarios where Elasticsearch is used to index and search for product variant data, including package sizes.

## Example GraphQL Query

You can query the `packageSize` field using the shop API:

```graphql
query {
  product(id: "1") {
    variants {
      id
      name
      packageSize
      packageSizeUnit # if using units
    }
  }
}
```

## Testing

1. Run `yarn test` to execute the e2e tests.
2. Implement additional tests to cover your specific use cases.

## Publishing to NPM

1. Make sure you are [logged in to NPM](https://docs.npmjs.com/cli/v9/commands/npm-login).
2. Build the plugin:

   ```bash
   yarn build
   ```

3. Publish the plugin:

   ```bash
   yarn publish
   ```

## Features

- ✅ Configurable package size field type (integer or float)
- ✅ Optional package size unit field
- ✅ Dynamic GraphQL schema generation
- ✅ Elasticsearch integration support
- ✅ Multi-language labels (English/Swedish)
- ✅ TypeScript support
- ✅ Backward compatibility with migration path

## Resources

- [Vendure Plugin Documentation](https://www.vendure.io/docs/plugins/)
- [GraphQL Code Generator](https://the-guild.dev/graphql/codegen) for generating TypeScript types for custom GraphQL types.