feeef 0.8.10 → 0.8.13

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.
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Pure utility class for estimating AI generation costs client-side.
3
+ *
4
+ * Mirrors the backend `AiCalculator` in `backend/app/services/ai_calculator.ts`.
5
+ * All methods are deterministic and require no network calls.
6
+ * The backend quote is authoritative; this calculator is a deterministic
7
+ * mirror for UX (showing estimated cost before the user clicks generate).
8
+ *
9
+ * Canonical `aiModels.billing` keys — keep in sync: backend `configs_controller.ts`,
10
+ * feeef `lib/core/app_config.dart`, admins_dashboard `src/lib/hooks/useOptions.ts`.
11
+ */
12
+ /** Fallback DZD per USD when `aiModels.exchangeRate` is missing (mirror backend). */
13
+ export declare const FALLBACK_AI_EXCHANGE_RATE = 260;
14
+ export interface RetailMarkupBilling {
15
+ multiplier?: number;
16
+ }
17
+ export interface ReferenceAttachmentSurchargeBilling {
18
+ perFileUsd?: number;
19
+ highResolutionExtraPerFileUsd?: number;
20
+ lowResolutionDiscountPerFileUsd?: number;
21
+ }
22
+ export interface ImageGenerationBilling {
23
+ fallbackProviderCostPerImageUsd?: number;
24
+ }
25
+ export interface TextGenerationBilling {
26
+ freeTierMaxPromptTokens?: number;
27
+ estimatedPromptTokensDefault?: number;
28
+ estimatedOutputTokensDefault?: number;
29
+ }
30
+ export interface TtsTokenEstimateBilling {
31
+ whenScriptEmptyTokens?: number;
32
+ whenAttachmentsOnlyTokens?: number;
33
+ promptBaseTokens?: number;
34
+ promptPerAttachmentTokens?: number;
35
+ outputMinimumTokens?: number;
36
+ outputToTextTokenRatio?: number;
37
+ maxTotalTokens?: number;
38
+ }
39
+ export interface VoiceGenerationBilling {
40
+ minimumChargeUsd?: number;
41
+ scriptEnhancementAddonUsd?: number;
42
+ ttsTokenEstimate?: TtsTokenEstimateBilling;
43
+ }
44
+ export interface LandingPageImageBilling {
45
+ fixedChargeUsd?: number;
46
+ }
47
+ export interface AIModelsBilling {
48
+ retailMarkup?: RetailMarkupBilling;
49
+ referenceAttachmentSurcharge?: ReferenceAttachmentSurchargeBilling;
50
+ imageGeneration?: ImageGenerationBilling;
51
+ textGeneration?: TextGenerationBilling;
52
+ voiceGeneration?: VoiceGenerationBilling;
53
+ landingPageImage?: LandingPageImageBilling;
54
+ }
55
+ /** Fully resolved billing after merge (stable export for callers/tests). */
56
+ export interface ResolvedAiModelsBilling {
57
+ retailMarkup: {
58
+ multiplier: number;
59
+ };
60
+ referenceAttachmentSurcharge: {
61
+ perFileUsd: number;
62
+ highResolutionExtraPerFileUsd: number;
63
+ lowResolutionDiscountPerFileUsd: number;
64
+ };
65
+ imageGeneration: {
66
+ fallbackProviderCostPerImageUsd: number;
67
+ };
68
+ textGeneration: {
69
+ freeTierMaxPromptTokens: number;
70
+ estimatedPromptTokensDefault: number;
71
+ estimatedOutputTokensDefault: number;
72
+ };
73
+ voiceGeneration: {
74
+ minimumChargeUsd: number;
75
+ scriptEnhancementAddonUsd: number;
76
+ ttsTokenEstimate: Required<TtsTokenEstimateBilling>;
77
+ };
78
+ landingPageImage: {
79
+ fixedChargeUsd: number;
80
+ };
81
+ }
82
+ /**
83
+ * Deep-merge optional server `billing` over platform defaults.
84
+ * Omit or pass `null` to get code defaults only.
85
+ */
86
+ export declare function mergeAiModelsBilling(partial?: AIModelsBilling | null): ResolvedAiModelsBilling;
87
+ /** Legacy flat keys for older importers (DZD leaves use `exchangeRate`). */
88
+ export interface LegacyAiBillingFlat {
89
+ MULTIPLIER: number;
90
+ FREE_TEXT_TOKENS_THRESHOLD: number;
91
+ DEFAULT_EXCHANGE_RATE: number;
92
+ DEFAULT_GOOGLE_IMAGE_COST_USD: number;
93
+ DEFAULT_ATTACHMENT_COST_USD: number;
94
+ ATTACHMENT_HIGH_RES_EXTRA_USD: number;
95
+ ATTACHMENT_LOW_RES_DISCOUNT_USD: number;
96
+ VOICEOVER_FIXED_COST_DZD: number;
97
+ VOICEOVER_ENHANCE_ADDON_DZD: number;
98
+ IMAGE_LANDING_PAGE_FIXED_COST_DZD: number;
99
+ DEFAULT_TEXT_PROMPT_TOKENS: number;
100
+ DEFAULT_TEXT_OUTPUT_TOKENS: number;
101
+ VOICE_TTS_EMPTY_SCRIPT_TEXT_TOKENS: number;
102
+ VOICE_TTS_ATTACHMENT_ONLY_TEXT_TOKENS: number;
103
+ VOICE_TTS_PROMPT_BASE: number;
104
+ VOICE_TTS_PROMPT_PER_ATTACHMENT: number;
105
+ VOICE_TTS_OUTPUT_MIN: number;
106
+ VOICE_TTS_OUTPUT_TEXT_FACTOR: number;
107
+ VOICE_TTS_TOKEN_CAP: number;
108
+ }
109
+ export declare function getLegacyAiBillingFlat(exchangeRate: number, resolved?: ResolvedAiModelsBilling): LegacyAiBillingFlat;
110
+ /**
111
+ * @deprecated Prefer `mergeAiModelsBilling` + `ResolvedAiModelsBilling`.
112
+ * Snapshot of defaults at `FALLBACK_AI_EXCHANGE_RATE` for DZD-derived fields.
113
+ */
114
+ export declare const AI_BILLING: LegacyAiBillingFlat;
115
+ export interface AiModelPricing {
116
+ input?: number;
117
+ output?: number;
118
+ unit: string;
119
+ contextThreshold?: string;
120
+ }
121
+ /**
122
+ * Optional operator overrides for Gemini image-generation Google Search grounding.
123
+ * Shapes `aiModels.models[].tools` from the app config API — same as backend `AIModel.tools`.
124
+ * Undefined keys mean “use platform default for this model id” (see backend `gemini_image_grounding`).
125
+ */
126
+ export interface AiModelTools {
127
+ googleSearch?: boolean;
128
+ googleImageSearch?: boolean;
129
+ }
130
+ export interface AiModelConfig {
131
+ id: string;
132
+ pricing?: AiModelPricing[];
133
+ localCost?: number | null;
134
+ /** From aiModels — used so TTS billing does not fall back to the first (often image) row. */
135
+ capabilities?: string[];
136
+ tools?: AiModelTools;
137
+ }
138
+ export interface AiCalculatorConfig {
139
+ exchangeRate?: number;
140
+ defaultImageCost?: number;
141
+ referenceImageCost?: number;
142
+ resolutionCosts?: Record<string, number>;
143
+ models?: AiModelConfig[];
144
+ /** Optional `aiModels.billing` overrides (merged over [mergeAiModelsBilling] defaults). */
145
+ billing?: AIModelsBilling | null;
146
+ }
147
+ export interface AiCostEstimate {
148
+ providerCostUsd: number;
149
+ providerCostDzd: number;
150
+ userCostDzd: number;
151
+ exchangeRate: number;
152
+ multiplier: number;
153
+ usedLocalCost: boolean;
154
+ breakdown: Record<string, number | boolean>;
155
+ }
156
+ /** Keep in sync with backend `defaultVoiceTtsTokenEstimates` (default billing only). */
157
+ export declare function defaultVoiceTtsTokenEstimates(scriptCharLength: number, attachmentCount: number): {
158
+ promptTokens: number;
159
+ outputTokens: number;
160
+ };
161
+ export declare class AiCalculator {
162
+ private config;
163
+ constructor(config?: AiCalculatorConfig);
164
+ /** TTS base DZD: localCost → flat USD row → tokens (per 1M) × estimates × rate × multiplier → floor. */
165
+ private _voiceoverBaseUserCostDzd;
166
+ private _attachmentExtraUserDzd;
167
+ /**
168
+ * Estimate the cost of an image generation action.
169
+ * Covers: image gen, logo gen, editOrGenerateSimpleImage.
170
+ */
171
+ estimateImageGeneration(options?: {
172
+ modelId?: string;
173
+ attachmentCount?: number;
174
+ attachmentResolution?: 'low' | 'medium' | 'high';
175
+ resolution?: string;
176
+ imageSize?: string;
177
+ iterations?: number;
178
+ referenceImageCount?: number;
179
+ }): AiCostEstimate;
180
+ /**
181
+ * Estimate the cost of a text generation action.
182
+ * Covers: updateProductUsingAi, generateSimpleCode, generateCustomComponentCode.
183
+ * Uses estimated tokens (exact cost billed post-generation).
184
+ */
185
+ estimateTextGeneration(options?: {
186
+ modelId?: string;
187
+ estimatedPromptTokens?: number;
188
+ estimatedOutputTokens?: number;
189
+ }): AiCostEstimate;
190
+ /**
191
+ * Voiceover: base + attachment surcharge + optional script-enhancement add-on.
192
+ */
193
+ estimateVoiceover(options?: {
194
+ modelId?: string;
195
+ attachmentCount?: number;
196
+ attachmentResolution?: 'low' | 'medium' | 'high';
197
+ enhanceScript?: boolean;
198
+ scriptCharLength?: number;
199
+ estimatedPromptTokens?: number;
200
+ estimatedOutputTokens?: number;
201
+ }): AiCostEstimate;
202
+ /** Get the fixed cost for image landing page generation. */
203
+ estimateImageLandingPage(): AiCostEstimate;
204
+ }
@@ -58,9 +58,21 @@ export interface OrderEntity {
58
58
  deliveryStatus: DeliveryStatus;
59
59
  customStatus?: string | null;
60
60
  tags: string[] | null;
61
+ /**
62
+ * Attribution tokens: `product:…`, `product_landing_page:…`.
63
+ * JSON / API field name is always **`references`** (never `orderReferences`).
64
+ */
65
+ references?: string[];
61
66
  createdAt: any;
62
67
  updatedAt: any;
63
68
  }
