@fayz-ai/inventory 0.0.0-stage → 0.1.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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -2
  3. package/dist/chunk-2FXO63QV.js +1732 -0
  4. package/dist/chunk-2FXO63QV.js.map +1 -0
  5. package/dist/chunk-52AJ7H2W.js +116 -0
  6. package/dist/chunk-52AJ7H2W.js.map +1 -0
  7. package/dist/chunk-AFUR3HLA.js +84 -0
  8. package/dist/chunk-AFUR3HLA.js.map +1 -0
  9. package/dist/chunk-EF5LVTOC.js +65 -0
  10. package/dist/chunk-EF5LVTOC.js.map +1 -0
  11. package/dist/chunk-GBIFZCEN.js +33 -0
  12. package/dist/chunk-GBIFZCEN.js.map +1 -0
  13. package/dist/chunk-GDEIBHAB.js +14 -0
  14. package/dist/chunk-GDEIBHAB.js.map +1 -0
  15. package/dist/chunk-JN5AZ656.js +35 -0
  16. package/dist/chunk-JN5AZ656.js.map +1 -0
  17. package/dist/chunk-JX7NCXJQ.js +15 -0
  18. package/dist/chunk-JX7NCXJQ.js.map +1 -0
  19. package/dist/chunk-MCWG3PMP.js +549 -0
  20. package/dist/chunk-MCWG3PMP.js.map +1 -0
  21. package/dist/chunk-RUOX7OOY.js +30 -0
  22. package/dist/chunk-RUOX7OOY.js.map +1 -0
  23. package/dist/chunk-SZXUGORU.js +13 -0
  24. package/dist/chunk-SZXUGORU.js.map +1 -0
  25. package/dist/chunk-W36J5END.js +48 -0
  26. package/dist/chunk-W36J5END.js.map +1 -0
  27. package/dist/chunk-YZDGJBJD.js +53 -0
  28. package/dist/chunk-YZDGJBJD.js.map +1 -0
  29. package/dist/data/mock.d.ts +3 -0
  30. package/dist/data/mock.d.ts.map +1 -0
  31. package/dist/data/mock.js +10 -0
  32. package/dist/data/mock.js.map +1 -0
  33. package/dist/data/provider.d.ts +120 -0
  34. package/dist/data/provider.d.ts.map +1 -0
  35. package/dist/data/provider.js +3 -0
  36. package/dist/data/provider.js.map +1 -0
  37. package/dist/data/supabase.d.ts +3 -0
  38. package/dist/data/supabase.d.ts.map +1 -0
  39. package/dist/data/supabase.js +13 -0
  40. package/dist/data/supabase.js.map +1 -0
  41. package/dist/data/tables.d.ts +25 -0
  42. package/dist/data/tables.d.ts.map +1 -0
  43. package/dist/data/tables.js +3 -0
  44. package/dist/data/tables.js.map +1 -0
  45. package/dist/domain/consumption.d.ts +33 -0
  46. package/dist/domain/consumption.d.ts.map +1 -0
  47. package/dist/domain/consumption.js +3 -0
  48. package/dist/domain/consumption.js.map +1 -0
  49. package/dist/domain/count.d.ts +85 -0
  50. package/dist/domain/count.d.ts.map +1 -0
  51. package/dist/domain/count.js +3 -0
  52. package/dist/domain/count.js.map +1 -0
  53. package/dist/domain/movement.d.ts +101 -0
  54. package/dist/domain/movement.d.ts.map +1 -0
  55. package/dist/domain/movement.js +3 -0
  56. package/dist/domain/movement.js.map +1 -0
  57. package/dist/domain/product.d.ts +245 -0
  58. package/dist/domain/product.d.ts.map +1 -0
  59. package/dist/domain/product.js +3 -0
  60. package/dist/domain/product.js.map +1 -0
  61. package/dist/domain/query.d.ts +12 -0
  62. package/dist/domain/query.d.ts.map +1 -0
  63. package/dist/domain/query.js +3 -0
  64. package/dist/domain/query.js.map +1 -0
  65. package/dist/domain/recipe-sheet.d.ts +133 -0
  66. package/dist/domain/recipe-sheet.d.ts.map +1 -0
  67. package/dist/domain/recipe-sheet.js +3 -0
  68. package/dist/domain/recipe-sheet.js.map +1 -0
  69. package/dist/domain/recipe.d.ts +138 -0
  70. package/dist/domain/recipe.d.ts.map +1 -0
  71. package/dist/domain/recipe.js +3 -0
  72. package/dist/domain/recipe.js.map +1 -0
  73. package/dist/domain/reference-data.d.ts +37 -0
  74. package/dist/domain/reference-data.d.ts.map +1 -0
  75. package/dist/domain/reference-data.js +3 -0
  76. package/dist/domain/reference-data.js.map +1 -0
  77. package/dist/domain/stock.d.ts +132 -0
  78. package/dist/domain/stock.d.ts.map +1 -0
  79. package/dist/domain/stock.js +5 -0
  80. package/dist/domain/stock.js.map +1 -0
  81. package/dist/domain/usage-audit.d.ts +95 -0
  82. package/dist/domain/usage-audit.d.ts.map +1 -0
  83. package/dist/domain/usage-audit.js +3 -0
  84. package/dist/domain/usage-audit.js.map +1 -0
  85. package/dist/lib/idempotency.d.ts +4 -0
  86. package/dist/lib/idempotency.d.ts.map +1 -0
  87. package/dist/lib/idempotency.js +3 -0
  88. package/dist/lib/idempotency.js.map +1 -0
  89. package/dist/store.d.ts +52 -0
  90. package/dist/store.d.ts.map +1 -0
  91. package/dist/store.js +193 -0
  92. package/dist/store.js.map +1 -0
  93. package/package.json +50 -3
