@haus-tech/package-size-plugin 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,36 +1,204 @@
1
- # Vendure plugin template
1
+ # Package Size Plugin for Vendure
2
2
 
3
- 1. Copy this directory and rename to `vendure-plugin-YOUR-PLUGIN-NAME`
4
- 2. Update the `name` and `description` field in `package.json`
5
- 4. Update this Readme: What does the plugin do? How can someone use your plugin in their project?
6
- 5. Run `yarn` to install the dependencies
7
- 6. Run `yarn start` to start the server
3
+ This plugin adds package size and optional unit functionality to product variants in Vendure.
8
4
 
9
- The admin is now available at `http://localhost:3050/admin`. Login with _superadmin/superadmin_
5
+ ## Installation
6
+
7
+ ```bash
8
+ yarn add @haus-tech/package-size-plugin
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ The plugin must be initialized with configuration options using the `.init()` method:
14
+
15
+ ```typescript
16
+ import { VendureConfig } from '@vendure/core'
17
+ import { PackageSizePlugin } from '@haus-tech/package-size-plugin'
18
+
19
+ export const config: VendureConfig = {
20
+ // ... other config
21
+ plugins: [
22
+ PackageSizePlugin.init({
23
+ // Configuration options (see below)
24
+ }),
25
+ // ... other plugins
26
+ ],
27
+ }
28
+ ```
29
+
30
+ ## Configuration Options
31
+
32
+ ### Basic Configuration (Package Size Only)
33
+
34
+ ```typescript
35
+ PackageSizePlugin.init({
36
+ // Uses default settings: integer package size, no unit field
37
+ })
38
+ ```
39
+
40
+ This creates a single custom field:
41
+
42
+ - `packageSizeInternal`: Integer field with default value `1`
43
+
44
+ ### Float Package Size Support
45
+
46
+ ```typescript
47
+ PackageSizePlugin.init({
48
+ packageSizeFieldType: 'float',
49
+ })
50
+ ```
51
+
52
+ This allows decimal values like `0.5`, `1.25`, `2.75`, etc.
53
+
54
+ ### With Package Size Unit
55
+
56
+ ```typescript
57
+ PackageSizePlugin.init({
58
+ usePackageSizeUnit: true,
59
+ defaultUnit: 'kg',
60
+ })
61
+ ```
62
+
63
+ This adds both fields:
64
+
65
+ - `packageSizeInternal`: Integer package size
66
+ - `packageSizeUnitInternal`: String unit field with text input
67
+
68
+ ### Full Configuration
69
+
70
+ ```typescript
71
+ PackageSizePlugin.init({
72
+ packageSizeFieldType: 'float', // Enable decimal values
73
+ usePackageSizeUnit: true, // Enable unit field
74
+ defaultUnit: 'kg', // Set default unit
75
+ })
76
+ ```
77
+
78
+ ## Configuration Reference
79
+
80
+ | Option | Type | Default | Description |
81
+ | ---------------------- | ------------------ | ------- | ------------------------------------------------------------------------ |
82
+ | `packageSizeFieldType` | `'int' \| 'float'` | `'int'` | Data type for package size field |
83
+ | `usePackageSizeUnit` | `boolean` | `false` | Whether to include the unit field |
84
+ | `defaultUnit` | `string` | `'st'` | Default value for unit field (only used if `usePackageSizeUnit` is true) |
85
+
86
+ ## GraphQL API
87
+
88
+ The plugin dynamically adds fields to the ProductVariant type based on your configuration:
89
+
90
+ ### Integer Package Size Only
10
91
 
11
- The shop GraphQL `http://localhost:3050/shop-api`. Here you can test your custom GraphQL query:
12
92
  ```graphql
13
- {
14
- exampleQuery
93
+ type ProductVariant {
94
+ packageSize: Int
15
95
  }
16
96
  ```
17
97
 