69
+ /** Lite orders report (8 UTC days + total), API key `lor`. */
70
+ export interface LiteOrdersReport {
71
+ lastSync: string;
72
+ lastItemDate: string;
73
+ totalOrders: number;
74
+ data: [number, number, number][];
75
+ }
64
76
  export interface OrderItem {
65
77
  productId: string;
66
78
  productName: string;
@@ -135,6 +147,7 @@ export interface OrderCreateInput {
135
147
  metadata?: Record<string, any>;
136
148
  storeId: string;
137
149
  tags?: string[];
150
+ references?: string[];
138
151
  }
139
152
  /**
140
153
  * Input for order items when creating/updating an order
@@ -180,6 +193,7 @@ export interface OrderUpdateInput {
180
193
  customFields?: Record<string, any>;
181
194
  metadata?: Record<string, any>;
182
195
  tags?: string[];
196
+ references?: string[];
183
197
  }
184
198
  /**
185
199
  * Order pricing calculation result
@@ -268,3 +268,5 @@ export interface ProductReport {
268
268
  }>;
269
269
  salesByDate?: Record<string, number>;
270
270
  }
271
+ /** Token for `Order.references`. */
272
+ export declare function formatProductOrderReference(productId: string): string;
@@ -35,3 +35,5 @@ export interface ProductLandingPageUpdate {
35
35
  productId: string | null;
36
36
  storeId?: string;
37
37
  }
38
+ /** Token for `Order.references`. */
39
+ export declare function formatProductLandingPageOrderReference(landingPageId: string): string;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Logical client surface for carrier integrations — mirrors backend `DeliveryService`
3
+ * (`feeefapps/backend/services/delivery/delivery_service.ts`).
4
+ */
5
+ import type { ParcelCreate, ParcelUpdate } from './parcel.js';
6
+ export interface DeliveryCarrierClient {
7
+ readonly providerId: string;
8
+ send(parcel: ParcelCreate): Promise<Record<string, unknown>>;
9
+ sendMany(parcels: ParcelCreate[]): Promise<Record<string, unknown>>;
10
+ unsend(trackingOrCarrierId: string): Promise<unknown>;
11
+ unsendMany(ids: string[]): Promise<unknown>;
12
+ update(input: ParcelUpdate): Promise<unknown>;
13
+ updateMany(updates: ParcelUpdate[]): Promise<unknown>;
14
+ delete(id: string): Promise<unknown>;
15
+ deleteMany(ids: string[]): Promise<unknown>;
16
+ label(tracking: string, options?: Record<string, unknown>): Promise<unknown>;
17
+ labels(ids: string[], options?: Record<string, unknown>): Promise<unknown>;
18
+ show(id: string): Promise<unknown>;
19
+ list(query?: Record<string, unknown>): Promise<unknown>;
20
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Canonical parcel domain types — keep aligned with
3
+ * `feeefapps/backend/services/delivery/domain/parcel.ts`.
4
+ *
5
+ * npm package name is `feeef`; this repo is the JS SDK source (`feeefjs`).
6
+ */
7
+ import type { ShippingType as FeeefShippingType } from '../core/entities/order.js';
8
+ /** Same enum as platform `Order.shippingType` / npm `feeef` `ShippingType`. */
9
+ export type ParcelShippingType = FeeefShippingType;
10
+ export interface ParcelLineItem {
11
+ name: string;
12
+ quantity: number;
13
+ price?: number | null;
14
+ variantPath?: string | null;
15
+ }
16
+ export interface ParcelContact {
17
+ firstName?: string | null;
18
+ lastName?: string | null;
19
+ phones?: string[];
20
+ emails?: string[];
21
+ }
22
+ export interface ParcelAddress {
23
+ street: string | null;
24
+ cityCode: string | null;
25
+ stateCode: string | null;
26
+ country: string | null;
27
+ note?: string | null;
28
+ }
29
+ export type ParcelDimensionUnit = 'cm' | 'm' | 'in';
30
+ export type ParcelWeightUnit = 'kg' | 'g' | 'lb' | 'oz';
31
+ export interface ParcelPackage {
32
+ width?: number | null;
33
+ height?: number | null;
34
+ length?: number | null;
35
+ weight?: number | null;
36
+ fragile?: boolean | null;
37
+ dimensionUnit?: ParcelDimensionUnit | null;
38
+ weightUnit?: ParcelWeightUnit | null;
39
+ }
40
+ /** Shipment category (forward / return / exchange) — field name on `ParcelCreate` is `type`. */
41
+ export type ParcelType = 'forward' | 'return' | 'exchange';
42
+ export interface ParcelUpdate {
43
+ carrierId: string;
44
+ contact?: Partial<ParcelContact>;
45
+ address?: Partial<ParcelAddress>;
46
+ total?: number;
47
+ notes?: string | null;
48
+ summary?: string;
49
+ package?: Partial<ParcelPackage> | null;
50
+ items?: ParcelLineItem[];
51
+ shippingType?: ParcelShippingType | string | null;
52
+ extensions?: Record<string, unknown>;
53
+ }
54
+ export interface ParcelCreate {
55
+ storeId: string;
56
+ reference: string;
57
+ contact: ParcelContact;
58
+ address: ParcelAddress;
59
+ /** Charged / COD amount (typically order total). Legacy JSON: `codAmount`. */
60
+ total: number;
61
+ itemsPrice?: number | null;
62
+ declaredValue: number | null;
63
+ shippingType?: ParcelShippingType | string | null;
64
+ shippingPrice?: number | null;
65
+ freeShipping?: boolean | null;
66
+ /** Stop-desk / hub id (Yalidine `stopdesk_id`, ZR `hubId`). Legacy: `centerId`. */
67
+ pickupId?: string | null;
68
+ fromStock?: boolean | null;
69
+ items: ParcelLineItem[];
70
+ /** Legacy JSON: `productsSummary`. */
71
+ summary: string;
72
+ notes: string | null;
73
+ metadata?: Record<string, unknown>;
74
+ extensions?: Record<string, unknown>;
75
+ package?: ParcelPackage | null;
76
+ /** Legacy JSON: `parcelType`. */
77
+ type?: ParcelType | null;
78
+ }
@@ -32,6 +32,7 @@ export interface SendOrderSchema {
32
32
  storeId: string;
33
33
  customFields?: Record<string, any>;
34
34
  metadata?: any;
35
+ references?: string[];
35
36
  }
36
37
  /**
37
38
  * Schema for guest order items
@@ -96,6 +97,8 @@ export interface OrderListOptions {
96
97
  shippingState?: string;
97
98
  shippingCity?: string;
98
99
  deliveryService?: DeliveryServiceFilter;
100
+ /** Filter orders whose `references` jsonb contains this token (repeat param or comma-separated). */
101
+ references?: string | string[];
99
102
  params?: Record<string, any>;
100
103
  }
101
104
  /**
@@ -1,6 +1,7 @@
1
1
  import { AxiosInstance } from 'axios';
2
2
  import { ModelRepository, ListResponse } from './repository.js';
3
3
  import { ProductLandingPage, ProductLandingPageCreate, ProductLandingPageUpdate } from '../../core/entities/product_landing_page.js';
4
+ import type { LiteOrdersReport } from '../../core/entities/order.js';
4
5
  /**
5
6
  * Options for listing product landing pages
6
7
  */
@@ -27,4 +28,10 @@ export declare class ProductLandingPagesRepository extends ModelRepository<Produ
27
28
  * @returns A Promise that resolves to a list of ProductLandingPage entities.
28
29
  */
29
30
  list(options?: ProductLandingPageListOptions): Promise<ListResponse<ProductLandingPage>>;
31
+ /**
32
+ * Lite orders report for a product landing page in a store.
33
+ */
34
+ liteOrdersReport(storeId: string, landingPageId: string): Promise<{
35
+ lor: LiteOrdersReport;
36
+ }>;
30
37
  }