package/dist/store.js ADDED
@@ -0,0 +1,193 @@
1
+ import { patchUsageEntries } from './chunk-SZXUGORU.js';
2
+ import { createMockInventoryProvider } from './chunk-MCWG3PMP.js';
3
+ import { createSupabaseInventoryProvider } from './chunk-2FXO63QV.js';
4
+ import './chunk-JN5AZ656.js';
5
+ import './chunk-JX7NCXJQ.js';
6
+ import './chunk-EF5LVTOC.js';
7
+ import './chunk-YZDGJBJD.js';
8
+ import './chunk-52AJ7H2W.js';
9
+ import './chunk-GDEIBHAB.js';
10
+ import './chunk-RUOX7OOY.js';
11
+ import './chunk-GBIFZCEN.js';
12
+ import './chunk-W36J5END.js';
13
+ import './chunk-AFUR3HLA.js';
14
+ import { createStore } from 'zustand/vanilla';
15
+ import { createSafeDataProvider, tl } from '@fayz-ai/core';
16
+ import { toast } from '@fayz-ai/ui';
17
+
18
+ function createInventoryDataProvider() {
19
+ return createSafeDataProvider(createSupabaseInventoryProvider, createMockInventoryProvider);
20
+ }
21
+ var inflight = /* @__PURE__ */ new Map();
22
+ function shared(key, read) {
23
+ const running = inflight.get(key);
24
+ if (running) return running;
25
+ const promise = read().finally(() => inflight.delete(key));
26
+ inflight.set(key, promise);
27
+ return promise;
28
+ }
29
+ function messageOf(err) {
30
+ if (err && typeof err === "object" && "message" in err) return String(err.message);
31
+ return void 0;
32
+ }
33
+ function createInventoryStore(provider) {
34
+ return createStore((set, get) => {
35
+ async function reloadUsageAudit() {
36
+ const [result, summary] = await Promise.all([provider.getUsageAudit(get().usageAuditQuery), provider.getSummary()]);
37
+ set({ usageAudit: result.data, usageAuditTotal: result.total, summary });
38
+ }
39
+ return {
40
+ products: [],
41
+ productsTotal: 0,
42
+ productsLoading: false,
43
+ productQuery: {},
44
+ movements: [],
45
+ movementsTotal: 0,
46
+ movementsLoading: false,
47
+ usageAudit: [],
48
+ usageAuditTotal: 0,
49
+ usageAuditLoading: false,
50
+ usageAuditQuery: {},
51
+ locations: [],
52
+ locationsLoading: false,
53
+ recipes: [],
54
+ recipesLoading: false,
55
+ summary: null,
56
+ summaryLoading: false,
57
+ restock: null,
58
+ categoryMix: null,
59
+ async fetchRestock() {
60
+ const read = provider.getRestockList;
61
+ if (!read) return;
62
+ try {
63
+ set({ restock: await shared("inv:restock", () => read.call(provider)) });
64
+ } catch {
65
+ set({ restock: [] });
66
+ }
67
+ },
68
+ async fetchCategoryMix() {
69
+ const read = provider.getCategoryDistribution;
70
+ if (!read) return;
71
+ try {
72
+ set({ categoryMix: await shared("inv:category-mix", () => read.call(provider)) });
73
+ } catch {
74
+ set({ categoryMix: [] });
75
+ }
76
+ },
77
+ async fetchSummary() {
78
+ set({ summaryLoading: true });
79
+ try {
80
+ set({ summary: await shared("inv:summary", () => provider.getSummary()), summaryLoading: false });
81
+ } catch (err) {
82
+ set({ summaryLoading: false });
83
+ throw err;
84
+ }
85
+ },
86
+ async fetchProducts(query) {
87
+ set({ productsLoading: true, productQuery: query });
88
+ try {
89
+ const result = await shared(`inv:products:${JSON.stringify(query)}`, () => provider.getProducts(query));
90
+ set({ products: result.data, productsTotal: result.total, productsLoading: false });
91
+ } catch (err) {
92
+ set({ productsLoading: false });
93
+ throw err;
94
+ }
95
+ },
96
+ async fetchMovements(query) {
97
+ set({ movementsLoading: true });
98
+ try {
99
+ const result = await shared(`inv:movements:${JSON.stringify(query)}`, () => provider.getMovements(query));
100
+ set({ movements: result.data, movementsTotal: result.total, movementsLoading: false });
101
+ } catch (err) {
102
+ set({ movementsLoading: false });
103
+ throw err;
104
+ }
105
+ },
106
+ async fetchUsageAudit(query) {
107
+ set({ usageAuditLoading: true, usageAuditQuery: query });
108
+ try {
109
+ const result = await shared(`inv:usage-audit:${JSON.stringify(query)}`, () => provider.getUsageAudit(query));
110
+ set({ usageAudit: result.data, usageAuditTotal: result.total, usageAuditLoading: false });
111
+ } catch (err) {
112
+ set({ usageAuditLoading: false });
113
+ throw err;
114
+ }
115
+ },
116
+ async correctUsage(input) {
117
+ await provider.correctUsage(input);
118
+ await reloadUsageAudit();
119
+ },
120
+ async approveUsageBatch(input) {
121
+ if (!provider.approveUsageBatch) throw new Error("inventory: provider has no approveUsageBatch");
122
+ return provider.approveUsageBatch(input);
123
+ },
124
+ patchUsageAuditEntries(lines, patch) {
125
+ set((state) => ({ usageAudit: patchUsageEntries(state.usageAudit, lines, patch) }));
126
+ },
127
+ async correctUsageBatch(input) {
128
+ const outcome = await provider.correctUsageBatch(input);
129
+ await reloadUsageAudit();
130
+ return outcome;
131
+ },
132
+ async fetchLocations() {
133
+ set({ locationsLoading: true });
134
+ try {
135
+ set({ locations: await shared("inv:locations", () => provider.getLocations()), locationsLoading: false });
136
+ } catch (err) {
137
+ set({ locationsLoading: false });
138
+ throw err;
139
+ }
140
+ },
141
+ async fetchRecipes() {
142
+ set({ recipesLoading: true });
143
+ set({ recipes: await provider.getRecipes(), recipesLoading: false });
144
+ },
145
+ async createProduct(input) {
146
+ try {
147
+ const product = await provider.createProduct(input);
148
+ const [result, summary] = await Promise.all([provider.getProducts(get().productQuery), provider.getSummary()]);
149
+ set({ products: result.data, productsTotal: result.total, summary });
150
+ toast.success(tl("Product created", "Produto cadastrado"));
151
+ return product;
152
+ } catch (err) {
153
+ toast.error(tl("Failed to create product", "N\xE3o foi poss\xEDvel cadastrar o produto"), { description: messageOf(err) });
154
+ throw err;
155
+ }
156
+ },
157
+ async createMovement(input) {
158
+ let movement;
159
+ try {
160
+ movement = await provider.createMovement(input);
161
+ } catch (err) {
162
+ toast.error(tl("Failed to record movement", "N\xE3o foi poss\xEDvel registrar a movimenta\xE7\xE3o"), { description: messageOf(err) });
163
+ throw err;
164
+ }
165
+ try {
166
+ set({ summary: await provider.getSummary() });
167
+ toast.success(tl("Stock movement recorded", "Movimenta\xE7\xE3o registrada"));
168
+ } catch {
169
+ toast.warning(tl(
170
+ "Stock movement recorded; refresh the list to see the updated balance",
171
+ "Movimenta\xE7\xE3o registrada; atualize a lista para ver o saldo novo"
172
+ ));
173
+ }
174
+ return movement;
175
+ },
176
+ async createRecipe(input) {
177
+ try {
178
+ const recipe = await provider.createRecipe(input);
179
+ set({ recipes: await provider.getRecipes() });
180
+ toast.success(tl("Recipe created", "Ficha t\xE9cnica cadastrada"));
181
+ return recipe;
182
+ } catch (err) {
183
+ toast.error(tl("Failed to create recipe", "N\xE3o foi poss\xEDvel cadastrar a ficha t\xE9cnica"), { description: messageOf(err) });
184
+ throw err;
185
+ }
186
+ }
187
+ };
188
+ });
189
+ }
190
+
191
+ export { createInventoryDataProvider, createInventoryStore };
192
+ //# sourceMappingURL=store.js.map
193
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store.ts"],"names":[],"mappings":"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","file":"store.js","sourcesContent":["import { createStore, type StoreApi } from 'zustand/vanilla'\nimport { createSafeDataProvider, tl } from '@fayz-ai/core'\nimport { toast } from '@fayz-ai/ui'\nimport { createSupabaseInventoryProvider } from './data/supabase'\nimport { createMockInventoryProvider } from './data/mock'\nimport type { InventoryDataProvider } from './data/provider'\nimport type { CreateProductInput, Product, ProductQuery } from './domain/product'\nimport type { CreateStockMovementInput, MovementQuery, StockMovement } from './domain/movement'\nimport type { CategoryCount, InventorySummary, RestockLine, StockLocation } from './domain/stock'\nimport type { CreateRecipeInput, Recipe } from './domain/recipe'\nimport {\n patchUsageEntries,\n type UsageAuditApproval, type UsageAuditApproveInput, type UsageAuditApproveResult, type UsageAuditBatchResult,\n type UsageAuditCorrection, type UsageAuditCorrectionInput, type UsageAuditEntry, type UsageAuditQuery,\n} from './domain/usage-audit'\n\n/** Supabase when the app has a client, the in-memory mock otherwise. */\nexport function createInventoryDataProvider(): InventoryDataProvider {\n return createSafeDataProvider(createSupabaseInventoryProvider, createMockInventoryProvider)\n}\n\nexport interface InventoryUIState {\n products: Product[]\n productsTotal: number\n productsLoading: boolean\n productQuery: ProductQuery\n\n movements: StockMovement[]\n movementsTotal: number\n movementsLoading: boolean\n\n usageAudit: UsageAuditEntry[]\n usageAuditTotal: number\n usageAuditLoading: boolean\n usageAuditQuery: UsageAuditQuery\n\n locations: StockLocation[]\n locationsLoading: boolean\n\n recipes: Recipe[]\n recipesLoading: boolean\n\n summary: InventorySummary | null\n summaryLoading: boolean\n\n /** Null until read. */\n restock: RestockLine[] | null\n categoryMix: CategoryCount[] | null\n\n fetchSummary(): Promise<void>\n fetchRestock(): Promise<void>\n fetchCategoryMix(): Promise<void>\n fetchProducts(query: ProductQuery): Promise<void>\n fetchMovements(query: MovementQuery): Promise<void>\n fetchUsageAudit(query: UsageAuditQuery): Promise<void>\n correctUsage(input: UsageAuditCorrectionInput): Promise<void>\n correctUsageBatch(input: { reason: string; lines: UsageAuditCorrection[] }): Promise<UsageAuditBatchResult>\n approveUsageBatch(input: UsageAuditApproveInput): Promise<UsageAuditApproveResult>\n /** Applies what an approval wrote to the rows on screen, without a reload. */\n patchUsageAuditEntries(lines: UsageAuditApproval[], patch: Partial<UsageAuditEntry>): void\n fetchLocations(): Promise<void>\n fetchRecipes(): Promise<void>\n createProduct(input: CreateProductInput): Promise<Product>\n createMovement(input: CreateStockMovementInput): Promise<StockMovement>\n createRecipe(input: CreateRecipeInput): Promise<Recipe>\n}\n\nconst inflight = new Map<string, Promise<unknown>>()\n\n/**\n * Shares the result of a read across every store, never its effect: a plugin rebuild creates a second store\n * while the first one's read is still in flight, so each caller sets its own state from the shared promise.\n */\nfunction shared<T>(key: string, read: () => Promise<T>): Promise<T> {\n const running = inflight.get(key) as Promise<T> | undefined\n if (running) return running\n const promise = read().finally(() => inflight.delete(key))\n inflight.set(key, promise)\n return promise\n}\n\nfunction messageOf(err: unknown): string | undefined {\n // The ledger RPCs throw PostgrestError, a plain object with a message.\n if (err && typeof err === 'object' && 'message' in err) return String(err.message)\n return undefined\n}\n\nexport function createInventoryStore(provider: InventoryDataProvider): StoreApi<InventoryUIState> {\n return createStore<InventoryUIState>((set, get) => {\n async function reloadUsageAudit(): Promise<void> {\n const [result, summary] = await Promise.all([provider.getUsageAudit(get().usageAuditQuery), provider.getSummary()])\n set({ usageAudit: result.data, usageAuditTotal: result.total, summary })\n }\n\n return {\n products: [], productsTotal: 0, productsLoading: false, productQuery: {},\n movements: [], movementsTotal: 0, movementsLoading: false,\n usageAudit: [], usageAuditTotal: 0, usageAuditLoading: false, usageAuditQuery: {},\n locations: [], locationsLoading: false,\n recipes: [], recipesLoading: false,\n summary: null, summaryLoading: false,\n restock: null, categoryMix: null,\n\n async fetchRestock() {\n const read = provider.getRestockList\n if (!read) return\n try {\n set({ restock: await shared('inv:restock', () => read.call(provider)) })\n } catch {\n // The restock card must not take the dashboard down with it.\n set({ restock: [] })\n }\n },\n\n async fetchCategoryMix() {\n const read = provider.getCategoryDistribution\n if (!read) return\n try {\n set({ categoryMix: await shared('inv:category-mix', () => read.call(provider)) })\n } catch {\n set({ categoryMix: [] })\n }\n },\n\n async fetchSummary() {\n set({ summaryLoading: true })\n try {\n set({ summary: await shared('inv:summary', () => provider.getSummary()), summaryLoading: false })\n } catch (err) {\n set({ summaryLoading: false })\n throw err\n }\n },\n\n async fetchProducts(query) {\n set({ productsLoading: true, productQuery: query })\n try {\n const result = await shared(`inv:products:${JSON.stringify(query)}`, () => provider.getProducts(query))\n set({ products: result.data, productsTotal: result.total, productsLoading: false })\n } catch (err) {\n set({ productsLoading: false })\n throw err\n }\n },\n\n async fetchMovements(query) {\n set({ movementsLoading: true })\n try {\n const result = await shared(`inv:movements:${JSON.stringify(query)}`, () => provider.getMovements(query))\n set({ movements: result.data, movementsTotal: result.total, movementsLoading: false })\n } catch (err) {\n set({ movementsLoading: false })\n throw err\n }\n },\n\n async fetchUsageAudit(query) {\n set({ usageAuditLoading: true, usageAuditQuery: query })\n try {\n const result = await shared(`inv:usage-audit:${JSON.stringify(query)}`, () => provider.getUsageAudit(query))\n set({ usageAudit: result.data, usageAuditTotal: result.total, usageAuditLoading: false })\n } catch (err) {\n set({ usageAuditLoading: false })\n throw err\n }\n },\n\n async correctUsage(input) {\n await provider.correctUsage(input)\n await reloadUsageAudit()\n },\n\n async approveUsageBatch(input) {\n if (!provider.approveUsageBatch) throw new Error('inventory: provider has no approveUsageBatch')\n return provider.approveUsageBatch(input)\n },\n\n patchUsageAuditEntries(lines, patch) {\n set((state) => ({ usageAudit: patchUsageEntries(state.usageAudit, lines, patch) }))\n },\n\n async correctUsageBatch(input) {\n const outcome = await provider.correctUsageBatch(input)\n await reloadUsageAudit()\n return outcome\n },\n\n async fetchLocations() {\n set({ locationsLoading: true })\n try {\n set({ locations: await shared('inv:locations', () => provider.getLocations()), locationsLoading: false })\n } catch (err) {\n set({ locationsLoading: false })\n throw err\n }\n },\n\n async fetchRecipes() {\n set({ recipesLoading: true })\n set({ recipes: await provider.getRecipes(), recipesLoading: false })\n },\n\n async createProduct(input) {\n try {\n const product = await provider.createProduct(input)\n const [result, summary] = await Promise.all([provider.getProducts(get().productQuery), provider.getSummary()])\n set({ products: result.data, productsTotal: result.total, summary })\n toast.success(tl('Product created', 'Produto cadastrado'))\n return product\n } catch (err) {\n toast.error(tl('Failed to create product', 'Não foi possível cadastrar o produto'), { description: messageOf(err) })\n throw err\n }\n },\n\n async createMovement(input) {\n let movement: StockMovement\n try {\n movement = await provider.createMovement(input)\n } catch (err) {\n toast.error(tl('Failed to record movement', 'Não foi possível registrar a movimentação'), { description: messageOf(err) })\n throw err\n }\n try {\n set({ summary: await provider.getSummary() })\n toast.success(tl('Stock movement recorded', 'Movimentação registrada'))\n } catch {\n toast.warning(tl(\n 'Stock movement recorded; refresh the list to see the updated balance',\n 'Movimentação registrada; atualize a lista para ver o saldo novo',\n ))\n }\n return movement\n },\n\n async createRecipe(input) {\n try {\n const recipe = await provider.createRecipe(input)\n set({ recipes: await provider.getRecipes() })\n toast.success(tl('Recipe created', 'Ficha técnica cadastrada'))\n return recipe\n } catch (err) {\n toast.error(tl('Failed to create recipe', 'Não foi possível cadastrar a ficha técnica'), { description: messageOf(err) })\n throw err\n }\n },\n }\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,53 @@
1
1
  {
2
2
  "name": "@fayz-ai/inventory",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "fayz": {
4
+ "status": "beta"
5
+ },
6
+ "version": "0.1.0",
7
+ "description": "Fayz SDK inventory context — the stock ledger domain, its repository port and adapters, and the store",
8
+ "type": "module",
9
+ "sideEffects": false,
10
+ "exports": {
11
+ "./*": {
12
+ "types": "./dist/*.d.ts",
13
+ "import": "./dist/*.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "peerDependencies": {
20
+ "@supabase/supabase-js": "^2.45.0",
21
+ "react": "^18.0.0 || ^19.0.0",
22
+ "zustand": "^4.5.0 || ^5.0.0"
23
+ },
24
+ "dependencies": {
25
+ "@fayz-ai/core": "^0.48.0",
26
+ "@fayz-ai/ui": "^0.48.0"
27
+ },
28
+ "devDependencies": {
29
+ "@supabase/supabase-js": "^2.45.0",
30
+ "@types/react": "^18.3.0",
31
+ "react": "^18.3.0",
32
+ "tsup": "^8.2.0",
33
+ "typescript": "^5.5.0",
34
+ "vitest": "^4.1.5",
35
+ "zustand": "^4.5.0"
36
+ },
37
+ "license": "MIT",
38
+ "keywords": [
39
+ "fayz",
40
+ "inventory",
41
+ "stock"
42
+ ],
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "scripts": {
47
+ "build": "tsup && tsc -b --force",
48
+ "dev": "tsup --watch",
49
+ "typecheck": "tsc -b tsconfig.test.json",
50
+ "test": "vitest run",
51
+ "clean": "rm -rf dist .tsbuildinfo"
52
+ }
6
53
  }