18
- ## Testing
98
+ ### Float Package Size with Unit
99
+
100
+ ```graphql
101
+ type ProductVariant {
102
+ packageSize: Float
103
+ packageSizeUnit: String
104
+ }
105
+ ```
106
+
107
+ ## Migration from Previous Versions
108
+
109
+ If you were using this plugin without the `.init()` method, you'll need to update your configuration:
110
+
111
+ **Before:**
112
+
113
+ ```typescript
114
+ plugins: [PackageSizePlugin]
115
+ ```
116
+
117
+ **After:**
118
+
119
+ ```typescript
120
+ plugins: [
121
+ PackageSizePlugin.init({
122
+ // Add your desired configuration
123
+ packageSizeFieldType: 'int', // or 'float'
124
+ usePackageSizeUnit: false, // or true if you want units
125
+ }),
126
+ ]
127
+ ```
19
128
 
20
- 1. Run `yarn test` to run the e2e test.
21
- 2. Don't forget to implement your own!
129
+ ## Database Migration
130
+
131
+ When changing `packageSizeFieldType` from `'int'` to `'float'`, you'll need to create a database migration:
132
+
133
+ ```bash
134
+ npx vendure migration:generate update-package-size-to-float
135
+ npx vendure migration:run
136
+ ```
22
137
 
23
- ## Publishing to NPM
138
+ ## Elasticsearch Integration
24
139
 