@@ -1,6 +1,7 @@
1
1
  import { AxiosInstance } from 'axios';
2
2
  import { ModelRepository, ListResponse } from './repository.js';
3
3
  import { ProductEntity, ProductCreateInput, ProductUpdateInput, ProductReport, ProductStatus } from '../../core/entities/product.js';
4
+ import type { LiteOrdersReport } from '../../core/entities/order.js';
4
5
  /**
5
6
  * Options for listing products
6
7
  */
@@ -54,4 +55,10 @@ export declare class ProductRepository extends ModelRepository<ProductEntity, Pr
54
55
  * @returns A Promise that resolves to the product report.
55
56
  */
56
57
  report(productId: string, storeId: string): Promise<ProductReport>;
58
+ /**
59
+ * Lite orders report for a product in a store.
60
+ */
61
+ liteOrdersReport(storeId: string, productId: string): Promise<{
62
+ lor: LiteOrdersReport;
63
+ }>;
57
64
  }
@@ -1,6 +1,7 @@
1
1
  import { AxiosInstance } from 'axios';
2
2
  import { ModelRepository, ListResponse } from './repository.js';
3
3
  import { StoreEntity, StoreSummary, StoreMember, StoreSubscriptionType, AddStoreMemberInput, UpdateStoreMemberInput, StoreCreateInput, StoreUpdateInput } from '../../core/entities/store.js';
