@shopware-ag/storefront-types 0.1.1 → 0.2.0

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,18 +1,20 @@
1
1
  # Types for Shopware Storefront
2
2
 
3
- This package provides types for window bound classes in Shopware 6 Storefront:
3
+ This package provides types for window-bound classes in Shopware 6 Storefront:
4
4
 
5
5
  - `window.PluginManager`
6
6
  - `window.PluginBaseClass`
7
7
  - `window.router`
8
8
 
9
+ and all regular imports of the Storefront.
10
+
9
11
  Install this package with NPM:
10
12
 
11
13
  ```bash
12
14
  npm install @shopware-ag/storefront-types --save-dev
13
15
  ```
14
16
 
15
- To hav the types active, you need to create a `tsconfig.json` (`src/Resources/app/storefront/tsconfig.json`) with following content:
17
+ To have the types active, you need to create a `tsconfig.json` (`src/Resources/app/storefront/tsconfig.json`) with the following content:
16
18
 
17
19
  ```json
18
20
  {
@@ -21,3 +23,29 @@ To hav the types active, you need to create a `tsconfig.json` (`src/Resources/ap
21
23
  }
22
24
  }
23
25
  ```
26
+
27
+ ## Typed Plugin Options
28
+
29
+ You can use a generic type parameter to get fully typed options in your plugins:
30
+
31
+ ```ts
32
+ const { PluginBaseClass } = window;
33
+
34
+ interface MyPluginOptions {
35
+ option1: string;
36
+ option2: number | null;
37
+ }
38
+
39
+ export default class MyPlugin extends PluginBaseClass<MyPluginOptions> {
40
+ static options: MyPluginOptions = {
41
+ option1: 'default value',
42
+ option2: null
43
+ };
44
+
45
+ init() {
46
+ // this.options is fully typed
47
+ console.log(this.options.option1); // string
48
+ console.log(this.options.option2); // number | null
49
+ }
50
+ }
51
+ ```
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@shopware-ag/storefront-types",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Provides Shopware Storefront Typescript types",
5
5
  "types": "index.d.ts",
6
+ "scripts": {
7
+ "test": "tsc --project tsconfig.test.json"
8
+ },
6
9
  "dependencies": {
7
10
  "@types/bootstrap": "^5.2.0"
8
11
  },
@@ -15,6 +15,12 @@ export default interface PluginManager {
15
15
  */
16
16
  extend(fromName: String, newName: string, pluginClass: Object, selector: String | NodeList | HTMLElement, options?: Object): boolean
17
17
 
18
+ /**
19
+ * Overrides an existing plugin with a new class.
20
+ * This is a convenience wrapper around extend() that uses the same name for both fromName and newName.
21
+ */
22
+ override(overrideName: String, pluginClass: Object, selector: String | NodeList | HTMLElement, options?: Object): boolean
23
+
18
24
  /**
19
25
  * Returns a list of all registered plugins.
20
26
  */
@@ -1,19 +1,19 @@
1
1
  import NativeEventEmitter from "./native-event-emitter";
2
2
 
3
- export default interface PluginBaseClass {
4
- new(el: HTMLElement, options?: any, pluginName?: false | string): PluginBaseClass;
3
+ export default interface PluginBaseClass<Options extends object = Record<string, unknown>> {
4
+ new(el: HTMLElement, options?: Partial<Options>, pluginName?: false | string): PluginBaseClass<Options>;
5
5
 
6
6
  el: HTMLElement;
7
7
  $emitter: NativeEventEmitter;
8
8
  _pluginName: String;
9
- initialOptions: object;
10
- options: object;
9
+ initialOptions: Options;
10
+ options: Options;
11
11
  _initialized: boolean;
12
12
  init(): void;
13
13
  _update(): void;
14
14
  update(): void;
15
15
  _registerInstance(): void;
16
16
  _getPluginName(pluginName: false | string): String;
17
- _mergeOptions(options: any): object;
17
+ _mergeOptions(options: Partial<Options>): Options;
18
18
  parseJsonOrFail(dashedPluginName: string): any | string;
19
19
  }
@@ -0,0 +1,49 @@
1
+ import type PluginBaseClass from '../plugin-system/plugin';
2
+
3
+ // Test: Generic with custom options type
4
+ interface MyPluginOptions {
5
+ option1: string;
6
+ option2: number | null;
7
+ nested: {
8
+ value: boolean;
9
+ };
10
+ }
11
+
12
+ declare const myPlugin: PluginBaseClass<MyPluginOptions>;
13
+
14
+ // Test: options should be typed correctly
15
+ const opt1: string = myPlugin.options.option1;
16
+ const opt2: number | null = myPlugin.options.option2;
17
+ const nestedVal: boolean = myPlugin.options.nested.value;
18
+
19
+ // Test: initialOptions should also be typed
20
+ const initOpt1: string = myPlugin.initialOptions.option1;
21
+
22
+ // Test: _mergeOptions should accept Partial<Options> and return Options
23
+ const merged: MyPluginOptions = myPlugin._mergeOptions({ option1: 'test' });
24
+ const mergedEmpty: MyPluginOptions = myPlugin._mergeOptions({});
25
+
26
+ // Test: Default generic (backwards compatibility)
27
+ declare const defaultPlugin: PluginBaseClass;
28
+
29
+ // Default plugin options should be Record<string, unknown>
30
+ const defaultOpt: unknown = defaultPlugin.options['anyKey'];
31
+ const defaultInitOpt: unknown = defaultPlugin.initialOptions['anyKey'];
32
+
33
+ // Test: Constructor options parameter should accept Partial<Options>
34
+ declare const PluginClass: PluginBaseClass<MyPluginOptions>;
35
+ declare const element: HTMLElement;
36
+ const instance = new PluginClass(element, { option1: 'partial' });
37
+ const instanceNoOpts = new PluginClass(element);
38
+
39
+ // @ts-expect-error - Should error when accessing non-existent property on typed options
40
+ myPlugin.options.nonExistent;
41
+
42
+ // @ts-expect-error - Should error when assigning wrong type
43
+ const wrongType: number = myPlugin.options.option1;
44
+
45
+ // @ts-expect-error - Should error when passing wrong option type to constructor
46
+ new PluginClass(element, { option1: 123 });
47
+
48
+ // @ts-expect-error - Should error when passing unknown option to constructor
49
+ new PluginClass(element, { unknownOption: 'value' });
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "lib": [
5
+ "es6",
6
+ "DOM"
7
+ ],
8
+ "noImplicitAny": true,
9
+ "noImplicitThis": true,
10
+ "strictNullChecks": true,
11
+ "strictFunctionTypes": true,
12
+ "noEmit": true,
13
+ "forceConsistentCasingInFileNames": true
14
+ },
15
+ "include": [
16
+ "tests/**/*.test-d.ts"
17
+ ]
18
+ }
@@ -1,32 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- release:
5
- types: [created]
6
-
7
- jobs:
8
- publish-npm:
9
- runs-on: ubuntu-latest
10
- permissions:
11
- contents: read
12
- id-token: write
13
- steps:
14
- - name: Checkout
15
- uses: actions/checkout@v4
16
-
17
- - name: Install Node 20.x
18
- uses: actions/setup-node@v3
19
- with:
20
- node-version: '20.x'
21
- registry-url: 'https://registry.npmjs.org'
22
-
23
- - name: Change version
24
- run: |
25
- jq '.version = "${{ github.ref_name }}"' package.json > package.new.json
26
- cp package.new.json package.json
27
- rm package.new.json
28
-
29
- - name: Release package
30
- run: npm publish --provenance --access public
31
- env:
32
- NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
package/bun.lockb DELETED
Binary file