@fakeware/plugin-pickware 0.0.1
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 +140 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.mjs +37 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @fakeware/plugin-pickware
|
|
2
|
+
|
|
3
|
+
A [fakeware](https://github.com/fakeware-sh/fakeware) plugin for **Pickware ERP** —
|
|
4
|
+
seed warehouses, bin locations, and stock into a Shopware 6 shop running Pickware.
|
|
5
|
+
|
|
6
|
+
It teaches fakeware about Pickware's DAL entities so you can author them with
|
|
7
|
+
`define(...)` in your data files, and contributes a fetcher that loads the shop's
|
|
8
|
+
existing warehouses into the run context.
|
|
9
|
+
|
|
10
|
+
> **Status: minimal v1.** Covers `pickware_erp_warehouse`, `pickware_erp_bin_location`,
|
|
11
|
+
> and `pickware_erp_stock_movement`. Suppliers, purchasing, stocktakes, and the
|
|
12
|
+
> WMS/POS/Shipping entities are intentionally out of scope for now.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
bun add -D @fakeware/plugin-pickware
|
|
18
|
+
# @fakeware/core is a peer dependency — your fakeware project already has it.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
Register the plugin in `fakeware.config.ts`:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { defineConfig } from '@fakeware/core/config'
|
|
27
|
+
import { pickware } from '@fakeware/plugin-pickware'
|
|
28
|
+
|
|
29
|
+
export default defineConfig({
|
|
30
|
+
shopware: {
|
|
31
|
+
url: process.env.SHOPWARE_URL!,
|
|
32
|
+
clientId: process.env.SHOPWARE_CLIENT_ID!,
|
|
33
|
+
clientSecret: process.env.SHOPWARE_CLIENT_SECRET!,
|
|
34
|
+
},
|
|
35
|
+
plugins: [pickware()],
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Author Pickware data in `data/*.ts`. Importing the package augments fakeware's
|
|
40
|
+
`EntityRegistry`, so the `pickware_erp_*` entity names are fully type-checked:
|
|
41
|
+
|
|
42
|
+
`data/pickware.ts`:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { define, ref } from '@fakeware/core'
|
|
46
|
+
import { stockMovementIn } from '@fakeware/plugin-pickware'
|
|
47
|
+
|
|
48
|
+
define('pickware_erp_warehouse', { $key: 'main', name: 'Main', code: 'WH-01' })
|
|
49
|
+
|
|
50
|
+
define('pickware_erp_bin_location', {
|
|
51
|
+
$key: 'a1',
|
|
52
|
+
code: 'A1',
|
|
53
|
+
warehouseId: ref('pickware_erp_warehouse/main'),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
define(
|
|
57
|
+
'pickware_erp_stock_movement',
|
|
58
|
+
stockMovementIn({
|
|
59
|
+
productId: ref('product/my-product'),
|
|
60
|
+
warehouseId: ref('pickware_erp_warehouse/main'),
|
|
61
|
+
quantity: 100,
|
|
62
|
+
}),
|
|
63
|
+
)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Bin locations referencing a warehouse via `ref()` are written after it
|
|
67
|
+
automatically. Seed stock through `pickware_erp_stock_movement` (an append-only
|
|
68
|
+
ledger) — never write `product.stock` directly while Pickware is active.
|
|
69
|
+
|
|
70
|
+
Run it with the fakeware CLI:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
fakeware up --dry-run
|
|
74
|
+
fakeware up
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Referencing existing warehouses
|
|
78
|
+
|
|
79
|
+
`pickware()` adds a fetcher that loads the shop's current warehouses into the run
|
|
80
|
+
context. Read them in a plugin `setup` hook or any code with access to the context:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { pickwareWarehouses } from '@fakeware/plugin-pickware'
|
|
84
|
+
|
|
85
|
+
const existing = pickwareWarehouses(shopContext.extensions)
|
|
86
|
+
const main = existing.find((w) => w.code === 'WH-01')
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## ⚠️ Verify field names against your install
|
|
90
|
+
|
|
91
|
+
Pickware publishes **no Shopware 6 API documentation**, so the entity *field
|
|
92
|
+
names* in this plugin (especially `destinationWarehouseId` on the stock movement)
|
|
93
|
+
are best-effort. **Before a live `up`, confirm them against your shop:**
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
curl -H "Authorization: Bearer <token>" \
|
|
97
|
+
https://your-shop.example/api/_info/entity-schema.json \
|
|
98
|
+
| jq 'keys | map(select(startswith("pickware_erp")))'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Inspect the `pickware_erp_warehouse`, `pickware_erp_bin_location`, and
|
|
102
|
+
`pickware_erp_stock_movement` field definitions there (or watch the Pickware
|
|
103
|
+
admin module's network requests) and adjust the record shapes in
|
|
104
|
+
`src/entities.ts` / the `stockMovementIn` helper to match.
|
|
105
|
+
|
|
106
|
+
Key facts the plugin is built around:
|
|
107
|
+
|
|
108
|
+
- Stock is owned by Pickware's **append-only ledger** (`pickware_erp_stock_movement`).
|
|
109
|
+
You change stock by **adding movements**; Pickware recomputes
|
|
110
|
+
`pickware_erp_stock` and mirrors the total back into `product.stock`.
|
|
111
|
+
- Writing `product.stock` directly via the standard API while Pickware is active
|
|
112
|
+
**nulls** the Pickware warehouses — don't do it.
|
|
113
|
+
|
|
114
|
+
## Publishing
|
|
115
|
+
|
|
116
|
+
This repo publishes `@fakeware/plugin-pickware` to npm via
|
|
117
|
+
[release-please](https://github.com/googleapis/release-please) — the same flow as
|
|
118
|
+
the fakeware monorepo. Conventional commits on `main` open a release PR; merging
|
|
119
|
+
it tags a version and publishes.
|
|
120
|
+
|
|
121
|
+
**One-time repo setup** (in GitHub → Settings):
|
|
122
|
+
|
|
123
|
+
- Add an npm publish credential for the `@fakeware` scope. The release workflow
|
|
124
|
+
uses npm provenance (`id-token: write`) — configure a trusted publisher on npm,
|
|
125
|
+
or add an `NPM_TOKEN` secret and wire it into `.github/workflows/release.yml`.
|
|
126
|
+
- The default `GITHUB_TOKEN` is sufficient for release-please's PR/tagging.
|
|
127
|
+
|
|
128
|
+
## Development
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
bun install
|
|
132
|
+
bun run build
|
|
133
|
+
bun run typecheck
|
|
134
|
+
bun test
|
|
135
|
+
bun run check
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FakewarePlugin, ShopContextFetcher } from "@fakeware/core";
|
|
2
|
+
|
|
3
|
+
//#region src/entities.d.ts
|
|
4
|
+
interface PickwareWarehouseRecord {
|
|
5
|
+
$key?: string;
|
|
6
|
+
name: string;
|
|
7
|
+
code: string;
|
|
8
|
+
}
|
|
9
|
+
interface PickwareBinLocationRecord {
|
|
10
|
+
$key?: string;
|
|
11
|
+
code: string;
|
|
12
|
+
warehouseId: string;
|
|
13
|
+
}
|
|
14
|
+
interface PickwareStockMovementRecord {
|
|
15
|
+
$key?: string;
|
|
16
|
+
productId: string;
|
|
17
|
+
quantity: number;
|
|
18
|
+
destinationWarehouseId: string;
|
|
19
|
+
}
|
|
20
|
+
declare module '@fakeware/core' {
|
|
21
|
+
interface EntityRegistry {
|
|
22
|
+
pickware_erp_warehouse: PickwareWarehouseRecord;
|
|
23
|
+
pickware_erp_bin_location: PickwareBinLocationRecord;
|
|
24
|
+
pickware_erp_stock_movement: PickwareStockMovementRecord;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/fetchers.d.ts
|
|
29
|
+
interface PickwareWarehouseRow {
|
|
30
|
+
id: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
code?: string;
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
declare const PICKWARE_WAREHOUSES_KEY = "pickwareWarehouses";
|
|
36
|
+
declare function pickwareWarehouses(extensions: Record<string, unknown>): PickwareWarehouseRow[];
|
|
37
|
+
declare const warehousesFetcher: ShopContextFetcher;
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/helpers.d.ts
|
|
40
|
+
interface StockMovementInInput {
|
|
41
|
+
productId: string;
|
|
42
|
+
warehouseId: string;
|
|
43
|
+
quantity: number;
|
|
44
|
+
$key?: string;
|
|
45
|
+
}
|
|
46
|
+
declare function stockMovementIn(input: StockMovementInInput): PickwareStockMovementRecord;
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/plugin.d.ts
|
|
49
|
+
declare function pickware(): FakewarePlugin;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { PICKWARE_WAREHOUSES_KEY, type PickwareBinLocationRecord, type PickwareStockMovementRecord, type PickwareWarehouseRecord, type PickwareWarehouseRow, type StockMovementInInput, pickware, pickwareWarehouses, stockMovementIn, warehousesFetcher };
|
|
52
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { definePlugin } from "@fakeware/core";
|
|
2
|
+
//#region src/fetchers.ts
|
|
3
|
+
const PICKWARE_WAREHOUSES_KEY = "pickwareWarehouses";
|
|
4
|
+
function pickwareWarehouses(extensions) {
|
|
5
|
+
return extensions["pickwareWarehouses"] ?? [];
|
|
6
|
+
}
|
|
7
|
+
const warehousesFetcher = {
|
|
8
|
+
entity: "pickware warehouses",
|
|
9
|
+
fetch: (client) => client.invoke("post /search/pickware-erp-warehouse", { body: { limit: 500 } }),
|
|
10
|
+
merge: (data, raw) => {
|
|
11
|
+
const rows = raw?.data ?? [];
|
|
12
|
+
data.extensions[PICKWARE_WAREHOUSES_KEY] = rows;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/helpers.ts
|
|
17
|
+
function stockMovementIn(input) {
|
|
18
|
+
if (!Number.isFinite(input.quantity) || input.quantity <= 0) throw new Error(`stockMovementIn: quantity must be a positive number, got ${input.quantity}.`);
|
|
19
|
+
return {
|
|
20
|
+
...input.$key ? { $key: input.$key } : {},
|
|
21
|
+
productId: input.productId,
|
|
22
|
+
quantity: input.quantity,
|
|
23
|
+
destinationWarehouseId: input.warehouseId
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/plugin.ts
|
|
28
|
+
function pickware() {
|
|
29
|
+
return definePlugin({
|
|
30
|
+
name: "pickware",
|
|
31
|
+
fetchers: [warehousesFetcher]
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { PICKWARE_WAREHOUSES_KEY, pickware, pickwareWarehouses, stockMovementIn, warehousesFetcher };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/fetchers.ts","../src/helpers.ts","../src/plugin.ts"],"sourcesContent":["import type { ShopContextFetcher } from '@fakeware/core'\n\nexport interface PickwareWarehouseRow {\n id: string\n name?: string\n code?: string\n [key: string]: unknown\n}\n\nexport const PICKWARE_WAREHOUSES_KEY = 'pickwareWarehouses'\n\nexport function pickwareWarehouses(extensions: Record<string, unknown>): PickwareWarehouseRow[] {\n return (extensions[PICKWARE_WAREHOUSES_KEY] as PickwareWarehouseRow[] | undefined) ?? []\n}\n\nexport const warehousesFetcher: ShopContextFetcher = {\n entity: 'pickware warehouses',\n fetch: (client) =>\n (client.invoke as (path: string, params: unknown) => Promise<unknown>)(\n 'post /search/pickware-erp-warehouse',\n { body: { limit: 500 } },\n ),\n merge: (data, raw) => {\n const rows = (raw as { data?: PickwareWarehouseRow[] } | null)?.data ?? []\n data.extensions[PICKWARE_WAREHOUSES_KEY] = rows\n },\n}\n","import type { PickwareStockMovementRecord } from './entities'\n\nexport interface StockMovementInInput {\n productId: string\n warehouseId: string\n quantity: number\n $key?: string\n}\n\nexport function stockMovementIn(input: StockMovementInInput): PickwareStockMovementRecord {\n if (!Number.isFinite(input.quantity) || input.quantity <= 0) {\n throw new Error(`stockMovementIn: quantity must be a positive number, got ${input.quantity}.`)\n }\n return {\n ...(input.$key ? { $key: input.$key } : {}),\n productId: input.productId,\n quantity: input.quantity,\n destinationWarehouseId: input.warehouseId,\n }\n}\n","import { definePlugin, type FakewarePlugin } from '@fakeware/core'\nimport { warehousesFetcher } from './fetchers'\n\nexport function pickware(): FakewarePlugin {\n return definePlugin({\n name: 'pickware',\n fetchers: [warehousesFetcher],\n })\n}\n"],"mappings":";;AASA,MAAa,0BAA0B;AAEvC,SAAgB,mBAAmB,YAA6D;CAC9F,OAAQ,WAAA,yBAA8E,CAAC;AACzF;AAEA,MAAa,oBAAwC;CACnD,QAAQ;CACR,QAAQ,WACL,OAAO,OACN,uCACA,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE,CACzB;CACF,QAAQ,MAAM,QAAQ;EACpB,MAAM,OAAQ,KAAkD,QAAQ,CAAC;EACzE,KAAK,WAAW,2BAA2B;CAC7C;AACF;;;ACjBA,SAAgB,gBAAgB,OAA0D;CACxF,IAAI,CAAC,OAAO,SAAS,MAAM,QAAQ,KAAK,MAAM,YAAY,GACxD,MAAM,IAAI,MAAM,4DAA4D,MAAM,SAAS,EAAE;CAE/F,OAAO;EACL,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;EACzC,WAAW,MAAM;EACjB,UAAU,MAAM;EAChB,wBAAwB,MAAM;CAChC;AACF;;;AChBA,SAAgB,WAA2B;CACzC,OAAO,aAAa;EAClB,MAAM;EACN,UAAU,CAAC,iBAAiB;CAC9B,CAAC;AACH"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fakeware/plugin-pickware",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Pickware ERP plugin for fakeware. Seed warehouses, bin locations and stock into a Shopware 6 shop running Pickware",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/fakeware-sh/plugin-pickware.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"fakeware",
|
|
13
|
+
"fakeware-plugin",
|
|
14
|
+
"shopware",
|
|
15
|
+
"pickware",
|
|
16
|
+
"seed",
|
|
17
|
+
"fixtures"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20",
|
|
21
|
+
"bun": ">=1.3.14"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"exports": {
|
|
30
|
+
"./package.json": "./package.json",
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.mts",
|
|
33
|
+
"import": "./dist/index.mjs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"dev": "tsdown --watch",
|
|
38
|
+
"build": "tsdown",
|
|
39
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
40
|
+
"check": "biome check . && bun run typecheck",
|
|
41
|
+
"fix": "biome check . --write && bun run typecheck",
|
|
42
|
+
"test": "bun test"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@fakeware/core": ">=0.0.9"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@biomejs/biome": "2.4.16",
|
|
49
|
+
"@fakeware/core": "0.0.9",
|
|
50
|
+
"@types/bun": "1.3.14",
|
|
51
|
+
"publint": "0.3.21",
|
|
52
|
+
"tsdown": "^0.22.2",
|
|
53
|
+
"typescript": "^6.0.3"
|
|
54
|
+
}
|
|
55
|
+
}
|