4
+ import type { LiteOrdersReport } from '../../core/entities/order.js';
4
5
  import { StoreInvitesRepository } from './store_invites_repository.js';
5
6
  /**
6
7
  * Options for listing stores
@@ -56,6 +57,12 @@ export declare class StoreRepository extends ModelRepository<StoreEntity, StoreC
56
57
  * @returns A Promise that resolves to a map of date to order count.
57
58
  */
58
59
  chart(id: string): Promise<Map<Date, number>>;
60
+ /**
61
+ * Lite orders report for the store (8 UTC days + total).
62
+ */
63
+ liteOrdersReport(storeId: string): Promise<{
64
+ lor: LiteOrdersReport;
65
+ }>;
59
66
  /**
60
67
  * Adds a member to the store.
61
68
  * @param storeId - The store ID.
@@ -1,4 +1,6 @@
1
1
  export * from './feeef/feeef.js';
2
+ export * from './delivery/parcel.js';
3
+ export * from './delivery/delivery_carrier_client.js';
2
4
  export * from './core/entities/order.js';
3
5
  export * from './core/entities/store.js';
4
6
  export * from './core/entities/product.js';
@@ -50,5 +52,6 @@ export * from './feeef/services/notifications.js';
50
52
  export * from './feeef/services/storage.js';
51
53
  export * from './feeef/services/integrations.js';
52
54
  export * from './realtime/index.js';
55
+ export * from './ai/ai_calculator.js';
53
56
  export * from './utils.js';
54
57
  export type { StoreIntegrations } from './core/entities/store.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "feeef",
3
3
  "description": "feeef sdk for javascript",
4
- "version": "0.8.10",
4
+ "version": "0.8.13",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
7
7
  "files": [