@aglyn/plugins-commerce 1.0.0-beta.243 → 1.0.0-beta.246
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/package.json +13 -13
- package/src/lib/components/commerce-console-page.js +10 -0
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/product-zones.d.ts +7 -1
- package/src/lib/components/console/product-zones.js.map +1 -1
- package/src/lib/components/console/products-hub-zone.component.d.ts +3 -2
- package/src/lib/components/console/products-hub-zone.component.js +9 -1
- package/src/lib/components/console/products-hub-zone.component.js.map +1 -1
- package/src/lib/components/console/review-settings-card.component.d.ts +14 -0
- package/src/lib/components/console/review-settings-card.component.js +168 -0
- package/src/lib/components/console/review-settings-card.component.js.map +1 -0
- package/src/lib/components/console/reviews-moderation-card.component.d.ts +14 -0
- package/src/lib/components/console/reviews-moderation-card.component.js +85 -11
- package/src/lib/components/console/reviews-moderation-card.component.js.map +1 -1
- package/src/lib/components/product-reviews.d.ts +29 -1
- package/src/lib/components/product-reviews.js +97 -12
- package/src/lib/components/product-reviews.js.map +1 -1
- package/src/lib/model/commerce.d.ts +11 -2
- package/src/lib/model/commerce.js +14 -2
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +1 -0
- package/src/lib/model/index.js +1 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/product-reviews.d.ts +124 -0
- package/src/lib/model/product-reviews.js +133 -0
- package/src/lib/model/product-reviews.js.map +1 -0
- package/src/lib/model/store-setup-content.d.ts +145 -0
- package/src/lib/model/store-setup-content.js +813 -0
- package/src/lib/model/store-setup-content.js.map +1 -0
- package/src/lib/server/membership-reset.js +8 -2
- package/src/lib/server/membership-reset.js.map +1 -1
- package/src/lib/server/order-event-triggers.d.ts +2 -0
- package/src/lib/server/order-event-triggers.js +18 -1
- package/src/lib/server/order-event-triggers.js.map +1 -1
- package/src/lib/server/review-requests.d.ts +102 -0
- package/src/lib/server/review-requests.js +346 -0
- package/src/lib/server/review-requests.js.map +1 -0
- package/src/lib/server/review-tokens.d.ts +82 -0
- package/src/lib/server/review-tokens.js +119 -0
- package/src/lib/server/review-tokens.js.map +1 -0
- package/src/lib/server/reviews.d.ts +36 -3
- package/src/lib/server/reviews.js +310 -52
- package/src/lib/server/reviews.js.map +1 -1
- package/src/lib/server/store-setup-ai-capability.d.ts +61 -0
- package/src/lib/server/store-setup-ai-capability.js +343 -0
- package/src/lib/server/store-setup-ai-capability.js.map +1 -0
- package/src/lib/server/store-setup-ai-writer.console.d.ts +27 -0
- package/src/lib/server/store-setup-ai-writer.console.js +44 -0
- package/src/lib/server/store-setup-ai-writer.console.js.map +1 -0
- package/src/lib/server/store-setup-ai-writer.d.ts +37 -0
- package/src/lib/server/store-setup-ai-writer.js +174 -0
- package/src/lib/server/store-setup-ai-writer.js.map +1 -0
- package/src/lib/server.js +27 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tenant-emails.js +58 -0
- package/src/lib/tenant-emails.js.map +1 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { registerPluginAiCapability } from "@aglyn/aglyn/plugin-manager/plugin-ai-capabilities";
|
|
18
|
+
import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
19
|
+
import { COMMERCE_MAX_PRICE_USD } from "../model/commerce.js";
|
|
20
|
+
import { LOCAL_DELIVERY_POSTCODES_MAX, PICKUP_HOURS_MAX, PICKUP_INSTRUCTIONS_MAX } from "../model/local-fulfillment-settings.js";
|
|
21
|
+
import { STORE_SETUP_COUNTRIES_MAX, STORE_SETUP_LOCATION_MAX, STORE_SETUP_MAX_MINUTES, STORE_SETUP_NAME_MAX, STORE_SETUP_RESOURCE, STORE_SHIPPING_ACTIONS, STORE_SHIPPING_AI_KINDS, STORE_SHIPPING_TIERS_MAX, STORE_TAX_LABEL_MAX, STORE_TAX_MODES } from "../model/store-setup-content.js";
|
|
22
|
+
/**
|
|
23
|
+
* WHAT AN AI BUILD CAN SET UP IN A STORE (AGL-3749): shipping zones and
|
|
24
|
+
* rates, local pickup, local delivery and sales tax — "free shipping over $50,
|
|
25
|
+
* otherwise $5 flat in the US", "offer local pickup at our Austin shop",
|
|
26
|
+
* "charge 8.25% Texas sales tax".
|
|
27
|
+
*
|
|
28
|
+
* Four operations the AI plugin's build planner offers, all written by this
|
|
29
|
+
* plugin's `store-settings` writer (`store-setup-ai-writer.ts`), so every
|
|
30
|
+
* change is the console cards' own: the role that may save them, the plan's
|
|
31
|
+
* `commerce` feature, lockdown, and the cards' normalizers and checks. No
|
|
32
|
+
* model runs: the planner fills the arguments and they ARE the change, so an
|
|
33
|
+
* item costs no credits.
|
|
34
|
+
*
|
|
35
|
+
* NEVER A NUMBER THE PERSON DID NOT GIVE. A blank flat rate charges nothing
|
|
36
|
+
* and a tax rate is the merchant's legal call, so every amount and
|
|
37
|
+
* percentage is "only when the request states it", and the writer refuses a
|
|
38
|
+
* rate without one. A request to "set up tax" that says neither how nor what
|
|
39
|
+
* rate is left out of the plan rather than guessed at.
|
|
40
|
+
*
|
|
41
|
+
* NEVER AN ACCOUNT. Carrier rates, label services and outside tax services
|
|
42
|
+
* need a person to connect an account; none of them is offered here.
|
|
43
|
+
*
|
|
44
|
+
* Settings are live once written: the cards save them live, and a store
|
|
45
|
+
* setting has no draft. `live` (the contract's flag, AGL-3745) tells the
|
|
46
|
+
* build step so, and the job reports the change as live.
|
|
47
|
+
* Free has no commerce, so a Free workspace's build is never offered one.
|
|
48
|
+
*/ export const STORE_SHIPPING_AI_OP = 'store-shipping';
|
|
49
|
+
export const STORE_PICKUP_AI_OP = 'store-pickup';
|
|
50
|
+
export const STORE_DELIVERY_AI_OP = 'store-delivery';
|
|
51
|
+
export const STORE_TAX_AI_OP = 'store-tax';
|
|
52
|
+
/** Where a person finds what the build set. */ const WHERE = 'Products → Settings';
|
|
53
|
+
/** The writer's content for an item: its arguments, tagged with the section its op changes. */ export function storeSetupContentFromArgs(section, args) {
|
|
54
|
+
const content = {
|
|
55
|
+
section
|
|
56
|
+
};
|
|
57
|
+
for (const [key, value] of Object.entries(args)){
|
|
58
|
+
if (value === undefined || value === null || value === '') continue;
|
|
59
|
+
content[key] = value;
|
|
60
|
+
}
|
|
61
|
+
return content;
|
|
62
|
+
}
|
|
63
|
+
const STATED = 'ONLY when the request states it; never a typical or suggested amount.';
|
|
64
|
+
/** What every store-setup operation shares. */ function storeSetupCapability(op, section, rest) {
|
|
65
|
+
return _extends({
|
|
66
|
+
op,
|
|
67
|
+
where: WHERE
|
|
68
|
+
}, rest, {
|
|
69
|
+
// Free includes no commerce.
|
|
70
|
+
freeAllowed: false,
|
|
71
|
+
feature: 'commerce',
|
|
72
|
+
draftResource: STORE_SETUP_RESOURCE,
|
|
73
|
+
live: true,
|
|
74
|
+
// Written without a model: the planner already filled the arguments.
|
|
75
|
+
estimateCredits: ()=>0,
|
|
76
|
+
degrade: 'omit',
|
|
77
|
+
draftContent: (item)=>storeSetupContentFromArgs(section, item.args)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
export const storeShippingAiCapability = storeSetupCapability(STORE_SHIPPING_AI_OP, 'shipping', {
|
|
81
|
+
noun: 'shipping rate',
|
|
82
|
+
intents: [
|
|
83
|
+
'store shipping: a shipping zone (countries) and its rate — flat, free over an order total, or tiered by order total or weight; change or remove a rate or zone. Live once the build runs. Amounts only as the request states them'
|
|
84
|
+
],
|
|
85
|
+
argsSchema: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
action: {
|
|
89
|
+
type: 'string',
|
|
90
|
+
description: 'set (the default) adds or replaces the rate named rateName in the zone; remove deletes that rate, or the whole zone and its rates when rateName is left out.',
|
|
91
|
+
enum: STORE_SHIPPING_ACTIONS
|
|
92
|
+
},
|
|
93
|
+
zoneName: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'The shipping zone, e.g. "United States" or "Rest of world". An existing zone is matched by this name or by the same countries.',
|
|
96
|
+
maxLength: STORE_SETUP_NAME_MAX
|
|
97
|
+
},
|
|
98
|
+
countries: {
|
|
99
|
+
type: 'array',
|
|
100
|
+
description: 'Two-letter country codes the zone ships to (["US"], ["US","CA"]), or ["*"] for everywhere no other zone names. Required for a new zone.',
|
|
101
|
+
items: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
maxLength: 2
|
|
104
|
+
},
|
|
105
|
+
maxItems: STORE_SETUP_COUNTRIES_MAX
|
|
106
|
+
},
|
|
107
|
+
rateName: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
description: 'What the shopper sees at checkout, e.g. "Standard". Required for set.',
|
|
110
|
+
maxLength: STORE_SETUP_NAME_MAX
|
|
111
|
+
},
|
|
112
|
+
kind: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'flat: one price. free_over: free at or above an order subtotal, otherwise amountUsd. price_tiers: priced by order subtotal. weight_tiers: priced by parcel weight in grams. Required for set.',
|
|
115
|
+
enum: STORE_SHIPPING_AI_KINDS
|
|
116
|
+
},
|
|
117
|
+
amountUsd: {
|
|
118
|
+
type: 'number',
|
|
119
|
+
description: `flat: the price; free_over: the price below the threshold. In dollars, 0 for free. ${STATED}`,
|
|
120
|
+
minimum: 0,
|
|
121
|
+
maximum: COMMERCE_MAX_PRICE_USD
|
|
122
|
+
},
|
|
123
|
+
freeOverUsd: {
|
|
124
|
+
type: 'number',
|
|
125
|
+
description: `free_over: the order subtotal in dollars at which shipping becomes free. ${STATED}`,
|
|
126
|
+
minimum: 0,
|
|
127
|
+
maximum: COMMERCE_MAX_PRICE_USD
|
|
128
|
+
},
|
|
129
|
+
tiers: {
|
|
130
|
+
type: 'array',
|
|
131
|
+
description: `price_tiers and weight_tiers: "upTo:price" entries — upTo is the subtotal in dollars (price_tiers) or grams (weight_tiers), price in dollars, e.g. ["50:5", "100:8"]. A larger order than the last tier gets no rate from it. ${STATED}`,
|
|
132
|
+
items: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
maxLength: 24
|
|
135
|
+
},
|
|
136
|
+
maxItems: STORE_SHIPPING_TIERS_MAX
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
required: [
|
|
140
|
+
'zoneName'
|
|
141
|
+
],
|
|
142
|
+
additionalProperties: false
|
|
143
|
+
},
|
|
144
|
+
maxPerPlan: 10
|
|
145
|
+
});
|
|
146
|
+
export const storePickupAiCapability = storeSetupCapability(STORE_PICKUP_AI_OP, 'pickup', {
|
|
147
|
+
noun: 'pickup setting',
|
|
148
|
+
intents: [
|
|
149
|
+
'store local pickup: let buyers collect orders free, at the store or at a named store location with its pickup hours and arrival instructions; switch pickup off. Live once the build runs'
|
|
150
|
+
],
|
|
151
|
+
argsSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
location: {
|
|
155
|
+
type: 'string',
|
|
156
|
+
description: 'The store location buyers collect from — its name, city or street, e.g. "Austin" — which must already be one of the store’s inventory locations. Leave out for a plain "Local pickup" choice at checkout with no location.',
|
|
157
|
+
maxLength: STORE_SETUP_LOCATION_MAX
|
|
158
|
+
},
|
|
159
|
+
enabled: {
|
|
160
|
+
type: 'boolean',
|
|
161
|
+
description: 'false to stop offering pickup; leave out to offer it.'
|
|
162
|
+
},
|
|
163
|
+
hours: {
|
|
164
|
+
type: 'string',
|
|
165
|
+
description: 'With location: pickup hours as the request gives them, one set of days per line or separated by ";", e.g. "Mo-Fr 09:00-17:00; Sa 10:00-14:00".',
|
|
166
|
+
maxLength: PICKUP_HOURS_MAX
|
|
167
|
+
},
|
|
168
|
+
instructions: {
|
|
169
|
+
type: 'string',
|
|
170
|
+
description: 'With location: what the buyer does on arrival, as the request says it.',
|
|
171
|
+
maxLength: PICKUP_INSTRUCTIONS_MAX
|
|
172
|
+
},
|
|
173
|
+
readyWithinMinutes: {
|
|
174
|
+
type: 'integer',
|
|
175
|
+
description: 'With location: how long an order usually takes to prepare, in minutes, when the request says.',
|
|
176
|
+
minimum: 0,
|
|
177
|
+
maximum: STORE_SETUP_MAX_MINUTES
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
additionalProperties: false
|
|
181
|
+
},
|
|
182
|
+
maxPerPlan: 5
|
|
183
|
+
});
|
|
184
|
+
export const storeDeliveryAiCapability = storeSetupCapability(STORE_DELIVERY_AI_OP, 'local-delivery', {
|
|
185
|
+
noun: 'local delivery setting',
|
|
186
|
+
intents: [
|
|
187
|
+
'store local delivery the merchant does themselves: delivery zones by postal code with a fee, a minimum and a free-over amount, delivery windows and instructions; switch it off. Live once the build runs. Fees only as the request states them'
|
|
188
|
+
],
|
|
189
|
+
argsSchema: {
|
|
190
|
+
type: 'object',
|
|
191
|
+
properties: {
|
|
192
|
+
enabled: {
|
|
193
|
+
type: 'boolean',
|
|
194
|
+
description: 'false to stop offering local delivery; leave out to offer it.'
|
|
195
|
+
},
|
|
196
|
+
country: {
|
|
197
|
+
type: 'string',
|
|
198
|
+
description: 'The two-letter country the store delivers within, e.g. US.',
|
|
199
|
+
maxLength: 2
|
|
200
|
+
},
|
|
201
|
+
location: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
description: 'The inventory location orders leave from, by name or city, when the request names one.',
|
|
204
|
+
maxLength: STORE_SETUP_LOCATION_MAX
|
|
205
|
+
},
|
|
206
|
+
zoneName: {
|
|
207
|
+
type: 'string',
|
|
208
|
+
description: 'The delivery zone to add, change or remove, e.g. "Downtown".',
|
|
209
|
+
maxLength: STORE_SETUP_NAME_MAX
|
|
210
|
+
},
|
|
211
|
+
postcodes: {
|
|
212
|
+
type: 'array',
|
|
213
|
+
description: 'The zone’s postal codes: exact ("78701"), a prefix ("787*") or a range ("78701-78705"). Required for a new zone.',
|
|
214
|
+
items: {
|
|
215
|
+
type: 'string',
|
|
216
|
+
maxLength: 24
|
|
217
|
+
},
|
|
218
|
+
maxItems: LOCAL_DELIVERY_POSTCODES_MAX
|
|
219
|
+
},
|
|
220
|
+
feeUsd: {
|
|
221
|
+
type: 'number',
|
|
222
|
+
description: `The zone’s delivery fee in dollars, 0 for free. Required for a new zone. ${STATED}`,
|
|
223
|
+
minimum: 0,
|
|
224
|
+
maximum: COMMERCE_MAX_PRICE_USD
|
|
225
|
+
},
|
|
226
|
+
minimumUsd: {
|
|
227
|
+
type: 'number',
|
|
228
|
+
description: `The smallest order the zone delivers, in dollars. ${STATED}`,
|
|
229
|
+
minimum: 0,
|
|
230
|
+
maximum: COMMERCE_MAX_PRICE_USD
|
|
231
|
+
},
|
|
232
|
+
freeOverUsd: {
|
|
233
|
+
type: 'number',
|
|
234
|
+
description: `Order total in dollars at which delivery is free. ${STATED}`,
|
|
235
|
+
minimum: 0,
|
|
236
|
+
maximum: COMMERCE_MAX_PRICE_USD
|
|
237
|
+
},
|
|
238
|
+
removeZone: {
|
|
239
|
+
type: 'boolean',
|
|
240
|
+
description: 'true to remove the zone named zoneName.'
|
|
241
|
+
},
|
|
242
|
+
windows: {
|
|
243
|
+
type: 'string',
|
|
244
|
+
description: 'Delivery windows as the request gives them, e.g. "Mo-Fr 09:00-12:00; Sa 10:00-14:00". Delivery is offered only with at least one window.',
|
|
245
|
+
maxLength: PICKUP_HOURS_MAX
|
|
246
|
+
},
|
|
247
|
+
leadTimeMinutes: {
|
|
248
|
+
type: 'integer',
|
|
249
|
+
description: 'How long before a window an order must be placed, in minutes, when the request says.',
|
|
250
|
+
minimum: 0,
|
|
251
|
+
maximum: STORE_SETUP_MAX_MINUTES
|
|
252
|
+
},
|
|
253
|
+
daysAhead: {
|
|
254
|
+
type: 'integer',
|
|
255
|
+
description: 'How many days ahead a window can be booked (1 to 30), when the request says.',
|
|
256
|
+
minimum: 1,
|
|
257
|
+
maximum: 30
|
|
258
|
+
},
|
|
259
|
+
instructions: {
|
|
260
|
+
type: 'string',
|
|
261
|
+
description: 'What the buyer is told about delivery, as the request says it.',
|
|
262
|
+
maxLength: PICKUP_INSTRUCTIONS_MAX
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
additionalProperties: false
|
|
266
|
+
},
|
|
267
|
+
maxPerPlan: 5
|
|
268
|
+
});
|
|
269
|
+
export const storeTaxAiCapability = storeSetupCapability(STORE_TAX_AI_OP, 'tax', {
|
|
270
|
+
noun: 'tax setting',
|
|
271
|
+
intents: [
|
|
272
|
+
'store sales tax: collect it at the manual rate the request states for a country or state, calculate it automatically, or not collect it; whether prices include tax; where the store sells from. Live once the build runs. Never a rate the request does not state — "set up tax" alone is a question back, not an item'
|
|
273
|
+
],
|
|
274
|
+
argsSchema: {
|
|
275
|
+
type: 'object',
|
|
276
|
+
properties: {
|
|
277
|
+
mode: {
|
|
278
|
+
type: 'string',
|
|
279
|
+
description: 'manual: the rates the merchant states. stripe: automatic calculation per buyer location, ONLY when the request asks for automatic tax. none: the store does not collect sales tax, ONLY when the request says so. Leave out to keep the store’s choice.',
|
|
280
|
+
enum: STORE_TAX_MODES
|
|
281
|
+
},
|
|
282
|
+
pricesIncludeTax: {
|
|
283
|
+
type: 'boolean',
|
|
284
|
+
description: 'true when the request says prices already include tax (VAT-style); false when it says tax is added on top.'
|
|
285
|
+
},
|
|
286
|
+
originCountry: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
description: 'The two-letter country the store sells from, e.g. US. Manual rates need it.',
|
|
289
|
+
maxLength: 2
|
|
290
|
+
},
|
|
291
|
+
originState: {
|
|
292
|
+
type: 'string',
|
|
293
|
+
description: 'The state or region the store sells from, e.g. TX.',
|
|
294
|
+
maxLength: 3
|
|
295
|
+
},
|
|
296
|
+
rateCountry: {
|
|
297
|
+
type: 'string',
|
|
298
|
+
description: 'The two-letter country a tax rate applies to.',
|
|
299
|
+
maxLength: 2
|
|
300
|
+
},
|
|
301
|
+
rateState: {
|
|
302
|
+
type: 'string',
|
|
303
|
+
description: 'The state or region a tax rate applies to, e.g. TX; leave out for the whole country.',
|
|
304
|
+
maxLength: 3
|
|
305
|
+
},
|
|
306
|
+
ratePercent: {
|
|
307
|
+
type: 'number',
|
|
308
|
+
description: `The tax rate in percent, e.g. 8.25. ${STATED}`,
|
|
309
|
+
minimum: 0,
|
|
310
|
+
maximum: 100
|
|
311
|
+
},
|
|
312
|
+
rateLabel: {
|
|
313
|
+
type: 'string',
|
|
314
|
+
description: 'The receipt label, e.g. "TX sales tax".',
|
|
315
|
+
maxLength: STORE_TAX_LABEL_MAX
|
|
316
|
+
},
|
|
317
|
+
removeRate: {
|
|
318
|
+
type: 'boolean',
|
|
319
|
+
description: 'true to remove the rate for rateCountry (and rateState).'
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
additionalProperties: false
|
|
323
|
+
},
|
|
324
|
+
maxPerPlan: 6
|
|
325
|
+
});
|
|
326
|
+
export const STORE_SETUP_AI_CAPABILITIES = [
|
|
327
|
+
storeShippingAiCapability,
|
|
328
|
+
storePickupAiCapability,
|
|
329
|
+
storeDeliveryAiCapability,
|
|
330
|
+
storeTaxAiCapability
|
|
331
|
+
];
|
|
332
|
+
/**
|
|
333
|
+
* Registers the four operations; the console surface calls it beside the
|
|
334
|
+
* writer, since only the console runs AI jobs (AGL-3026). Idempotent.
|
|
335
|
+
*/ export function registerStoreSetupAiCapabilities() {
|
|
336
|
+
for (const capability of STORE_SETUP_AI_CAPABILITIES){
|
|
337
|
+
registerPluginAiCapability(capability, {
|
|
338
|
+
pluginId: BUNDLE_ID
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
//# sourceMappingURL=store-setup-ai-capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/store-setup-ai-capability.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerPluginAiCapability,\n type PluginAiCapability,\n type PluginAiCapabilityArgs,\n} from '@aglyn/aglyn/plugin-manager/plugin-ai-capabilities'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { COMMERCE_MAX_PRICE_USD } from '../model/commerce'\nimport {\n LOCAL_DELIVERY_POSTCODES_MAX,\n PICKUP_HOURS_MAX,\n PICKUP_INSTRUCTIONS_MAX,\n} from '../model/local-fulfillment-settings'\nimport {\n STORE_SETUP_COUNTRIES_MAX,\n STORE_SETUP_LOCATION_MAX,\n STORE_SETUP_MAX_MINUTES,\n STORE_SETUP_NAME_MAX,\n STORE_SETUP_RESOURCE,\n STORE_SHIPPING_ACTIONS,\n STORE_SHIPPING_AI_KINDS,\n STORE_SHIPPING_TIERS_MAX,\n STORE_TAX_LABEL_MAX,\n STORE_TAX_MODES,\n type StoreSetupSection,\n} from '../model/store-setup-content'\n\n/**\n * WHAT AN AI BUILD CAN SET UP IN A STORE (AGL-3749): shipping zones and\n * rates, local pickup, local delivery and sales tax — \"free shipping over $50,\n * otherwise $5 flat in the US\", \"offer local pickup at our Austin shop\",\n * \"charge 8.25% Texas sales tax\".\n *\n * Four operations the AI plugin's build planner offers, all written by this\n * plugin's `store-settings` writer (`store-setup-ai-writer.ts`), so every\n * change is the console cards' own: the role that may save them, the plan's\n * `commerce` feature, lockdown, and the cards' normalizers and checks. No\n * model runs: the planner fills the arguments and they ARE the change, so an\n * item costs no credits.\n *\n * NEVER A NUMBER THE PERSON DID NOT GIVE. A blank flat rate charges nothing\n * and a tax rate is the merchant's legal call, so every amount and\n * percentage is \"only when the request states it\", and the writer refuses a\n * rate without one. A request to \"set up tax\" that says neither how nor what\n * rate is left out of the plan rather than guessed at.\n *\n * NEVER AN ACCOUNT. Carrier rates, label services and outside tax services\n * need a person to connect an account; none of them is offered here.\n *\n * Settings are live once written: the cards save them live, and a store\n * setting has no draft. `live` (the contract's flag, AGL-3745) tells the\n * build step so, and the job reports the change as live.\n * Free has no commerce, so a Free workspace's build is never offered one.\n */\n\nexport const STORE_SHIPPING_AI_OP = 'store-shipping'\nexport const STORE_PICKUP_AI_OP = 'store-pickup'\nexport const STORE_DELIVERY_AI_OP = 'store-delivery'\nexport const STORE_TAX_AI_OP = 'store-tax'\n\n/** Where a person finds what the build set. */\nconst WHERE = 'Products → Settings'\n\n/** The writer's content for an item: its arguments, tagged with the section its op changes. */\nexport function storeSetupContentFromArgs(\n section: StoreSetupSection,\n args: PluginAiCapabilityArgs,\n): Readonly<Record<string, unknown>> {\n const content: Record<string, unknown> = { section }\n for (const [key, value] of Object.entries(args)) {\n if (value === undefined || value === null || value === '') continue\n content[key] = value\n }\n return content\n}\n\nconst STATED = 'ONLY when the request states it; never a typical or suggested amount.'\n\n/** What every store-setup operation shares. */\nfunction storeSetupCapability(\n op: string,\n section: StoreSetupSection,\n rest: Pick<PluginAiCapability, 'noun' | 'intents' | 'argsSchema' | 'maxPerPlan'>,\n): PluginAiCapability {\n return {\n op,\n where: WHERE,\n ...rest,\n // Free includes no commerce.\n freeAllowed: false,\n feature: 'commerce',\n draftResource: STORE_SETUP_RESOURCE,\n live: true,\n // Written without a model: the planner already filled the arguments.\n estimateCredits: () => 0,\n degrade: 'omit',\n draftContent: (item) => storeSetupContentFromArgs(section, item.args),\n }\n}\n\nexport const storeShippingAiCapability = storeSetupCapability(STORE_SHIPPING_AI_OP, 'shipping', {\n noun: 'shipping rate',\n intents: [\n 'store shipping: a shipping zone (countries) and its rate — flat, free over an order total, or tiered by order total or weight; change or remove a rate or zone. Live once the build runs. Amounts only as the request states them',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n description: 'set (the default) adds or replaces the rate named rateName in the zone; remove deletes that rate, or the whole zone and its rates when rateName is left out.',\n enum: STORE_SHIPPING_ACTIONS,\n },\n zoneName: {\n type: 'string',\n description: 'The shipping zone, e.g. \"United States\" or \"Rest of world\". An existing zone is matched by this name or by the same countries.',\n maxLength: STORE_SETUP_NAME_MAX,\n },\n countries: {\n type: 'array',\n description: 'Two-letter country codes the zone ships to ([\"US\"], [\"US\",\"CA\"]), or [\"*\"] for everywhere no other zone names. Required for a new zone.',\n items: { type: 'string', maxLength: 2 },\n maxItems: STORE_SETUP_COUNTRIES_MAX,\n },\n rateName: {\n type: 'string',\n description: 'What the shopper sees at checkout, e.g. \"Standard\". Required for set.',\n maxLength: STORE_SETUP_NAME_MAX,\n },\n kind: {\n type: 'string',\n description:\n 'flat: one price. free_over: free at or above an order subtotal, otherwise amountUsd. price_tiers: priced by order subtotal. weight_tiers: priced by parcel weight in grams. Required for set.',\n enum: STORE_SHIPPING_AI_KINDS,\n },\n amountUsd: {\n type: 'number',\n description: `flat: the price; free_over: the price below the threshold. In dollars, 0 for free. ${STATED}`,\n minimum: 0,\n maximum: COMMERCE_MAX_PRICE_USD,\n },\n freeOverUsd: {\n type: 'number',\n description: `free_over: the order subtotal in dollars at which shipping becomes free. ${STATED}`,\n minimum: 0,\n maximum: COMMERCE_MAX_PRICE_USD,\n },\n tiers: {\n type: 'array',\n description: `price_tiers and weight_tiers: \"upTo:price\" entries — upTo is the subtotal in dollars (price_tiers) or grams (weight_tiers), price in dollars, e.g. [\"50:5\", \"100:8\"]. A larger order than the last tier gets no rate from it. ${STATED}`,\n items: { type: 'string', maxLength: 24 },\n maxItems: STORE_SHIPPING_TIERS_MAX,\n },\n },\n required: ['zoneName'],\n additionalProperties: false,\n },\n maxPerPlan: 10,\n})\n\nexport const storePickupAiCapability = storeSetupCapability(STORE_PICKUP_AI_OP, 'pickup', {\n noun: 'pickup setting',\n intents: [\n 'store local pickup: let buyers collect orders free, at the store or at a named store location with its pickup hours and arrival instructions; switch pickup off. Live once the build runs',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n location: {\n type: 'string',\n description:\n 'The store location buyers collect from — its name, city or street, e.g. \"Austin\" — which must already be one of the store’s inventory locations. Leave out for a plain \"Local pickup\" choice at checkout with no location.',\n maxLength: STORE_SETUP_LOCATION_MAX,\n },\n enabled: { type: 'boolean', description: 'false to stop offering pickup; leave out to offer it.' },\n hours: {\n type: 'string',\n description: 'With location: pickup hours as the request gives them, one set of days per line or separated by \";\", e.g. \"Mo-Fr 09:00-17:00; Sa 10:00-14:00\".',\n maxLength: PICKUP_HOURS_MAX,\n },\n instructions: {\n type: 'string',\n description: 'With location: what the buyer does on arrival, as the request says it.',\n maxLength: PICKUP_INSTRUCTIONS_MAX,\n },\n readyWithinMinutes: {\n type: 'integer',\n description: 'With location: how long an order usually takes to prepare, in minutes, when the request says.',\n minimum: 0,\n maximum: STORE_SETUP_MAX_MINUTES,\n },\n },\n additionalProperties: false,\n },\n maxPerPlan: 5,\n})\n\nexport const storeDeliveryAiCapability = storeSetupCapability(STORE_DELIVERY_AI_OP, 'local-delivery', {\n noun: 'local delivery setting',\n intents: [\n 'store local delivery the merchant does themselves: delivery zones by postal code with a fee, a minimum and a free-over amount, delivery windows and instructions; switch it off. Live once the build runs. Fees only as the request states them',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n enabled: { type: 'boolean', description: 'false to stop offering local delivery; leave out to offer it.' },\n country: { type: 'string', description: 'The two-letter country the store delivers within, e.g. US.', maxLength: 2 },\n location: {\n type: 'string',\n description: 'The inventory location orders leave from, by name or city, when the request names one.',\n maxLength: STORE_SETUP_LOCATION_MAX,\n },\n zoneName: {\n type: 'string',\n description: 'The delivery zone to add, change or remove, e.g. \"Downtown\".',\n maxLength: STORE_SETUP_NAME_MAX,\n },\n postcodes: {\n type: 'array',\n description: 'The zone’s postal codes: exact (\"78701\"), a prefix (\"787*\") or a range (\"78701-78705\"). Required for a new zone.',\n items: { type: 'string', maxLength: 24 },\n maxItems: LOCAL_DELIVERY_POSTCODES_MAX,\n },\n feeUsd: {\n type: 'number',\n description: `The zone’s delivery fee in dollars, 0 for free. Required for a new zone. ${STATED}`,\n minimum: 0,\n maximum: COMMERCE_MAX_PRICE_USD,\n },\n minimumUsd: { type: 'number', description: `The smallest order the zone delivers, in dollars. ${STATED}`, minimum: 0, maximum: COMMERCE_MAX_PRICE_USD },\n freeOverUsd: { type: 'number', description: `Order total in dollars at which delivery is free. ${STATED}`, minimum: 0, maximum: COMMERCE_MAX_PRICE_USD },\n removeZone: { type: 'boolean', description: 'true to remove the zone named zoneName.' },\n windows: {\n type: 'string',\n description: 'Delivery windows as the request gives them, e.g. \"Mo-Fr 09:00-12:00; Sa 10:00-14:00\". Delivery is offered only with at least one window.',\n maxLength: PICKUP_HOURS_MAX,\n },\n leadTimeMinutes: {\n type: 'integer',\n description: 'How long before a window an order must be placed, in minutes, when the request says.',\n minimum: 0,\n maximum: STORE_SETUP_MAX_MINUTES,\n },\n daysAhead: { type: 'integer', description: 'How many days ahead a window can be booked (1 to 30), when the request says.', minimum: 1, maximum: 30 },\n instructions: { type: 'string', description: 'What the buyer is told about delivery, as the request says it.', maxLength: PICKUP_INSTRUCTIONS_MAX },\n },\n additionalProperties: false,\n },\n maxPerPlan: 5,\n})\n\nexport const storeTaxAiCapability = storeSetupCapability(STORE_TAX_AI_OP, 'tax', {\n noun: 'tax setting',\n intents: [\n 'store sales tax: collect it at the manual rate the request states for a country or state, calculate it automatically, or not collect it; whether prices include tax; where the store sells from. Live once the build runs. Never a rate the request does not state — \"set up tax\" alone is a question back, not an item',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n mode: {\n type: 'string',\n description:\n 'manual: the rates the merchant states. stripe: automatic calculation per buyer location, ONLY when the request asks for automatic tax. none: the store does not collect sales tax, ONLY when the request says so. Leave out to keep the store’s choice.',\n enum: STORE_TAX_MODES,\n },\n pricesIncludeTax: {\n type: 'boolean',\n description: 'true when the request says prices already include tax (VAT-style); false when it says tax is added on top.',\n },\n originCountry: {\n type: 'string',\n description: 'The two-letter country the store sells from, e.g. US. Manual rates need it.',\n maxLength: 2,\n },\n originState: { type: 'string', description: 'The state or region the store sells from, e.g. TX.', maxLength: 3 },\n rateCountry: { type: 'string', description: 'The two-letter country a tax rate applies to.', maxLength: 2 },\n rateState: {\n type: 'string',\n description: 'The state or region a tax rate applies to, e.g. TX; leave out for the whole country.',\n maxLength: 3,\n },\n ratePercent: {\n type: 'number',\n description: `The tax rate in percent, e.g. 8.25. ${STATED}`,\n minimum: 0,\n maximum: 100,\n },\n rateLabel: { type: 'string', description: 'The receipt label, e.g. \"TX sales tax\".', maxLength: STORE_TAX_LABEL_MAX },\n removeRate: { type: 'boolean', description: 'true to remove the rate for rateCountry (and rateState).' },\n },\n additionalProperties: false,\n },\n maxPerPlan: 6,\n})\n\nexport const STORE_SETUP_AI_CAPABILITIES: readonly PluginAiCapability[] = [\n storeShippingAiCapability,\n storePickupAiCapability,\n storeDeliveryAiCapability,\n storeTaxAiCapability,\n]\n\n/**\n * Registers the four operations; the console surface calls it beside the\n * writer, since only the console runs AI jobs (AGL-3026). Idempotent.\n */\nexport function registerStoreSetupAiCapabilities(): void {\n for (const capability of STORE_SETUP_AI_CAPABILITIES) {\n registerPluginAiCapability(capability, { pluginId: BUNDLE_ID })\n }\n}\n"],"names":["registerPluginAiCapability","BUNDLE_ID","COMMERCE_MAX_PRICE_USD","LOCAL_DELIVERY_POSTCODES_MAX","PICKUP_HOURS_MAX","PICKUP_INSTRUCTIONS_MAX","STORE_SETUP_COUNTRIES_MAX","STORE_SETUP_LOCATION_MAX","STORE_SETUP_MAX_MINUTES","STORE_SETUP_NAME_MAX","STORE_SETUP_RESOURCE","STORE_SHIPPING_ACTIONS","STORE_SHIPPING_AI_KINDS","STORE_SHIPPING_TIERS_MAX","STORE_TAX_LABEL_MAX","STORE_TAX_MODES","STORE_SHIPPING_AI_OP","STORE_PICKUP_AI_OP","STORE_DELIVERY_AI_OP","STORE_TAX_AI_OP","WHERE","storeSetupContentFromArgs","section","args","content","key","value","Object","entries","undefined","STATED","storeSetupCapability","op","rest","where","freeAllowed","feature","draftResource","live","estimateCredits","degrade","draftContent","item","storeShippingAiCapability","noun","intents","argsSchema","type","properties","action","description","enum","zoneName","maxLength","countries","items","maxItems","rateName","kind","amountUsd","minimum","maximum","freeOverUsd","tiers","required","additionalProperties","maxPerPlan","storePickupAiCapability","location","enabled","hours","instructions","readyWithinMinutes","storeDeliveryAiCapability","country","postcodes","feeUsd","minimumUsd","removeZone","windows","leadTimeMinutes","daysAhead","storeTaxAiCapability","mode","pricesIncludeTax","originCountry","originState","rateCountry","rateState","ratePercent","rateLabel","removeRate","STORE_SETUP_AI_CAPABILITIES","registerStoreSetupAiCapabilities","capability","pluginId"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The `store-settings` writer (AGL-3749) over the console's Admin SDK, with
|
|
19
|
+
* the lockdown verdict every console write door asks: the platform, the
|
|
20
|
+
* workspace, the site and the member, for a write.
|
|
21
|
+
*/
|
|
22
|
+
export declare const storeSetupAiWriter: import("@aglyn/aglyn/src").PluginResourceDraftWriter;
|
|
23
|
+
/**
|
|
24
|
+
* Registers the writer; the console surface calls it, since only the console
|
|
25
|
+
* runs AI jobs (AGL-3026). Idempotent: a second call replaces the first.
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerStoreSetupAiWriter(): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { registerPluginResourceDraftWriter } from "@aglyn/aglyn/plugin-manager/plugin-resource-drafts";
|
|
17
|
+
import { firebaseAdmin, getLockdownVerdict } from "@aglyn/tenant-data-admin";
|
|
18
|
+
import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
19
|
+
import { STORE_SETUP_RESOURCE } from "../model/store-setup-content.js";
|
|
20
|
+
import { createStoreSetupAiWriter } from "./store-setup-ai-writer.js";
|
|
21
|
+
/**
|
|
22
|
+
* The `store-settings` writer (AGL-3749) over the console's Admin SDK, with
|
|
23
|
+
* the lockdown verdict every console write door asks: the platform, the
|
|
24
|
+
* workspace, the site and the member, for a write.
|
|
25
|
+
*/ export const storeSetupAiWriter = createStoreSetupAiWriter({
|
|
26
|
+
firestore: ()=>firebaseAdmin.app().firestore(),
|
|
27
|
+
lockdown: async ({ uid, org, host })=>Boolean(await getLockdownVerdict({
|
|
28
|
+
staff: false,
|
|
29
|
+
uid,
|
|
30
|
+
org: org,
|
|
31
|
+
host: host,
|
|
32
|
+
intent: 'write'
|
|
33
|
+
}))
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Registers the writer; the console surface calls it, since only the console
|
|
37
|
+
* runs AI jobs (AGL-3026). Idempotent: a second call replaces the first.
|
|
38
|
+
*/ export function registerStoreSetupAiWriter() {
|
|
39
|
+
registerPluginResourceDraftWriter(STORE_SETUP_RESOURCE, storeSetupAiWriter, {
|
|
40
|
+
pluginId: BUNDLE_ID
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=store-setup-ai-writer.console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/store-setup-ai-writer.console.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerPluginResourceDraftWriter } from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts'\nimport { firebaseAdmin, getLockdownVerdict } from '@aglyn/tenant-data-admin'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { STORE_SETUP_RESOURCE } from '../model/store-setup-content'\nimport { createStoreSetupAiWriter } from './store-setup-ai-writer'\n\n/**\n * The `store-settings` writer (AGL-3749) over the console's Admin SDK, with\n * the lockdown verdict every console write door asks: the platform, the\n * workspace, the site and the member, for a write.\n */\nexport const storeSetupAiWriter = createStoreSetupAiWriter({\n firestore: () => firebaseAdmin.app().firestore() as unknown as FirebaseFirestore.Firestore,\n lockdown: async ({ uid, org, host }) =>\n Boolean(await getLockdownVerdict({ staff: false, uid, org: org as never, host: host as never, intent: 'write' })),\n})\n\n/**\n * Registers the writer; the console surface calls it, since only the console\n * runs AI jobs (AGL-3026). Idempotent: a second call replaces the first.\n */\nexport function registerStoreSetupAiWriter(): void {\n registerPluginResourceDraftWriter(STORE_SETUP_RESOURCE, storeSetupAiWriter, { pluginId: BUNDLE_ID })\n}\n"],"names":["registerPluginResourceDraftWriter","firebaseAdmin","getLockdownVerdict","BUNDLE_ID","STORE_SETUP_RESOURCE","createStoreSetupAiWriter","storeSetupAiWriter","firestore","app","lockdown","uid","org","host","Boolean","staff","intent","registerStoreSetupAiWriter","pluginId"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,iCAAiC,QAAQ,qDAAoD;AACtG,SAASC,aAAa,EAAEC,kBAAkB,QAAQ,2BAA0B;AAC5E,SAASC,SAAS,QAAQ,gCAA4B;AACtD,SAASC,oBAAoB,QAAQ,kCAA8B;AACnE,SAASC,wBAAwB,QAAQ,6BAAyB;AAElE;;;;CAIC,GACD,OAAO,MAAMC,qBAAqBD,yBAAyB;IACzDE,WAAW,IAAMN,cAAcO,GAAG,GAAGD,SAAS;IAC9CE,UAAU,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE,GACjCC,QAAQ,MAAMX,mBAAmB;YAAEY,OAAO;YAAOJ;YAAKC,KAAKA;YAAcC,MAAMA;YAAeG,QAAQ;QAAQ;AAClH,GAAE;AAEF;;;CAGC,GACD,OAAO,SAASC;IACdhB,kCAAkCI,sBAAsBE,oBAAoB;QAAEW,UAAUd;IAAU;AACpG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { PluginDraftContext, PluginResourceDraftWriter } from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts';
|
|
18
|
+
type Firestore = FirebaseFirestore.Firestore;
|
|
19
|
+
type Stored = Record<string, unknown>;
|
|
20
|
+
/** The refusal for a member without the publishing role (admin or editor). */
|
|
21
|
+
export declare const STORE_SETUP_ROLE_REFUSAL = "Changing store settings through AI needs an admin or editor role";
|
|
22
|
+
/** The refusal for a plan without commerce. */
|
|
23
|
+
export declare const STORE_SETUP_PLAN_REFUSAL = "Selling online is not included in your plan \u2014 see Billing";
|
|
24
|
+
/** What a member is told while a lockdown refuses writes to the site. */
|
|
25
|
+
export declare const STORE_SETUP_LOCKED_REFUSAL = "This site is not accepting changes right now.";
|
|
26
|
+
/** Whether a lockdown refuses this member's write to this site; `true` refuses. */
|
|
27
|
+
export type StoreSetupLockdownCheck = (input: {
|
|
28
|
+
uid: string;
|
|
29
|
+
org: PluginDraftContext['org'];
|
|
30
|
+
host: Stored;
|
|
31
|
+
}) => Promise<boolean>;
|
|
32
|
+
export interface StoreSetupAiWriterDeps {
|
|
33
|
+
firestore: () => Firestore;
|
|
34
|
+
lockdown: StoreSetupLockdownCheck;
|
|
35
|
+
}
|
|
36
|
+
export declare function createStoreSetupAiWriter(deps: StoreSetupAiWriterDeps): PluginResourceDraftWriter;
|
|
37
|
+
export {};
|