25
- 1. Make sure you are [logged in to NPM](https://docs.npmjs.com/cli/v9/commands/npm-login)
26
- 2. `yarn build`
27
- 3. `yarn publish`
140
+ If you're using Elasticsearch, configure the mappings based on your field type:
28
141
 
29
- That's it!
142
+ ### For Integer Package Size
30
143
 
31
- (Maybe share your accomplishments in the [Vendure slack](https://join.slack.com/t/vendure-ecommerce/shared_invite/zt-1exzio25w-vjL5TYkyJZjK52d6jkOsIA)?
144
+ ```typescript
145
+ const elasticSearchConfig: ElasticsearchOptions = {
146
+ // ... other config
147
+ indexMappingProperties: {
148
+ 'variant-packageSize': { type: 'integer' },
149
+ 'variant-packageSizeUnit': { type: 'keyword' }, // if using units
150
+ },
151
+ customProductVariantMappings: {
152
+ packageSize: {
153
+ graphQlType: 'Int!',
154
+ valueFn: async (productVariant: ProductVariant) => {
155
+ return productVariant.customFields.packageSizeInternal ?? 1
156
+ },
157
+ },
158
+ packageSizeUnit: {
159
+ // if using units
160
+ graphQlType: 'String!',
161
+ valueFn: async (productVariant: ProductVariant) => {
162
+ return productVariant.customFields.packageSizeUnitInternal ?? 'st'
163
+ },
164
+ },
165
+ },
166
+ }
167
+ ```
168
+
169
+ ### For Float Package Size
170
+
171
+ ```typescript
172
+ const elasticSearchConfig: ElasticsearchOptions = {
173
+ // ... other config
174
+ indexMappingProperties: {
175
+ 'variant-packageSize': { type: 'float' },
176
+ 'variant-packageSizeUnit': { type: 'keyword' }, // if using units
177
+ },
178
+ customProductVariantMappings: {
179
+ packageSize: {
180
+ graphQlType: 'Float!',
181
+ valueFn: async (productVariant: ProductVariant) => {
182
+ return productVariant.customFields.packageSizeInternal ?? 1.0
183
+ },
184
+ },
185
+ packageSizeUnit: {
186
+ // if using units
187
+ graphQlType: 'String!',
188
+ valueFn: async (productVariant: ProductVariant) => {
189
+ return productVariant.customFields.packageSizeUnitInternal ?? 'st'
190
+ },
191
+ },
192
+ },
193
+ }
194
+ ```
32
195
 
33
- ## Next steps
196
+ ## Features
34
197
 
35
- 1. Check out [the docs](https://www.vendure.io/docs/plugins/) to see the possibilities of a plugin
36
- 2. Check out [GraphQL codegen](https://the-guild.dev/graphql/codegen) to generate Typescript types for your custom GraphQL types
198
+ - Configurable package size field type (integer or float)
199
+ - Optional package size unit field
200
+ - ✅ Dynamic GraphQL schema generation
201
+ - ✅ Elasticsearch integration support
202
+ - ✅ Multi-language labels (English/Swedish)
203
+ - ✅ TypeScript support
204
+ - ✅ Backward compatibility with migration path
@@ -1 +1 @@
1
- export declare const shopApiExtensions: import("graphql").DocumentNode;
1
+ export declare const getShopApiExtensions: (packageSizeFieldType: "int" | "float") => import("graphql").DocumentNode;
@@ -3,10 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.shopApiExtensions = void 0;
6
+ exports.getShopApiExtensions = void 0;
7
7
  const graphql_tag_1 = __importDefault(require("graphql-tag"));
8
- exports.shopApiExtensions = (0, graphql_tag_1.default) `
9
- extend type ProductVariant {
10
- packageSize: Int
11
- }
12
- `;
8
+ const getShopApiExtensions = (packageSizeFieldType) => {
9
+ const packageSizeType = packageSizeFieldType === 'float' ? 'Float' : 'Int';
10
+ return (0, graphql_tag_1.default) `
11
+ extend type ProductVariant {
12
+ packageSize: ${packageSizeType}
13
+ packageSizeUnit: String
14
+ }
15
+ `;
16
+ };
17
+ exports.getShopApiExtensions = getShopApiExtensions;
@@ -2,4 +2,5 @@ import { RequestContext, ProductVariant } from '@vendure/core';
2
2
  export declare class ProductVariantEntityResolver {
3
3
  constructor();
4
4
  packageSize(ctx: RequestContext, variant: ProductVariant): number;
5
+ packageSizeUnit(ctx: RequestContext, variant: ProductVariant): string;
5
6
  }
@@ -20,7 +20,11 @@ let ProductVariantEntityResolver = class ProductVariantEntityResolver {
20
20
  packageSize(ctx, variant) {
21
21
  return variant.customFields.packageSizeInternal || 1;
22
22
  }
23
+ packageSizeUnit(ctx, variant) {
24
+ return variant.customFields.packageSizeUnitInternal || 'st';
25
+ }
23
26
  };
27
+ exports.ProductVariantEntityResolver = ProductVariantEntityResolver;
24
28
  __decorate([
25
29
  (0, graphql_1.ResolveField)(),
26
30
  __param(0, (0, core_1.Ctx)()),
@@ -29,8 +33,15 @@ __decorate([
29
33
  __metadata("design:paramtypes", [core_1.RequestContext, core_1.ProductVariant]),
30
34
  __metadata("design:returntype", void 0)
31
35
  ], ProductVariantEntityResolver.prototype, "packageSize", null);
32
- ProductVariantEntityResolver = __decorate([
36
+ __decorate([
37
+ (0, graphql_1.ResolveField)(),
38
+ __param(0, (0, core_1.Ctx)()),
39
+ __param(1, (0, graphql_1.Parent)()),
40
+ __metadata("design:type", Function),
41
+ __metadata("design:paramtypes", [core_1.RequestContext, core_1.ProductVariant]),
42
+ __metadata("design:returntype", void 0)
43
+ ], ProductVariantEntityResolver.prototype, "packageSizeUnit", null);
44
+ exports.ProductVariantEntityResolver = ProductVariantEntityResolver = __decorate([
33
45
  (0, graphql_1.Resolver)('ProductVariant'),
34
46
  __metadata("design:paramtypes", [])
35
47
  ], ProductVariantEntityResolver);
36
- exports.ProductVariantEntityResolver = ProductVariantEntityResolver;
@@ -1,10 +1,26 @@
1
+ import { LanguageCode, Type } from '@vendure/core';
2
+ export interface PackageSizeUnit {
3
+ value: string;
4
+ label: {
5
+ languageCode: LanguageCode;
6
+ value: string;
7
+ }[];
8
+ }
9
+ export interface PackageSizePluginConfig {
10
+ defaultUnit?: string;
11
+ packageSizeFieldType?: 'int' | 'float';
12
+ usePackageSizeUnit?: boolean;
13
+ }
1
14
  declare module '@vendure/core' {
2
15
  interface CustomProductVariantFields {
3
16
  packageSizeInternal: number;
17
+ packageSizeUnitInternal: string;
4
18
  }
5
19
  interface ProductVariant {
6
20
  packageSize: number;
21
+ packageSizeUnit: string;
7
22
  }
8
23
  }
9
24
  export declare class PackageSizePlugin {
25
+ static init(config: PackageSizePluginConfig): Type<any>;
10
26
  }
@@ -10,29 +10,53 @@ exports.PackageSizePlugin = void 0;
10
10
  const core_1 = require("@vendure/core");
11
11
  const api_extensions_1 = require("./api/api-extensions");
12
12
  const package_size_resolver_1 = require("./api/package-size.resolver");
13
- let PackageSizePlugin = class PackageSizePlugin {
14
- };
15
- PackageSizePlugin = __decorate([
16
- (0, core_1.VendurePlugin)({
17
- imports: [core_1.PluginCommonModule],
18
- shopApiExtensions: {
19
- resolvers: [package_size_resolver_1.ProductVariantEntityResolver],
20
- schema: api_extensions_1.shopApiExtensions,
21
- },
22
- configuration: (config) => {
23
- config.customFields.ProductVariant.push({
24
- name: 'packageSizeInternal',
25
- type: 'int',
26
- defaultValue: 1,
27
- public: false,
28
- label: [
29
- { languageCode: core_1.LanguageCode.en, value: 'Package Size' },
30
- { languageCode: core_1.LanguageCode.sv, value: 'Förpackningsstorlek' },
31
- ],
32
- });
33
- return config;
34
- },
35
- compatibility: '^3.0.0',
36
- })
37
- ], PackageSizePlugin);
13
+ class PackageSizePlugin {
14
+ static init(config) {
15
+ const fieldType = config.packageSizeFieldType || 'int';
16
+ const usePackageSizeUnit = config.usePackageSizeUnit || false;
17
+ let DynamicPackageSizePlugin = class DynamicPackageSizePlugin {
18
+ };
19
+ DynamicPackageSizePlugin = __decorate([
20
+ (0, core_1.VendurePlugin)({
21
+ imports: [core_1.PluginCommonModule],
22
+ shopApiExtensions: {
23
+ resolvers: [package_size_resolver_1.ProductVariantEntityResolver],
24
+ schema: (0, api_extensions_1.getShopApiExtensions)(fieldType),
25
+ },
26
+ configuration: (vendureConfig) => {
27
+ const defaultUnit = config.defaultUnit || 'st';
28
+ const defaultValue = fieldType === 'float' ? 1.0 : 1;
29
+ vendureConfig.customFields.ProductVariant.push({
30
+ name: 'packageSizeInternal',
31
+ type: fieldType,
32
+ defaultValue: defaultValue,
33
+ public: false,
34
+ label: [
35
+ { languageCode: core_1.LanguageCode.en, value: 'Package Size' },
36
+ { languageCode: core_1.LanguageCode.sv, value: 'Förpackningsstorlek' },
37
+ ],
38
+ });
39
+ if (usePackageSizeUnit) {
40
+ vendureConfig.customFields.ProductVariant.push({
41
+ name: 'packageSizeUnitInternal',
42
+ type: 'string',
43
+ defaultValue: defaultUnit,
44
+ ui: {
45
+ component: 'text-form-input',
46
+ },
47
+ public: false,
48
+ label: [
49
+ { languageCode: core_1.LanguageCode.en, value: 'Package Size Unit' },
50
+ { languageCode: core_1.LanguageCode.sv, value: 'Förpackningsenhet' },
51
+ ],
52
+ });
53
+ }
54
+ return vendureConfig;
55
+ },
56
+ compatibility: '^3.0.0',
57
+ })
58
+ ], DynamicPackageSizePlugin);
59
+ return DynamicPackageSizePlugin;
60
+ }
61
+ }
38
62
  exports.PackageSizePlugin = PackageSizePlugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haus-tech/package-size-plugin",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Package size plugin for Vendure",
5
5
  "author": "Haus Tech",
6
6
  "repository": {