feeef 0.12.10 → 0.12.12
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/build/index.js +412 -196
- package/build/index.js.map +1 -1
- package/build/src/ai/ai_calculator.d.ts +149 -25
- package/build/src/core/entities/order.d.ts +2 -0
- package/build/src/core/entities/product.d.ts +4 -0
- package/build/src/core/entities/store.d.ts +239 -4
- package/build/src/core/oauth_scopes.d.ts +20 -0
- package/build/src/feeef/feeef.d.ts +1 -1
- package/build/src/feeef/repositories/apps.d.ts +5 -1
- package/build/src/index.d.ts +1 -0
- package/package.json +2 -2
- package/build/bin/japa_types.d.ts +0 -7
- package/build/bin/test.d.ts +0 -1
|
@@ -1,13 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Client-side AI cost estimator — deterministic mirror of the backend engine
|
|
3
|
+
* in `backend/app/services/ai_calculator.ts`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The backend quote is always authoritative (it performs the wallet debit);
|
|
6
|
+
* this class exists so UIs can show "you will pay X DZD" before generating,
|
|
7
|
+
* with the SAME formulas and the SAME config inputs (`aiModels` + `models`
|
|
8
|
+
* catalog from the app-config endpoint). No network calls, no side effects.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* ## Money model (identical to backend)
|
|
11
|
+
*
|
|
12
|
+
* ```
|
|
13
|
+
* provider cost (USD) what the AI provider charges
|
|
14
|
+
* × exchangeRate → provider cost (DZD)
|
|
15
|
+
* × retailMarkup.multiplier → retail user cost (DZD)
|
|
16
|
+
* + flat retail add-ons (DZD) reference images, resolution tiers,
|
|
17
|
+
* feature add-ons, attachment surcharge…
|
|
18
|
+
* = userCostDzd
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Invariants:
|
|
22
|
+
* 1. `providerCostUsd`/`providerCostDzd` are ALWAYS the pre-markup provider
|
|
23
|
+
* cost; `0` when unknown (retail floors) — never back-computed from the
|
|
24
|
+
* retail price.
|
|
25
|
+
* 2. `userCostDzd` is the final retail amount, rounded to 3 decimals.
|
|
26
|
+
*
|
|
27
|
+
* ## Pricing precedence (identical to backend)
|
|
28
|
+
*
|
|
29
|
+
* - **Text** : legacy exact-id row (context tiers) → catalog
|
|
30
|
+
* `pricing.prompt/completion` → named default legacy row
|
|
31
|
+
* (`gemini-flash-lite-latest`) → free. Never `models[0]`.
|
|
32
|
+
* - **Image** : catalog (`image_output_per_size_usd` → `image_output`) →
|
|
33
|
+
* legacy exact-id `unit:'image'` row → `defaultImageCost` floor.
|
|
34
|
+
* Legacy `localCost` (DZD) stays an explicit retail override.
|
|
35
|
+
* - **Voice** : legacy row (`localCost` → flat `audio`/`voice` USD → `image`
|
|
36
|
+
* unit for voice-capable rows → `tokens` per-1M), floored by
|
|
37
|
+
* `voiceGeneration.minimumChargeUsd` unless `localCost` is set.
|
|
38
|
+
*
|
|
39
|
+
* Canonical `aiModels.billing` keys — keep in sync: backend
|
|
40
|
+
* `ai_models_billing.ts`, feeef.dart `ai_calculator.dart`, admins_dashboard
|
|
41
|
+
* `useOptions.ts`.
|
|
11
42
|
*/
|
|
12
43
|
import { ModelsCatalogConfig } from '../core/models_catalog.js';
|
|
13
44
|
/** Fallback DZD per USD when `aiModels.exchangeRate` is missing (mirror backend). */
|
|
@@ -107,6 +138,7 @@ export interface LegacyAiBillingFlat {
|
|
|
107
138
|
VOICE_TTS_OUTPUT_TEXT_FACTOR: number;
|
|
108
139
|
VOICE_TTS_TOKEN_CAP: number;
|
|
109
140
|
}
|
|
141
|
+
/** @deprecated Prefer `mergeAiModelsBilling` + `ResolvedAiModelsBilling`. */
|
|
110
142
|
export declare function getLegacyAiBillingFlat(exchangeRate: number, resolved?: ResolvedAiModelsBilling): LegacyAiBillingFlat;
|
|
111
143
|
/**
|
|
112
144
|
* @deprecated Prefer `mergeAiModelsBilling` + `ResolvedAiModelsBilling`.
|
|
@@ -114,15 +146,18 @@ export declare function getLegacyAiBillingFlat(exchangeRate: number, resolved?:
|
|
|
114
146
|
*/
|
|
115
147
|
export declare const AI_BILLING: LegacyAiBillingFlat;
|
|
116
148
|
export interface AiModelPricing {
|
|
149
|
+
/** USD per 1M tokens (`unit: 'tokens'`) — `input` prompt / `output` completion. */
|
|
117
150
|
input?: number;
|
|
151
|
+
/** For `unit: 'image' | 'audio' | 'voice'`: USD per single generation. */
|
|
118
152
|
output?: number;
|
|
119
153
|
unit: string;
|
|
154
|
+
/** Optional context tier, e.g. `<=200K` / `>200K` (tokens unit only). */
|
|
120
155
|
contextThreshold?: string;
|
|
121
156
|
}
|
|
122
157
|
/**
|
|
123
158
|
* Optional operator overrides for Gemini image-generation Google Search grounding.
|
|
124
159
|
* Shapes `aiModels.models[].tools` from the app config API — same as backend `AIModel.tools`.
|
|
125
|
-
* Undefined keys mean
|
|
160
|
+
* Undefined keys mean "use platform default for this model id" (see backend `gemini_image_grounding`).
|
|
126
161
|
*/
|
|
127
162
|
export interface AiModelTools {
|
|
128
163
|
googleSearch?: boolean;
|
|
@@ -131,6 +166,7 @@ export interface AiModelTools {
|
|
|
131
166
|
export interface AiModelConfig {
|
|
132
167
|
id: string;
|
|
133
168
|
pricing?: AiModelPricing[];
|
|
169
|
+
/** Explicit admin retail price (DZD) for one generation — overrides computed retail. */
|
|
134
170
|
localCost?: number | null;
|
|
135
171
|
/** From aiModels — used so TTS billing does not fall back to the first (often image) row. */
|
|
136
172
|
capabilities?: string[];
|
|
@@ -138,15 +174,24 @@ export interface AiModelConfig {
|
|
|
138
174
|
}
|
|
139
175
|
export interface AiCalculatorConfig {
|
|
140
176
|
exchangeRate?: number;
|
|
177
|
+
/** Floor retail-provider DZD for one image when no source prices the model. */
|
|
141
178
|
defaultImageCost?: number;
|
|
179
|
+
/** Flat retail DZD per reference image. */
|
|
142
180
|
referenceImageCost?: number;
|
|
181
|
+
/** Flat retail DZD per resolution tier (`MEDIA_RESOLUTION_LOW|MEDIUM|HIGH`). */
|
|
143
182
|
resolutionCosts?: Record<string, number>;
|
|
183
|
+
/** Legacy `aiModels.models` rows (admin overrides). */
|
|
144
184
|
models?: AiModelConfig[];
|
|
145
|
-
/**
|
|
185
|
+
/** Multi-provider catalog (`models` option) — preferred pricing source. */
|
|
146
186
|
modelsCatalog?: ModelsCatalogConfig;
|
|
147
187
|
/** Optional `aiModels.billing` overrides (merged over [mergeAiModelsBilling] defaults). */
|
|
148
188
|
billing?: AIModelsBilling | null;
|
|
149
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Result of a cost estimation.
|
|
192
|
+
* `providerCostUsd`/`providerCostDzd` are pre-markup provider cost (0 when
|
|
193
|
+
* unknown); `userCostDzd` is the retail amount the wallet would be debited.
|
|
194
|
+
*/
|
|
150
195
|
export interface AiCostEstimate {
|
|
151
196
|
providerCostUsd: number;
|
|
152
197
|
providerCostDzd: number;
|
|
@@ -156,34 +201,92 @@ export interface AiCostEstimate {
|
|
|
156
201
|
usedLocalCost: boolean;
|
|
157
202
|
breakdown: Record<string, number | boolean>;
|
|
158
203
|
}
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
204
|
+
/**
|
|
205
|
+
* Deterministic client-side mirror of the backend `AiCalculator`.
|
|
206
|
+
*
|
|
207
|
+
* ```ts
|
|
208
|
+
* const calc = new AiCalculator({ ...appConfig.aiModels, modelsCatalog: appConfig.models })
|
|
209
|
+
* const { userCostDzd } = calc.estimateImageGeneration({ modelId, imageSize: '2K' })
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
164
212
|
export declare class AiCalculator {
|
|
165
213
|
private config;
|
|
166
214
|
constructor(config?: AiCalculatorConfig);
|
|
167
|
-
/**
|
|
168
|
-
private
|
|
169
|
-
private
|
|
215
|
+
/** Exact-id legacy row (namespace tolerant). NO `models[0]` fallback. */
|
|
216
|
+
private findLegacyModel;
|
|
217
|
+
private findCatalogRow;
|
|
218
|
+
private modelHasVoiceCapability;
|
|
219
|
+
/** Context-tier row from a legacy `tokens` pricing list (mirror backend). */
|
|
220
|
+
private pickLegacyTokenRow;
|
|
221
|
+
/** Catalog `pricing.prompt`/`completion` (USD per token) → USD per 1M. */
|
|
222
|
+
private pickCatalogTokenPricing;
|
|
223
|
+
/**
|
|
224
|
+
* USD-per-1M pricing: legacy exact-id → catalog → named default legacy row →
|
|
225
|
+
* `null` (free). Mirrors backend `resolveTextTokenPricing`.
|
|
226
|
+
*/
|
|
227
|
+
private resolveTextTokenPricing;
|
|
228
|
+
/**
|
|
229
|
+
* Catalog per-image USD, preferring the per-tier map
|
|
230
|
+
* (`image_output_per_size_usd`: requested tier → 1K → 2K → 4K → first
|
|
231
|
+
* positive), then flat `image_output`.
|
|
232
|
+
*/
|
|
233
|
+
private pickCatalogImageUsd;
|
|
234
|
+
/** Legacy exact-id `unit:'image'` row output (USD per image). */
|
|
235
|
+
private pickLegacyImageUsd;
|
|
236
|
+
/** Attachment surcharge (stores/products/audio context files) in retail DZD. */
|
|
237
|
+
private attachmentExtraUserDzd;
|
|
170
238
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
239
|
+
* Flat DZD resolution extras — ONE rule, mirror of backend
|
|
240
|
+
* `computeResolutionExtrasDzd`:
|
|
241
|
+
* - output extra only when an output size tier is requested (1K→LOW,
|
|
242
|
+
* 2K→MEDIUM, 4K→HIGH),
|
|
243
|
+
* - input extra only when an explicit input resolution is requested
|
|
244
|
+
* (`max(0, cost[resolution] − cost[LOW])`).
|
|
245
|
+
*/
|
|
246
|
+
private resolutionExtrasDzd;
|
|
247
|
+
/** Voice row: exact id → named TTS default → any voice-capable row. */
|
|
248
|
+
private findVoiceModel;
|
|
249
|
+
/**
|
|
250
|
+
* Flat provider USD per TTS generation: `audio`/`voice` units; for
|
|
251
|
+
* voice-capable rows also the `image` unit (legacy admin editor artifact).
|
|
252
|
+
*/
|
|
253
|
+
private pickTtsFlatUsd;
|
|
254
|
+
/**
|
|
255
|
+
* Base TTS pricing (mirror backend `computeBaseVoiceoverBilling`):
|
|
256
|
+
* `localCost` → flat USD → tokens per-1M → floor; non-localCost paths are
|
|
257
|
+
* floored by `voiceGeneration.minimumChargeUsd`. Provider cost is honest
|
|
258
|
+
* (0 when only a retail figure is known).
|
|
259
|
+
*/
|
|
260
|
+
private voiceoverBase;
|
|
261
|
+
private ttsTokenEstimates;
|
|
262
|
+
/**
|
|
263
|
+
* Image generation cost (image studio, logo studio, landing-page image).
|
|
264
|
+
*
|
|
265
|
+
* `userCostDzd = base(model, tier) × iterations + referenceImages ×
|
|
266
|
+
* referenceImageCost + attachment surcharge + resolution extras + feature
|
|
267
|
+
* add-ons`. Base precedence: catalog → legacy `unit:'image'` row →
|
|
268
|
+
* `defaultImageCost` floor; legacy `localCost` overrides retail.
|
|
173
269
|
*/
|
|
174
270
|
estimateImageGeneration(options?: {
|
|
175
271
|
modelId?: string;
|
|
176
272
|
attachmentCount?: number;
|
|
177
273
|
attachmentResolution?: 'low' | 'medium' | 'high';
|
|
274
|
+
/** Explicit input/reference processing resolution (input extra). */
|
|
178
275
|
resolution?: string;
|
|
276
|
+
/**
|
|
277
|
+
* Effective output size tier (`1K`/`2K`/`4K`). Pass only for models that
|
|
278
|
+
* support output tiers — the backend resolves it via `pickImageSize`.
|
|
279
|
+
*/
|
|
179
280
|
imageSize?: string;
|
|
180
281
|
iterations?: number;
|
|
181
282
|
referenceImageCount?: number;
|
|
283
|
+
/** Catalog-driven feature add-ons (DZD), e.g. transparent background. */
|
|
284
|
+
featureAddonsDzd?: number;
|
|
182
285
|
}): AiCostEstimate;
|
|
183
286
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
287
|
+
* Text generation estimate (actual billing happens post-success from real
|
|
288
|
+
* token usage on the backend). Free when the model is unpriced everywhere
|
|
289
|
+
* or `promptTokens < freeTierMaxPromptTokens` (prompt tokens — not total).
|
|
187
290
|
*/
|
|
188
291
|
estimateTextGeneration(options?: {
|
|
189
292
|
modelId?: string;
|
|
@@ -191,7 +294,10 @@ export declare class AiCalculator {
|
|
|
191
294
|
estimatedOutputTokens?: number;
|
|
192
295
|
}): AiCostEstimate;
|
|
193
296
|
/**
|
|
194
|
-
* Voiceover: base
|
|
297
|
+
* Voiceover estimate: TTS base (heuristic tokens unless explicitly given) +
|
|
298
|
+
* attachment surcharge + optional script-enhancement add-on. The backend
|
|
299
|
+
* settles from ACTUAL usage (`computeVoiceoverSettlement`); this preview
|
|
300
|
+
* uses the same retail policy.
|
|
195
301
|
*/
|
|
196
302
|
estimateVoiceover(options?: {
|
|
197
303
|
modelId?: string;
|
|
@@ -202,6 +308,24 @@ export declare class AiCalculator {
|
|
|
202
308
|
estimatedPromptTokens?: number;
|
|
203
309
|
estimatedOutputTokens?: number;
|
|
204
310
|
}): AiCostEstimate;
|
|
205
|
-
/**
|
|
206
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Landing-page image cost — identical formula to [estimateImageGeneration]
|
|
313
|
+
* (image-studio parity). Without an image model id, returns the fixed
|
|
314
|
+
* `billing.landingPageImage` charge (provider cost unknown → 0). A ≤ 0
|
|
315
|
+
* image quote also falls back to the fixed charge (zero-guard).
|
|
316
|
+
*/
|
|
317
|
+
estimateImageLandingPage(options?: {
|
|
318
|
+
imageModelId?: string;
|
|
319
|
+
attachmentCount?: number;
|
|
320
|
+
attachmentResolution?: 'low' | 'medium' | 'high';
|
|
321
|
+
resolution?: string;
|
|
322
|
+
imageSize?: string;
|
|
323
|
+
referenceImageCount?: number;
|
|
324
|
+
featureAddonsDzd?: number;
|
|
325
|
+
}): AiCostEstimate;
|
|
207
326
|
}
|
|
327
|
+
/** Heuristic TTS token counts using **default** billing only (keep in sync with backend). */
|
|
328
|
+
export declare function defaultVoiceTtsTokenEstimates(scriptCharLength: number, attachmentCount: number): {
|
|
329
|
+
promptTokens: number;
|
|
330
|
+
outputTokens: number;
|
|
331
|
+
};
|
|
@@ -3,6 +3,8 @@ export declare enum OrderStatus {
|
|
|
3
3
|
pending = "pending",
|
|
4
4
|
review = "review",
|
|
5
5
|
accepted = "accepted",
|
|
6
|
+
/** Confirmed, but still needs merchant action before processing/completed. */
|
|
7
|
+
followup = "followup",
|
|
6
8
|
processing = "processing",
|
|
7
9
|
completed = "completed",
|
|
8
10
|
cancelled = "cancelled"
|
|
@@ -303,6 +303,10 @@ export interface ProductUpdateInput {
|
|
|
303
303
|
type?: ProductType;
|
|
304
304
|
decoration?: ProductDecoration;
|
|
305
305
|
integrationsData?: IntegrationsData;
|
|
306
|
+
/** Moderation (admin): ISO date to verify, null to unverify. */
|
|
307
|
+
verifiedAt?: string | null;
|
|
308
|
+
/** Moderation (admin): ISO date to block, null to unblock. */
|
|
309
|
+
blockedAt?: string | null;
|
|
306
310
|
}
|
|
307
311
|
/**
|
|
308
312
|
* Product report/analytics data
|
|
@@ -48,7 +48,19 @@ export interface StoreEntity {
|
|
|
48
48
|
/** Linked inventory project ID for stock management. */
|
|
49
49
|
projectId?: string | null;
|
|
50
50
|
}
|
|
51
|
-
export declare const generatePublicStoreIntegrations: (integrations: StoreIntegrations | null | undefined
|
|
51
|
+
export declare const generatePublicStoreIntegrations: (integrations: StoreIntegrations | null | undefined,
|
|
52
|
+
/**
|
|
53
|
+
* Optional store configs — used to expose inventory storefront flags
|
|
54
|
+
* (`show_unavailable_on_frontend`) on {@link PublicInventoryIntegration}.
|
|
55
|
+
*/
|
|
56
|
+
configs?: Pick<StoreConfigs, "inventory_integration"> | StoreConfigs | null) => PublicStoreIntegrations | null;
|
|
57
|
+
/**
|
|
58
|
+
* Public inventory module (no project credentials).
|
|
59
|
+
* Storefront OOS UI runs only when `active` and `showUnavailableOnFrontend`.
|
|
60
|
+
*/
|
|
61
|
+
export declare const generatePublicStoreIntegrationInventory: (inventory: StoreInventoryIntegration | null | undefined, options?: {
|
|
62
|
+
showUnavailableOnFrontend?: boolean;
|
|
63
|
+
}) => PublicInventoryIntegration | null | undefined;
|
|
52
64
|
/** Strips connector auth secrets from public store JSON. */
|
|
53
65
|
export declare const generatePublicStoreIntegrationConnectors: (connectors: ConnectorsIntegration | null | undefined) => PublicConnectorsIntegration | null | undefined;
|
|
54
66
|
export declare const generatePublicStoreIntegrationCustomFields: (customFields: any | null | undefined) => PublicCustomFieldsIntegration | null | undefined;
|
|
@@ -191,7 +203,24 @@ export interface PublicPaymentIntegration {
|
|
|
191
203
|
methods: PublicPaymentMethod[];
|
|
192
204
|
defaultMethod?: string;
|
|
193
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Public inventory module — no project / warehouse secrets.
|
|
208
|
+
* Combined with effective-active (entitlement) on store serialization.
|
|
209
|
+
*
|
|
210
|
+
* Storefront must only fetch/apply OOS when `active && showUnavailableOnFrontend`.
|
|
211
|
+
*/
|
|
212
|
+
export interface PublicInventoryIntegration {
|
|
213
|
+
active: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* When true, storefront shows unavailable variants (live qty / legacy stock).
|
|
216
|
+
* Opt-in via `configs.inventory_integration.show_unavailable_on_frontend`.
|
|
217
|
+
* @default false
|
|
218
|
+
*/
|
|
219
|
+
showUnavailableOnFrontend: boolean;
|
|
220
|
+
}
|
|
194
221
|
export interface PublicStoreIntegrations {
|
|
222
|
+
/** Global Meta integration; credentials and ad accounts never included. */
|
|
223
|
+
meta: PublicMetaIntegration | null;
|
|
195
224
|
metaPixel: PublicMetaPixelIntegration | null;
|
|
196
225
|
tiktokPixel: PublicTiktokPixelIntegration | null;
|
|
197
226
|
googleAnalytics: PublicGoogleAnalyticsIntegration | null;
|
|
@@ -206,6 +235,11 @@ export interface PublicStoreIntegrations {
|
|
|
206
235
|
customFields: PublicCustomFieldsIntegration | null;
|
|
207
236
|
payment: PublicPaymentIntegration | null;
|
|
208
237
|
connectors: PublicConnectorsIntegration | null;
|
|
238
|
+
/**
|
|
239
|
+
* Inventory module. Storefront OOS checks require `active` and
|
|
240
|
+
* `showUnavailableOnFrontend` (merchant opt-in).
|
|
241
|
+
*/
|
|
242
|
+
inventory: PublicInventoryIntegration | null;
|
|
209
243
|
}
|
|
210
244
|
export declare enum StoreMemberRole {
|
|
211
245
|
editor = "editor",
|
|
@@ -221,6 +255,12 @@ export interface StoreMember {
|
|
|
221
255
|
createdAt: any;
|
|
222
256
|
active: boolean;
|
|
223
257
|
metadata: Record<string, any>;
|
|
258
|
+
/**
|
|
259
|
+
* Fine-grained RBAC scopes (e.g. `orders`, `products.read`, `store.integrations`).
|
|
260
|
+
* Empty/undefined = legacy unrestricted access for the member's role.
|
|
261
|
+
* Parent scopes imply `.read` children (`orders` ⇒ `orders.read`).
|
|
262
|
+
*/
|
|
263
|
+
scopes?: string[];
|
|
224
264
|
}
|
|
225
265
|
export declare enum StoreInviteStatus {
|
|
226
266
|
pending = "pending",
|
|
@@ -245,12 +285,16 @@ export interface StoreInvite {
|
|
|
245
285
|
name: string;
|
|
246
286
|
iconUrl?: string;
|
|
247
287
|
};
|
|
288
|
+
/** RBAC scopes copied onto the member when the invite is accepted. */
|
|
289
|
+
scopes?: string[];
|
|
248
290
|
}
|
|
249
291
|
export interface CreateStoreInviteInput {
|
|
250
292
|
email: string;
|
|
251
293
|
role: StoreMemberRole;
|
|
252
294
|
expiresAt?: string;
|
|
253
295
|
metadata?: Record<string, any>;
|
|
296
|
+
/** RBAC scopes to grant on acceptance (see {@link StoreMember.scopes}). */
|
|
297
|
+
scopes?: string[];
|
|
254
298
|
}
|
|
255
299
|
/** How order sync handles line items with no inventory bucket for their SKU. */
|
|
256
300
|
export type MissingInventoryBucketPolicy = 'ignore' | 'reject';
|
|
@@ -278,6 +322,12 @@ export interface InventoryIntegration {
|
|
|
278
322
|
* @default true
|
|
279
323
|
*/
|
|
280
324
|
allow_backorder?: boolean;
|
|
325
|
+
/**
|
|
326
|
+
* When true (and inventory public integration is active), the storefront
|
|
327
|
+
* fetches live availability and marks out-of-stock variants.
|
|
328
|
+
* @default false
|
|
329
|
+
*/
|
|
330
|
+
show_unavailable_on_frontend?: boolean;
|
|
281
331
|
}
|
|
282
332
|
export type FinancePdfPaperSize = 'a4' | 'letter' | 'a5' | 'legal';
|
|
283
333
|
/** Layout and content options for finance PDF documents. */
|
|
@@ -312,6 +362,7 @@ export interface StoreConfigs {
|
|
|
312
362
|
customStatusMappings?: CustomStatusMapping[];
|
|
313
363
|
/** Feature flag to enable custom statuses across the app */
|
|
314
364
|
customStatusEnabled?: boolean;
|
|
365
|
+
confirmationQueue?: ConfirmationQueueConfig;
|
|
315
366
|
inventory_integration?: InventoryIntegration;
|
|
316
367
|
finance_integration?: FinanceIntegration;
|
|
317
368
|
}
|
|
@@ -332,6 +383,42 @@ export interface CustomStatusMapping {
|
|
|
332
383
|
paymentStatus?: PaymentStatus | null;
|
|
333
384
|
/** Codes (or names) of other mappings suggested as the next workflow step */
|
|
334
385
|
next?: string[];
|
|
386
|
+
/**
|
|
387
|
+
* Minutes to postpone the order when this status is set. The order's
|
|
388
|
+
* `scheduledAt` becomes `now + snoozeMinutes`, so it leaves the confirmation
|
|
389
|
+
* queue and re-enters it once the delay elapses (e.g. "not_respond_1" -> 180).
|
|
390
|
+
*/
|
|
391
|
+
snoozeMinutes?: number | null;
|
|
392
|
+
/** Plain-text reason presets offered to the confirmer when this status is set. */
|
|
393
|
+
reasons?: string[];
|
|
394
|
+
/** Whether the confirmer may type a reason that is not in `reasons`. */
|
|
395
|
+
allowOtherReason?: boolean;
|
|
396
|
+
/**
|
|
397
|
+
* Whether a reason is mandatory. Always treated as `true` when `status` is
|
|
398
|
+
* `cancelled`, regardless of the stored value.
|
|
399
|
+
*/
|
|
400
|
+
requiresReason?: boolean;
|
|
401
|
+
/** Whether orders carrying this status may be served by the confirmation queue. */
|
|
402
|
+
queueEligible?: boolean;
|
|
403
|
+
}
|
|
404
|
+
/** Store-level confirmation queue settings. */
|
|
405
|
+
export interface ConfirmationQueueConfig {
|
|
406
|
+
enabled?: boolean;
|
|
407
|
+
/**
|
|
408
|
+
* How long a `draft` order must age before it becomes eligible for
|
|
409
|
+
* confirmation. Gives the customer time to finish submitting.
|
|
410
|
+
*/
|
|
411
|
+
draftDelayMinutes?: number;
|
|
412
|
+
/**
|
|
413
|
+
* After a confirmer skips, how long before the order is due again
|
|
414
|
+
* (`scheduled_at` soft-snooze). Default 15.
|
|
415
|
+
*/
|
|
416
|
+
skipDeferMinutes?: number;
|
|
417
|
+
/**
|
|
418
|
+
* How long after `updated_at` a recent history order stays correctable
|
|
419
|
+
* in the confirmation feed. Default 5.
|
|
420
|
+
*/
|
|
421
|
+
historyActionMinutes?: number;
|
|
335
422
|
}
|
|
336
423
|
export interface StoreCurrencyConfig {
|
|
337
424
|
code: string;
|
|
@@ -439,6 +526,79 @@ export interface TiktokPixel {
|
|
|
439
526
|
id: string;
|
|
440
527
|
accessToken?: string;
|
|
441
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* An ad account the merchant chose to manage from Feeef.
|
|
531
|
+
*/
|
|
532
|
+
export interface MetaAdAccountRef {
|
|
533
|
+
/** Graph node id, `act_123`. */
|
|
534
|
+
id: string;
|
|
535
|
+
/** Bare numeric id, `123`. */
|
|
536
|
+
accountId: string;
|
|
537
|
+
name?: string;
|
|
538
|
+
currency?: string;
|
|
539
|
+
timezoneName?: string;
|
|
540
|
+
accountStatus?: number;
|
|
541
|
+
}
|
|
542
|
+
/** Everything ads-related on the Meta integration. */
|
|
543
|
+
export interface MetaAdsConfig {
|
|
544
|
+
active?: boolean;
|
|
545
|
+
adAccounts?: MetaAdAccountRef[];
|
|
546
|
+
defaultAdAccountId?: string | null;
|
|
547
|
+
/** Default insights window for the dashboard, e.g. `last_7d`. */
|
|
548
|
+
defaultDatePreset?: string | null;
|
|
549
|
+
/** Extra hosts that count as this store's storefront when matching ad links. */
|
|
550
|
+
extraStoreHosts?: string[];
|
|
551
|
+
metadata?: Record<string, any>;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Meta OAuth credentials.
|
|
555
|
+
*
|
|
556
|
+
* Server-side only — the token is encrypted at rest and written exclusively by
|
|
557
|
+
* the OAuth callback. It is stripped from every client-facing projection, and
|
|
558
|
+
* `mergeIntegrationsPatch` in the backend refuses to accept it from a client.
|
|
559
|
+
*/
|
|
560
|
+
export interface MetaOAuthCredentials {
|
|
561
|
+
/** AES-encrypted access token. Never present in API responses. */
|
|
562
|
+
accessTokenEnc: string;
|
|
563
|
+
tokenType?: string;
|
|
564
|
+
expiresAt?: string;
|
|
565
|
+
/** Scopes Meta actually granted, from `debug_token`. */
|
|
566
|
+
scopes?: string[];
|
|
567
|
+
connectedAt?: string;
|
|
568
|
+
connectedByUserId?: string;
|
|
569
|
+
metaUserId?: string;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Global Meta integration (`store.integrations.meta`).
|
|
573
|
+
*
|
|
574
|
+
* Credentials live at the top level and are shared by every Meta feature.
|
|
575
|
+
* Ads live under `ads`; pixels remain on the legacy {@link MetaPixelIntegration}
|
|
576
|
+
* key for now and may move here later.
|
|
577
|
+
*/
|
|
578
|
+
export interface MetaIntegration {
|
|
579
|
+
active: boolean;
|
|
580
|
+
oauth2?: MetaOAuthCredentials | null;
|
|
581
|
+
/** Meta identity the token belongs to, for display + reconnect detection. */
|
|
582
|
+
account?: {
|
|
583
|
+
id: string;
|
|
584
|
+
name?: string;
|
|
585
|
+
} | null;
|
|
586
|
+
ads?: MetaAdsConfig | null;
|
|
587
|
+
metadata?: Record<string, any>;
|
|
588
|
+
}
|
|
589
|
+
/** Storefront-safe Meta integration — credentials and ad accounts excluded. */
|
|
590
|
+
export interface PublicMetaIntegration {
|
|
591
|
+
active: boolean;
|
|
592
|
+
ads: {
|
|
593
|
+
active: boolean;
|
|
594
|
+
} | null;
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Generates public Meta integration data.
|
|
598
|
+
* `oauth2`, `account`, and the ad-account list are intentionally excluded — none
|
|
599
|
+
* of it belongs on a storefront page.
|
|
600
|
+
*/
|
|
601
|
+
export declare const generatePublicStoreIntegrationMeta: (meta: MetaIntegration | null | undefined) => PublicMetaIntegration | null;
|
|
442
602
|
export interface MetaPixelIntegration {
|
|
443
603
|
id: string;
|
|
444
604
|
pixels: MetaPixel[];
|
|
@@ -484,6 +644,19 @@ export interface GoogleSheetsIntegration {
|
|
|
484
644
|
metadata: Record<string, any>;
|
|
485
645
|
simple?: boolean;
|
|
486
646
|
columns?: GoogleSheetsColumn<any>[];
|
|
647
|
+
/**
|
|
648
|
+
* When true, draft (abandoned-cart) orders are written to a dedicated
|
|
649
|
+
* sheet tab (`draftSheetName`) instead of the main tab (`name`).
|
|
650
|
+
* When the order leaves the draft status (e.g. becomes pending), its row is
|
|
651
|
+
* removed from the draft tab and a fresh row is inserted into the main tab.
|
|
652
|
+
* Disabled by default.
|
|
653
|
+
*/
|
|
654
|
+
draftSheetEnabled?: boolean;
|
|
655
|
+
/**
|
|
656
|
+
* Tab title used for draft orders when `draftSheetEnabled` is true.
|
|
657
|
+
* Falls back to the platform default ("الطلبات المتروكة") when empty.
|
|
658
|
+
*/
|
|
659
|
+
draftSheetName?: string | null;
|
|
487
660
|
}
|
|
488
661
|
export interface GoogleTagsIntegration {
|
|
489
662
|
id: string;
|
|
@@ -580,6 +753,30 @@ export interface ZrexpressIntegration {
|
|
|
580
753
|
/** Additional metadata for the integration */
|
|
581
754
|
metadata?: Record<string, any>;
|
|
582
755
|
}
|
|
756
|
+
/**
|
|
757
|
+
* Codpilot mini-ERP — push Feeef orders for confirmation / COD ops.
|
|
758
|
+
*
|
|
759
|
+
* Auth: subdomain + apiId + Bearer apiToken.
|
|
760
|
+
* Docs: https://codpilot.gitbook.io/codpilot-api
|
|
761
|
+
* Sync state: `order.metadata.codpilot` (not a delivery carrier).
|
|
762
|
+
*/
|
|
763
|
+
export interface CodpilotIntegration {
|
|
764
|
+
/** Business subdomain (`mystore` → mystore.codpilot.net) */
|
|
765
|
+
subdomain: string;
|
|
766
|
+
apiId: string;
|
|
767
|
+
apiToken: string;
|
|
768
|
+
active: boolean;
|
|
769
|
+
/**
|
|
770
|
+
* Auto-send when a status dimension transitions into `equals`.
|
|
771
|
+
* Default (client-seeded): `[{ id: 'default-pending', dimension: 'orderStatus', equals: 'pending' }]`.
|
|
772
|
+
*/
|
|
773
|
+
statusRules?: Array<{
|
|
774
|
+
id: string;
|
|
775
|
+
dimension: 'orderStatus' | 'deliveryStatus' | 'paymentStatus' | 'customStatus';
|
|
776
|
+
equals: string;
|
|
777
|
+
}>;
|
|
778
|
+
metadata?: Record<string, any>;
|
|
779
|
+
}
|
|
583
780
|
/**
|
|
584
781
|
* MDM Express (api.mdm.express) — `x-api-key` and/or Bearer JWT, MDM store `trackingId` (`mdmStoreId` on orders),
|
|
585
782
|
* and MDM seller id (`mdmSellerId`) for service-fees.
|
|
@@ -598,6 +795,29 @@ export interface MdmExpressIntegration {
|
|
|
598
795
|
webhookSecret?: string | null;
|
|
599
796
|
metadata?: Record<string, any>;
|
|
600
797
|
}
|
|
798
|
+
/**
|
|
799
|
+
* Feeef Delivery (Near Delivery white-label). Merchants never hold Near API keys —
|
|
800
|
+
* enable via `POST .../integrations/feeefDelivery/enable`.
|
|
801
|
+
*/
|
|
802
|
+
export interface FeeefDeliveryIntegration {
|
|
803
|
+
id: string;
|
|
804
|
+
active: boolean;
|
|
805
|
+
autoSend?: boolean;
|
|
806
|
+
/** Near sender user id — required when active. */
|
|
807
|
+
nearSenderUserId: number;
|
|
808
|
+
nearSenderUsername?: string | null;
|
|
809
|
+
nearSenderEmail?: string | null;
|
|
810
|
+
nearAccountType?: 'platform' | 'api' | 'both' | null;
|
|
811
|
+
/** 0 = address pickup, 1 = center pickup. */
|
|
812
|
+
pickupLocationType?: 0 | 1 | null;
|
|
813
|
+
pickupAddress?: string | null;
|
|
814
|
+
senderCenterId?: number | null;
|
|
815
|
+
defaultBuralistId?: number | null;
|
|
816
|
+
/** Prefer Feeef-branded PDF labels (default true). */
|
|
817
|
+
useFeeefLabel?: boolean | null;
|
|
818
|
+
webhookSecret?: string | null;
|
|
819
|
+
metadata?: Record<string, any>;
|
|
820
|
+
}
|
|
601
821
|
export declare enum SecurityTreatment {
|
|
602
822
|
block = "block",
|
|
603
823
|
warning = "warning",
|
|
@@ -664,12 +884,15 @@ export interface PublicSecurityIntegration {
|
|
|
664
884
|
options: PublicSecurityOptions;
|
|
665
885
|
}
|
|
666
886
|
/**
|
|
667
|
-
* Webhook event types for order lifecycle
|
|
887
|
+
* Webhook event types for order and product lifecycle
|
|
668
888
|
*/
|
|
669
889
|
export declare enum WebhookEvent {
|
|
670
890
|
ORDER_CREATED = "orderCreated",
|
|
671
891
|
ORDER_UPDATED = "orderUpdated",
|
|
672
|
-
ORDER_DELETED = "orderDeleted"
|
|
892
|
+
ORDER_DELETED = "orderDeleted",
|
|
893
|
+
PRODUCT_CREATED = "productCreated",
|
|
894
|
+
PRODUCT_UPDATED = "productUpdated",
|
|
895
|
+
PRODUCT_DELETED = "productDeleted"
|
|
673
896
|
}
|
|
674
897
|
/**
|
|
675
898
|
* Individual webhook configuration
|
|
@@ -693,7 +916,7 @@ export interface WebhookConfig {
|
|
|
693
916
|
metadata: Record<string, any>;
|
|
694
917
|
}
|
|
695
918
|
/**
|
|
696
|
-
* Webhooks integration configuration for real-time order notifications
|
|
919
|
+
* Webhooks integration configuration for real-time order and product notifications
|
|
697
920
|
*/
|
|
698
921
|
export interface WebhooksIntegration {
|
|
699
922
|
/** List of configured webhooks */
|
|
@@ -830,6 +1053,11 @@ export interface PublicConnectorsIntegration {
|
|
|
830
1053
|
export interface StoreIntegrations {
|
|
831
1054
|
[key: string]: any;
|
|
832
1055
|
metadata?: Record<string, any>;
|
|
1056
|
+
/**
|
|
1057
|
+
* Global Meta integration — credentials shared by every Meta feature.
|
|
1058
|
+
* Ads live here today; pixels may move over from `metaPixel` later.
|
|
1059
|
+
*/
|
|
1060
|
+
meta?: MetaIntegration;
|
|
833
1061
|
metaPixel?: MetaPixelIntegration;
|
|
834
1062
|
tiktokPixel?: TiktokPixelIntegration;
|
|
835
1063
|
googleAnalytics?: GoogleAnalyticsIntegration;
|
|
@@ -852,6 +1080,9 @@ export interface StoreIntegrations {
|
|
|
852
1080
|
zimou?: ZimouIntegration;
|
|
853
1081
|
zrexpress?: ZrexpressIntegration;
|
|
854
1082
|
mdmExpress?: MdmExpressIntegration;
|
|
1083
|
+
/** Feeef Delivery (Near white-label) — no merchant API keys. */
|
|
1084
|
+
feeefDelivery?: FeeefDeliveryIntegration;
|
|
1085
|
+
codpilot?: CodpilotIntegration;
|
|
855
1086
|
security?: SecurityIntegration;
|
|
856
1087
|
dispatcher?: DispatcherIntegration;
|
|
857
1088
|
inventory?: StoreInventoryIntegration;
|
|
@@ -990,6 +1221,8 @@ export interface AddStoreMemberInput {
|
|
|
990
1221
|
role: StoreMemberRole;
|
|
991
1222
|
name?: string;
|
|
992
1223
|
metadata?: Record<string, any>;
|
|
1224
|
+
/** RBAC scopes to grant (see {@link StoreMember.scopes}). Empty/undefined = unrestricted for the role. */
|
|
1225
|
+
scopes?: string[];
|
|
993
1226
|
}
|
|
994
1227
|
/**
|
|
995
1228
|
* Input for updating a store member
|
|
@@ -998,4 +1231,6 @@ export interface UpdateStoreMemberInput {
|
|
|
998
1231
|
role?: StoreMemberRole;
|
|
999
1232
|
name?: string;
|
|
1000
1233
|
metadata?: Record<string, any>;
|
|
1234
|
+
/** Replacement RBAC scopes (see {@link StoreMember.scopes}). Omit to keep current scopes. */
|
|
1235
|
+
scopes?: string[];
|
|
1001
1236
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth / member RBAC scope catalog — aligned with backend
|
|
3
|
+
* `app/oauth_scopes.ts` (`MEMBER_SCOPES` + `auth`, `apps`).
|
|
4
|
+
*
|
|
5
|
+
* Keep this list in sync when adding a store resource. Unknown strings are
|
|
6
|
+
* rejected by the API validators.
|
|
7
|
+
*/
|
|
8
|
+
/** Store member RBAC scopes (parent implies `.read` child). */
|
|
9
|
+
export declare const MEMBER_SCOPES: readonly ["store", "store.read", "store.settings", "store.integrations", "store.members", "orders", "orders.read", "products", "products.read", "categories", "categories.read", "pages", "pages.read", "product_landing_pages", "product_landing_pages.read", "shipping_prices", "shipping_prices.read", "template_components", "template_components.read", "store_templates", "store_templates.read", "finance", "finance.read", "inventory", "inventory.read"];
|
|
10
|
+
export type MemberScope = (typeof MEMBER_SCOPES)[number];
|
|
11
|
+
/** Scopes for developer tooling / delegation (not store-specific RBAC). */
|
|
12
|
+
export declare const OAUTH_PLATFORM_SCOPES: readonly ["auth", "apps"];
|
|
13
|
+
/**
|
|
14
|
+
* Identity-only grant when an app is registered without scopes.
|
|
15
|
+
* Never `*` — empty registration must not escalate to full access.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_OAUTH_SCOPES: readonly ["auth"];
|
|
18
|
+
/** Every scope string allowed on OAuth apps and access tokens. */
|
|
19
|
+
export declare const OAUTH_SCOPES: readonly ["store", "store.read", "store.settings", "store.integrations", "store.members", "orders", "orders.read", "products", "products.read", "categories", "categories.read", "pages", "pages.read", "product_landing_pages", "product_landing_pages.read", "shipping_prices", "shipping_prices.read", "template_components", "template_components.read", "store_templates", "store_templates.read", "finance", "finance.read", "inventory", "inventory.read", "auth", "apps"];
|
|
20
|
+
export type OAuthScope = (typeof OAUTH_SCOPES)[number];
|