@anker-in/lib 1.0.0-beta.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/.gitkeep ADDED
File without changes
@@ -0,0 +1,27 @@
1
+
2
+ > @anker-in/lib@1.0.0 build /Users/anker/Code/headless-ui/packages/lib
3
+ > tsup
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.4.0
8
+ CLI Using tsup config: /Users/anker/Code/headless-ui/packages/lib/tsup.config.ts
9
+ CLI Target: esnext
10
+ CLI Cleaning output folder
11
+ ESM Build start
12
+ CJS Build start
13
+ IIFE Build start
14
+ If you do not supply "output.name", you may not be able to access the exports of an IIFE bundle.
15
+ IIFE dist/index.global.js 198.00 B
16
+ IIFE dist/index.global.js.map 397.00 B
17
+ IIFE ⚡️ Build success in 436ms
18
+ CJS dist/index.js 143.00 B
19
+ CJS dist/index.js.map 389.00 B
20
+ CJS ⚡️ Build success in 438ms
21
+ ESM dist/index.mjs 130.00 B
22
+ ESM dist/index.mjs.map 390.00 B
23
+ ESM ⚡️ Build success in 438ms
24
+ DTS Build start
25
+ DTS ⚡️ Build success in 4317ms
26
+ DTS dist/index.d.mts 161.00 B
27
+ DTS dist/index.d.ts 161.00 B
@@ -0,0 +1,14 @@
1
+
2
+ > @anker-in/lib@1.0.0 test /Users/anker/Code/headless-ui/packages/lib
3
+ > jest --passWithNoTests
4
+
5
+ PASS src/__tests__/math.test.ts
6
+ math functions
7
+ ✓ add should correctly add two numbers (1 ms)
8
+ ✓ subtract should correctly subtract two numbers
9
+
10
+ Test Suites: 1 passed, 1 total
11
+ Tests: 2 passed, 2 total
12
+ Snapshots: 0 total
13
+ Time: 1.197 s
14
+ Ran all test suites.
package/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # @anker-in/lib
2
+
3
+ 便利导出包,整合所有 Anker headless 功能。用户只需安装和导入这一个包即可使用所有功能。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pnpm add @anker-in/lib
9
+ ```
10
+
11
+ **就这样!** 所有依赖(`@anker-in/shared`、`@anker-in/cart`、`@anker-in/shopify`)会自动安装。
12
+
13
+ ## 快速开始
14
+
15
+ ### 1. 设置 HeadlessProvider
16
+
17
+ ```tsx
18
+ import { HeadlessProvider } from '@anker-in/lib'
19
+
20
+ const headlessConfig = {
21
+ storefrontToken: 'your-token',
22
+ storeDomain: 'your-store.myshopify.com',
23
+ locale: 'en-US',
24
+ comboMetafieldsNamespace: 'custom',
25
+ cartIdCookieName: 'cart_id',
26
+ brand: 'Anker',
27
+ appName: 'My App'
28
+ }
29
+
30
+ function App() {
31
+ return (
32
+ <HeadlessProvider headlessConfig={headlessConfig}>
33
+ <YourApp />
34
+ </HeadlessProvider>
35
+ )
36
+ }
37
+ ```
38
+
39
+ ### 2. 使用所有功能(从一个包导入!)
40
+
41
+ ```tsx
42
+ import {
43
+ // Context
44
+ useHeadlessContext,
45
+
46
+ // Shopify 功能
47
+ useProduct,
48
+ createCart,
49
+
50
+ // Cart 功能
51
+ useBuyNow,
52
+ useAddToCart,
53
+ useUpdateCartLines
54
+ } from '@anker-in/lib'
55
+
56
+ function ProductPage() {
57
+ const { storefrontToken, storeDomain } = useHeadlessContext()
58
+ const product = useProduct(productId)
59
+ const { trigger: buyNow } = useBuyNow()
60
+
61
+ const handleBuyNow = () => {
62
+ buyNow({
63
+ lineItems: [
64
+ {
65
+ variant: { id: product.variants[0].id },
66
+ quantity: 1
67
+ }
68
+ ]
69
+ })
70
+ }
71
+
72
+ return (
73
+ <div>
74
+ <h1>{product?.title}</h1>
75
+ <button onClick={handleBuyNow}>立即购买</button>
76
+ </div>
77
+ )
78
+ }
79
+ ```
80
+
81
+ ## 架构设计
82
+
83
+ 为了避免循环依赖,采用了分层架构:
84
+
85
+ ```
86
+ ┌──────────────┐
87
+ │ shared │ (基础包:Context + Types)
88
+ └──────┬───────┘
89
+
90
+ ┌───────┼────────┐
91
+ │ │ │
92
+ ↓ ↓ ↓
93
+ ┌────────┬──────┬─────────┐
94
+ │ lib │ cart │ shopify │
95
+ └────┬───┴──────┴────┬────┘
96
+ │ │
97
+ └───────┬───────┘
98
+
99
+ (lib 重新导出所有)
100
+ ```
101
+
102
+ ### 包职责
103
+
104
+ - **@anker-in/shared**: 基础包,提供 `HeadlessProvider` 和 `HeadlessConfig`
105
+ - **@anker-in/shopify**: Shopify API 集成和 hooks
106
+ - **@anker-in/cart**: 购物车功能和 hooks
107
+ - **@anker-in/lib**: 便利导出包,重新导出所有功能 + 自己的工具函数
108
+
109
+ ### 为什么这样设计?
110
+
111
+ **问题:** 如果 `lib` 包含 Context,而 `cart` 使用 `lib` 的 Context,那么 `lib` 就不能导出 `cart`(会形成循环)。
112
+
113
+ **解决:** 将 Context 提取到独立的 `shared` 包,这样:
114
+ - ✅ `cart` 依赖 `shared`(获取 Context)
115
+ - ✅ `lib` 依赖 `shared`(获取 Context)
116
+ - ✅ `lib` 依赖 `cart`(重新导出)
117
+ - ✅ 完全消除循环依赖!
118
+
119
+ ## API
120
+
121
+ ### HeadlessProvider
122
+
123
+ 提供全局配置的 Context Provider。
124
+
125
+ ```tsx
126
+ <HeadlessProvider headlessConfig={config}>
127
+ {children}
128
+ </HeadlessProvider>
129
+ ```
130
+
131
+ ### useHeadlessContext
132
+
133
+ 获取 Headless 配置的 Hook。
134
+
135
+ ```tsx
136
+ const { storefrontToken, storeDomain, locale, ... } = useHeadlessContext()
137
+ ```
138
+
139
+ ### HeadlessConfig
140
+
141
+ ```typescript
142
+ type HeadlessConfig = {
143
+ storefrontToken: string // Shopify Storefront API token
144
+ storeDomain: string // 店铺域名
145
+ locale: string // 语言环境
146
+ comboMetafieldsNamespace: string
147
+ cartIdCookieName: string // 购物车 ID 的 cookie 名称
148
+ brand: string // 品牌名称
149
+ appName: string // 应用名称
150
+ }
151
+ ```
152
+
153
+ ## 导出内容
154
+
155
+ 从 `@anker-in/lib` 可以导入:
156
+
157
+ - ✅ **Shared**: `HeadlessProvider`, `useHeadlessContext`, `HeadlessConfig`
158
+ - ✅ **Shopify**: 所有 Shopify 功能和 hooks
159
+ - ✅ **Cart**: 所有购物车功能和 hooks
160
+ - ✅ **Lib 自己的工具**: math 等工具函数
161
+
162
+ **简单来说,你只需要从 `@anker-in/lib` 导入所有内容!**
@@ -0,0 +1,425 @@
1
+ # 使用示例
2
+
3
+ ## 完整的电商应用示例
4
+
5
+ 以下是一个完整的示例,展示如何使用 `@anker-in/lib` 构建电商应用:
6
+
7
+ ### 1. 应用入口(App.tsx)
8
+
9
+ ```tsx
10
+ import { HeadlessProvider } from '@anker-in/lib'
11
+ import { ProductList } from './components/ProductList'
12
+ import { Cart } from './components/Cart'
13
+
14
+ const headlessConfig = {
15
+ storefrontToken: process.env.NEXT_PUBLIC_SHOPIFY_TOKEN!,
16
+ storeDomain: process.env.NEXT_PUBLIC_SHOPIFY_DOMAIN!,
17
+ locale: 'zh-CN',
18
+ comboMetafieldsNamespace: 'custom',
19
+ cartIdCookieName: 'anker_cart_id',
20
+ brand: 'Anker',
21
+ appName: 'Anker Store'
22
+ }
23
+
24
+ export default function App() {
25
+ return (
26
+ <HeadlessProvider headlessConfig={headlessConfig}>
27
+ <div className="app">
28
+ <header>
29
+ <h1>Anker 商店</h1>
30
+ <Cart />
31
+ </header>
32
+ <main>
33
+ <ProductList />
34
+ </main>
35
+ </div>
36
+ </HeadlessProvider>
37
+ )
38
+ }
39
+ ```
40
+
41
+ ### 2. 产品列表(ProductList.tsx)
42
+
43
+ ```tsx
44
+ import { useProducts, useHeadlessContext } from '@anker-in/lib'
45
+ import { ProductCard } from './ProductCard'
46
+
47
+ export function ProductList() {
48
+ const { locale } = useHeadlessContext()
49
+ const { data: products, isLoading } = useProducts({
50
+ first: 12,
51
+ // 其他查询参数...
52
+ })
53
+
54
+ if (isLoading) return <div>加载中...</div>
55
+
56
+ return (
57
+ <div className="product-grid">
58
+ {products?.map(product => (
59
+ <ProductCard key={product.id} product={product} />
60
+ ))}
61
+ </div>
62
+ )
63
+ }
64
+ ```
65
+
66
+ ### 3. 产品卡片(ProductCard.tsx)
67
+
68
+ ```tsx
69
+ import {
70
+ useAddToCart,
71
+ useBuyNow,
72
+ type Product
73
+ } from '@anker-in/lib'
74
+
75
+ interface ProductCardProps {
76
+ product: Product
77
+ }
78
+
79
+ export function ProductCard({ product }: ProductCardProps) {
80
+ const { trigger: addToCart, isMutating: isAdding } = useAddToCart()
81
+ const { trigger: buyNow, isMutating: isBuying } = useBuyNow()
82
+
83
+ const handleAddToCart = async () => {
84
+ try {
85
+ await addToCart({
86
+ lineItems: [{
87
+ variant: { id: product.variants[0].id },
88
+ quantity: 1
89
+ }]
90
+ })
91
+ alert('已添加到购物车!')
92
+ } catch (error) {
93
+ console.error('添加失败:', error)
94
+ }
95
+ }
96
+
97
+ const handleBuyNow = async () => {
98
+ await buyNow({
99
+ lineItems: [{
100
+ variant: { id: product.variants[0].id },
101
+ quantity: 1
102
+ }],
103
+ gtmParams: {
104
+ currency: 'USD',
105
+ value: parseFloat(product.variants[0].price.amount)
106
+ }
107
+ })
108
+ }
109
+
110
+ return (
111
+ <div className="product-card">
112
+ <img src={product.images[0]?.url} alt={product.title} />
113
+ <h3>{product.title}</h3>
114
+ <p className="price">${product.variants[0].price.amount}</p>
115
+
116
+ <div className="actions">
117
+ <button
118
+ onClick={handleAddToCart}
119
+ disabled={isAdding}
120
+ >
121
+ {isAdding ? '添加中...' : '加入购物车'}
122
+ </button>
123
+
124
+ <button
125
+ onClick={handleBuyNow}
126
+ disabled={isBuying}
127
+ className="primary"
128
+ >
129
+ {isBuying ? '处理中...' : '立即购买'}
130
+ </button>
131
+ </div>
132
+ </div>
133
+ )
134
+ }
135
+ ```
136
+
137
+ ### 4. 购物车(Cart.tsx)
138
+
139
+ ```tsx
140
+ import {
141
+ useCart,
142
+ useUpdateCartLines,
143
+ useRemoveCartLines,
144
+ useApplyCartCodes
145
+ } from '@anker-in/lib'
146
+ import { useState } from 'react'
147
+
148
+ export function Cart() {
149
+ const { data: cart } = useCart()
150
+ const { trigger: updateLines } = useUpdateCartLines()
151
+ const { trigger: removeLines } = useRemoveCartLines()
152
+ const { trigger: applyCode } = useApplyCartCodes()
153
+ const [discountCode, setDiscountCode] = useState('')
154
+
155
+ const handleQuantityChange = (lineId: string, quantity: number) => {
156
+ updateLines({
157
+ lines: [{
158
+ id: lineId,
159
+ quantity
160
+ }]
161
+ })
162
+ }
163
+
164
+ const handleRemove = (lineId: string) => {
165
+ removeLines({ lineIds: [lineId] })
166
+ }
167
+
168
+ const handleApplyDiscount = () => {
169
+ if (discountCode) {
170
+ applyCode({ discountCodes: [discountCode] })
171
+ }
172
+ }
173
+
174
+ if (!cart) return <div>购物车为空</div>
175
+
176
+ return (
177
+ <div className="cart">
178
+ <h2>购物车 ({cart.lines.length})</h2>
179
+
180
+ {cart.lines.map(line => (
181
+ <div key={line.id} className="cart-item">
182
+ <img src={line.merchandise.image?.url} alt={line.merchandise.title} />
183
+ <div className="info">
184
+ <h4>{line.merchandise.product.title}</h4>
185
+ <p>{line.merchandise.title}</p>
186
+ <p className="price">${line.cost.totalAmount.amount}</p>
187
+ </div>
188
+
189
+ <div className="quantity">
190
+ <button onClick={() => handleQuantityChange(line.id, line.quantity - 1)}>
191
+ -
192
+ </button>
193
+ <span>{line.quantity}</span>
194
+ <button onClick={() => handleQuantityChange(line.id, line.quantity + 1)}>
195
+ +
196
+ </button>
197
+ </div>
198
+
199
+ <button onClick={() => handleRemove(line.id)}>删除</button>
200
+ </div>
201
+ ))}
202
+
203
+ <div className="discount">
204
+ <input
205
+ type="text"
206
+ placeholder="优惠码"
207
+ value={discountCode}
208
+ onChange={(e) => setDiscountCode(e.target.value)}
209
+ />
210
+ <button onClick={handleApplyDiscount}>应用</button>
211
+ </div>
212
+
213
+ <div className="total">
214
+ <h3>总计: ${cart.cost.totalAmount.amount}</h3>
215
+ <a href={cart.checkoutUrl} className="checkout-button">
216
+ 去结账
217
+ </a>
218
+ </div>
219
+ </div>
220
+ )
221
+ }
222
+ ```
223
+
224
+ ### 5. 产品详情页(ProductDetail.tsx)
225
+
226
+ ```tsx
227
+ import {
228
+ useProduct,
229
+ useBuyNow,
230
+ useAddToCart,
231
+ useHeadlessContext
232
+ } from '@anker-in/lib'
233
+ import { useState } from 'react'
234
+
235
+ interface ProductDetailProps {
236
+ productId: string
237
+ }
238
+
239
+ export function ProductDetail({ productId }: ProductDetailProps) {
240
+ const { brand } = useHeadlessContext()
241
+ const { data: product, isLoading } = useProduct(productId)
242
+ const [selectedVariant, setSelectedVariant] = useState(0)
243
+ const [quantity, setQuantity] = useState(1)
244
+
245
+ const { trigger: buyNow } = useBuyNow()
246
+ const { trigger: addToCart } = useAddToCart()
247
+
248
+ if (isLoading) return <div>加载中...</div>
249
+ if (!product) return <div>产品未找到</div>
250
+
251
+ const currentVariant = product.variants[selectedVariant]
252
+
253
+ return (
254
+ <div className="product-detail">
255
+ <div className="gallery">
256
+ {product.images.map((image, idx) => (
257
+ <img key={idx} src={image.url} alt={`${product.title} ${idx + 1}`} />
258
+ ))}
259
+ </div>
260
+
261
+ <div className="info">
262
+ <span className="brand">{brand}</span>
263
+ <h1>{product.title}</h1>
264
+ <div dangerouslySetInnerHTML={{ __html: product.descriptionHtml }} />
265
+
266
+ <div className="variants">
267
+ <h3>选择规格</h3>
268
+ {product.variants.map((variant, idx) => (
269
+ <button
270
+ key={variant.id}
271
+ onClick={() => setSelectedVariant(idx)}
272
+ className={selectedVariant === idx ? 'active' : ''}
273
+ >
274
+ {variant.title}
275
+ </button>
276
+ ))}
277
+ </div>
278
+
279
+ <div className="price">
280
+ <h2>${currentVariant.price.amount}</h2>
281
+ </div>
282
+
283
+ <div className="quantity">
284
+ <label>数量:</label>
285
+ <input
286
+ type="number"
287
+ min="1"
288
+ value={quantity}
289
+ onChange={(e) => setQuantity(parseInt(e.target.value))}
290
+ />
291
+ </div>
292
+
293
+ <div className="actions">
294
+ <button
295
+ onClick={() => addToCart({
296
+ lineItems: [{
297
+ variant: { id: currentVariant.id },
298
+ quantity
299
+ }]
300
+ })}
301
+ className="add-to-cart"
302
+ >
303
+ 加入购物车
304
+ </button>
305
+
306
+ <button
307
+ onClick={() => buyNow({
308
+ lineItems: [{
309
+ variant: { id: currentVariant.id },
310
+ quantity
311
+ }],
312
+ gtmParams: {
313
+ currency: 'USD',
314
+ value: parseFloat(currentVariant.price.amount) * quantity,
315
+ items: [{
316
+ item_id: product.id,
317
+ item_name: product.title,
318
+ price: parseFloat(currentVariant.price.amount),
319
+ quantity
320
+ }]
321
+ }
322
+ })}
323
+ className="buy-now"
324
+ >
325
+ 立即购买
326
+ </button>
327
+ </div>
328
+ </div>
329
+ </div>
330
+ )
331
+ }
332
+ ```
333
+
334
+ ## 高级功能示例
335
+
336
+ ### 使用购物车特性 Hooks
337
+
338
+ ```tsx
339
+ import {
340
+ useCartAttributes,
341
+ usePriceDiscount,
342
+ useCalcOrderDiscount,
343
+ useCartItemQuantityLimit
344
+ } from '@anker-in/lib'
345
+
346
+ function AdvancedCart() {
347
+ // 购物车自定义属性
348
+ const { attributes, updateAttribute } = useCartAttributes()
349
+
350
+ // 价格折扣
351
+ const { discountedPrice } = usePriceDiscount()
352
+
353
+ // 订单折扣计算
354
+ const { orderDiscount } = useCalcOrderDiscount()
355
+
356
+ // 数量限制
357
+ const { maxQuantity, isLimitReached } = useCartItemQuantityLimit()
358
+
359
+ return (
360
+ <div>
361
+ {/* 使用这些 hooks 的数据 */}
362
+ </div>
363
+ )
364
+ }
365
+ ```
366
+
367
+ ### 自定义埋点
368
+
369
+ ```tsx
370
+ import { useBuyNow } from '@anker-in/lib'
371
+
372
+ function CustomTracking() {
373
+ const { trigger: buyNow } = useBuyNow({
374
+ withTrack: false // 禁用默认埋点
375
+ })
376
+
377
+ const handleBuyNow = async () => {
378
+ // 自定义埋点逻辑
379
+ window.dataLayer?.push({
380
+ event: 'custom_buy_now',
381
+ // ... 自定义数据
382
+ })
383
+
384
+ await buyNow({
385
+ lineItems: [/* ... */],
386
+ fbqTrackConfig: {
387
+ // Facebook Pixel 配置
388
+ content_ids: ['product-123'],
389
+ content_type: 'product',
390
+ value: 99.99,
391
+ currency: 'USD'
392
+ }
393
+ })
394
+ }
395
+
396
+ return <button onClick={handleBuyNow}>购买</button>
397
+ }
398
+ ```
399
+
400
+ ## TypeScript 支持
401
+
402
+ 所有导出的类型都可以直接使用:
403
+
404
+ ```tsx
405
+ import type {
406
+ Product,
407
+ Cart,
408
+ CartLine,
409
+ HeadlessConfig,
410
+ BuyNowArgs,
411
+ // ... 更多类型
412
+ } from '@anker-in/lib'
413
+
414
+ const config: HeadlessConfig = {
415
+ storefrontToken: '...',
416
+ storeDomain: '...',
417
+ // ...
418
+ }
419
+
420
+ function handleProduct(product: Product) {
421
+ // TypeScript 完整支持
422
+ }
423
+ ```
424
+
425
+
@@ -0,0 +1,11 @@
1
+ export * from '@anker-in/shared';
2
+ export * from '@anker-in/shopify';
3
+ export * from '@anker-in/cart';
4
+
5
+ /**
6
+ * 这是一个demo 模版
7
+ */
8
+ declare const add: (a: number, b: number) => number;
9
+ declare const subtract: (a: number, b: number) => number;
10
+
11
+ export { add, subtract };
@@ -0,0 +1,11 @@
1
+ export * from '@anker-in/shared';
2
+ export * from '@anker-in/shopify';
3
+ export * from '@anker-in/cart';
4
+
5
+ /**
6
+ * 这是一个demo 模版
7
+ */
8
+ declare const add: (a: number, b: number) => number;
9
+ declare const subtract: (a: number, b: number) => number;
10
+
11
+ export { add, subtract };
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ add: () => add,
25
+ subtract: () => subtract
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/math.ts
30
+ var add = (a, b) => a + b;
31
+ var subtract = (a, b) => a - b;
32
+
33
+ // src/index.ts
34
+ __reExport(index_exports, require("@anker-in/shared"), module.exports);
35
+ __reExport(index_exports, require("@anker-in/shopify"), module.exports);
36
+ __reExport(index_exports, require("@anker-in/cart"), module.exports);
37
+ // Annotate the CommonJS export names for ESM import in node:
38
+ 0 && (module.exports = {
39
+ add,
40
+ subtract,
41
+ ...require("@anker-in/shared"),
42
+ ...require("@anker-in/shopify"),
43
+ ...require("@anker-in/cart")
44
+ });
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/math.ts"],"sourcesContent":["// 导出本地功能\nexport * from './math'\n\n// 重新导出所有包的内容(作为便利导出)\nexport * from '@anker-in/shared'\nexport * from '@anker-in/shopify'\nexport * from '@anker-in/cart'\n","/**\n * 这是一个demo 模版\n */\nexport const add = (a: number, b: number) => a + b\nexport const subtract = (a: number, b: number) => a - b\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,IAAM,MAAM,CAAC,GAAW,MAAc,IAAI;AAC1C,IAAM,WAAW,CAAC,GAAW,MAAc,IAAI;;;ADAtD,0BAAc,6BAJd;AAKA,0BAAc,8BALd;AAMA,0BAAc,2BANd;","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,13 @@
1
+ // src/math.ts
2
+ var add = (a, b) => a + b;
3
+ var subtract = (a, b) => a - b;
4
+
5
+ // src/index.ts
6
+ export * from "@anker-in/shared";
7
+ export * from "@anker-in/shopify";
8
+ export * from "@anker-in/cart";
9
+ export {
10
+ add,
11
+ subtract
12
+ };
13
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/math.ts","../src/index.ts"],"sourcesContent":["/**\n * 这是一个demo 模版\n */\nexport const add = (a: number, b: number) => a + b\nexport const subtract = (a: number, b: number) => a - b\n","// 导出本地功能\nexport * from './math'\n\n// 重新导出所有包的内容(作为便利导出)\nexport * from '@anker-in/shared'\nexport * from '@anker-in/shopify'\nexport * from '@anker-in/cart'\n"],"mappings":";AAGO,IAAM,MAAM,CAAC,GAAW,MAAc,IAAI;AAC1C,IAAM,WAAW,CAAC,GAAW,MAAc,IAAI;;;ACAtD,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
package/jest.config.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { JestConfigWithTsJest } from 'ts-jest'
2
+
3
+ const config: JestConfigWithTsJest = {
4
+ preset: 'ts-jest',
5
+ testEnvironment: 'jsdom', // 使用 node 环境(如果是浏览器库可改成 'jsdom')
6
+ clearMocks: true, // 每次测试后自动清除 mock
7
+ coverageDirectory: 'coverage', // 输出覆盖率报告
8
+ testMatch: ['**/__tests__/**/*.test.ts'], // 匹配测试文件路径
9
+ moduleFileExtensions: ['ts', 'js', 'json'],
10
+ }
11
+
12
+ export default config
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@anker-in/lib",
3
+ "version": "1.0.0-beta.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "dependencies": {
7
+ "@anker-in/shared": "1.0.0",
8
+ "@anker-in/shopify": "0.0.0-beta.4",
9
+ "@anker-in/cart": "1.0.0"
10
+ },
11
+ "devDependencies": {
12
+ "@types/jest": "^29.5.12",
13
+ "@types/react": "^18.3.3",
14
+ "jest": "^29.0.0",
15
+ "ts-jest": "^29.2.6",
16
+ "tsup": "^8.4.0",
17
+ "typescript": "^5.0.0"
18
+ },
19
+ "peerDependencies": {
20
+ "react": "^18.0.0",
21
+ "react-dom": "^18.0.0"
22
+ },
23
+ "scripts": {
24
+ "dev": "tsup --watch",
25
+ "build": "tsup",
26
+ "test": "jest --passWithNoTests",
27
+ "test:watch": "jest --watch",
28
+ "coverage": "jest --coverage",
29
+ "clean": "rm -rf .turbo node_modules dist"
30
+ }
31
+ }
@@ -0,0 +1,15 @@
1
+ import { add, subtract } from '../math'
2
+
3
+ describe('math functions', () => {
4
+ test('add should correctly add two numbers', () => {
5
+ expect(add(2, 3)).toBe(5)
6
+ expect(add(-1, -1)).toBe(-2)
7
+ expect(add(0, 5)).toBe(5)
8
+ })
9
+
10
+ test('subtract should correctly subtract two numbers', () => {
11
+ expect(subtract(5, 3)).toBe(2)
12
+ expect(subtract(0, 5)).toBe(-5)
13
+ expect(subtract(-1, -1)).toBe(0)
14
+ })
15
+ })
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ // 导出本地功能
2
+ export * from './math'
3
+
4
+ // 重新导出所有包的内容(作为便利导出)
5
+ export * from '@anker-in/shared'
6
+ export * from '@anker-in/shopify'
7
+ export * from '@anker-in/cart'
package/src/math.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 这是一个demo 模版
3
+ */
4
+ export const add = (a: number, b: number) => a + b
5
+ export const subtract = (a: number, b: number) => a - b
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "target": "esnext",
6
+ "module": "esnext",
7
+ "moduleResolution": "bundler",
8
+ "declaration": true,
9
+ "declarationMap": true,
10
+ "sourceMap": true,
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "lib": ["DOM", "ESNext", "DOM.Iterable"],
14
+ "skipLibCheck": true,
15
+ "jsx": "react-jsx",
16
+ "types": ["jest", "node"]
17
+ },
18
+ "include": ["src"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm', 'cjs'],
6
+ dts: true,
7
+ splitting: false,
8
+ sourcemap: true,
9
+ clean: true,
10
+ external: [
11
+ 'react',
12
+ 'react-dom',
13
+ '@anker-in/shared',
14
+ '@anker-in/shopify',
15
+ '@anker-in/cart',
16
+ 'next/router',
17
+ '@sentry/nextjs',
18
+ 'swr',
19
+ ],
20
+ })