@seamlet/astro 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +39 -4
- package/components/RequestForm.astro +7 -15
- package/dist/bridge.d.ts +3 -2
- package/dist/bridge.js +2 -2
- package/dist/{chunk-ULOKDC6D.js → chunk-CTS7Q45A.js} +1 -1
- package/dist/{chunk-JQ4YD7MM.js → chunk-NOAAAA5T.js} +2 -2
- package/dist/{chunk-TMN7KG5M.js → chunk-PAGIPRTS.js} +80 -3
- package/dist/{chunk-BCJUH3ZD.js → chunk-XZDRTVJH.js} +1 -1
- package/dist/cli.js +4 -4
- package/dist/client.js +1 -1
- package/dist/{parse-content-CT2cUVL-.d.ts → content-ZG6F3MPA.d.ts} +1 -81
- package/dist/feeds.d.ts +50 -0
- package/dist/feeds.js +174 -0
- package/dist/index.js +10 -10
- package/dist/{messages-Dwjthhrk.d.ts → messages-d-elsH_0.d.ts} +2 -1
- package/dist/parse-content-Dtec5MKj.d.ts +83 -0
- package/dist/presets-Ch54FeQK.d.ts +104 -0
- package/dist/preview-requests.d.ts +3 -2
- package/dist/preview-requests.js +3 -3
- package/dist/protocol.d.ts +4 -3
- package/dist/protocol.js +2 -2
- package/dist/{request-sending-ZBTK5L7U.js → request-sending-WCEHXPWV.js} +1 -1
- package/dist/routes/media.js +5 -5
- package/dist/schema.d.ts +44 -104
- package/dist/schema.js +11 -3
- package/dist/{site-description-cKiFtNHW.d.ts → site-description-0UU5Wukx.d.ts} +2 -1
- package/dist/site.d.ts +3 -2
- package/dist/site.js +5 -5
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
- The consent of a form links to the business's own policy, a page of the site (`policyHref`, `/privacy` by default, `PRIVACY_PAGE_PATH`), not to texts kept by the CMS: the business is the operator of its visitors' data, and the CMS only passes requests on. `privacyPolicyFields()` is the policy as content and `privacyPolicyTextOf({ siteTitle, operator, forms })` a template to start it with.
|
|
6
|
+
- Breaking: `RequestForm.astro` has no `consentHref` and no separate paragraph of the policy (`seamlet-form-policy`); `legalPagePathOf` and `LegalDocument` are gone. The reason `closed` of `seamlet:request-failed` now means the CMS has nobody to mail the site's requests to.
|
|
7
|
+
|
|
8
|
+
## 1.5.0
|
|
9
|
+
|
|
10
|
+
- Feeds of the catalog: `@seamlet/astro/feeds` with `yandexFeedOf` (YML for Яндекс), `avitoFeedOf` (an Avito autoload file, with the fields of its category from the site) and `productOffersOf`, the offers of `productFields` records.
|
|
11
|
+
- A calculator whose prices the owner keeps: `ratesField()` and `estimateOf(rates, amounts)`.
|
|
12
|
+
|
|
3
13
|
## 1.4.0
|
|
4
14
|
|
|
5
15
|
- Documents: `file({ label })` holds a PDF the owner uploads in the CMS, `{ src, name }` (`FileValue`): a price list, a menu, a contract. An empty name of a file asks for its file (`missing-file-src`). A static build copies the uploaded documents its pages link to, as it copies the photos, and the route of uploads serves them on request; `isUploadedFile` names both.
|
package/README.md
CHANGED
|
@@ -375,7 +375,7 @@ What was opened stays open while the page is rendered anew after every edit: a p
|
|
|
375
375
|
|
|
376
376
|
## Requests
|
|
377
377
|
|
|
378
|
-
A visitor sends the business a request from the site: «Обратный звонок», «Рассчитать стоимость», «Бронь столика». The site declares its forms, gives them to `defineSeamletSite` and renders them; the CMS
|
|
378
|
+
A visitor sends the business a request from the site: «Обратный звонок», «Рассчитать стоимость», «Бронь столика». The site declares its forms, gives them to `defineSeamletSite` and renders them; the CMS passes every request on by mail to the people who edit the site and keeps nothing once it is delivered.
|
|
379
379
|
|
|
380
380
|
```ts
|
|
381
381
|
// src/forms.ts
|
|
@@ -420,15 +420,15 @@ import { estimateForm } from "../forms";
|
|
|
420
420
|
|
|
421
421
|
The fields are `requestText` (a line), `requestLongText` (several lines), `requestPhone`, `requestEmail` and `requestChoice` (one of `options`); each may be `required`, and a text has a `maxLength` (200 for a line, 2000 for several by default). A field's name is a name such as `phone` or `preferredTime`. The form's `title` names its requests in the CMS and in the letters.
|
|
422
422
|
|
|
423
|
-
`RequestForm.astro` renders plain elements with classes (`seamlet-form`, `seamlet-form-field`, `seamlet-form-issue`, `seamlet-form-consent`, `seamlet-form-
|
|
423
|
+
`RequestForm.astro` renders plain elements with classes (`seamlet-form`, `seamlet-form-field`, `seamlet-form-issue`, `seamlet-form-consent`, `seamlet-form-submit`, `seamlet-form-sent`, `seamlet-form-failed`), which the site styles from around it: `.contacts :global(.seamlet-form-field)`. Its props are the `form`, the words of the button (`submitLabel`), what the visitor reads once the request is sent or could not be (`sentText`, `failedText`), the page of the business's policy the consent links to (`policyHref`, the site's own `/privacy` by default, `PRIVACY_PAGE_PATH`) and `instance`, which tells apart two forms of the same id on one page.
|
|
424
424
|
|
|
425
|
-
The visitor consents with a checkbox of its own, never checked beforehand,
|
|
425
|
+
The visitor consents with a checkbox of its own, never checked beforehand, on the terms of the business's policy, a page of the site: `/privacy` unless `policyHref` names another. The business is the operator of its visitors' data and publishes its policy; Seamlet only passes a request on by its commission. `privacyPolicyFields()` is the policy as content the owner edits, and `privacyPolicyTextOf({ siteTitle, operator, forms })` starts it with the business's details and what its forms ask (152-ФЗ): put it in the initial content and render it with `RichText` at `/privacy`. While the CMS has nobody to mail a site's requests to, it takes none, and the form says it could not send. Without a script the form is posted to the CMS, which answers with a page of its own; with the package's script (on every page, loaded only where a form is) the visitor stays on the page. The script checks what was typed with the code the CMS checks it with (`readRequestValues`), says what to fix under each field and sends the request.
|
|
426
426
|
|
|
427
427
|
The site's own code hears every step from events on the form element, which bubble:
|
|
428
428
|
|
|
429
429
|
- `seamlet:request-send` (`REQUEST_SEND_EVENT`), before the request is sent, with `{ form, entries }`. Cancelable: after `event.preventDefault()` the package sends nothing, and the site sends the request its own way.
|
|
430
430
|
- `seamlet:request-sent` (`REQUEST_SENT_EVENT`), once the CMS has kept it, with `{ form, entries, id }`: a goal of the site's analytics, its own message.
|
|
431
|
-
- `seamlet:request-failed` (`REQUEST_FAILED_EVENT`), with `{ form, reason, issues }`; `reason` is `invalid`, `closed` (the
|
|
431
|
+
- `seamlet:request-failed` (`REQUEST_FAILED_EVENT`), with `{ form, reason, issues }`; `reason` is `invalid`, `closed` (the CMS has nobody to mail the site's requests to), `too-many` or `unavailable`.
|
|
432
432
|
|
|
433
433
|
```ts
|
|
434
434
|
document.addEventListener(REQUEST_SENT_EVENT, (event) => {
|
|
@@ -438,6 +438,41 @@ document.addEventListener(REQUEST_SENT_EVENT, (event) => {
|
|
|
438
438
|
|
|
439
439
|
A site whose `Content-Security-Policy` sets `connect-src` or `form-action` lets the CMS's origin in both. A request the policy stops on its way is posted by the browser as a plain form.
|
|
440
440
|
|
|
441
|
+
## A calculator
|
|
442
|
+
|
|
443
|
+
`ratesField()` is a collection of rates the owner keeps (what is counted, its unit, its price), and `estimateOf(rates, amounts)` sums what a visitor chose, the amounts known by the ids of their rates, in whole rubles. The site's own script asks the amounts and shows the sum; the page writes the rates for it, `data-rates={JSON.stringify(content.rates)}`. A new price reaches the calculator with the next publication.
|
|
444
|
+
|
|
445
|
+
## Feeds of the catalog
|
|
446
|
+
|
|
447
|
+
`@seamlet/astro/feeds` writes the catalog for the places that sell it, from the published content: `yandexFeedOf(shop, offers, madeAt)` in YML (Яндекс Директ, Бизнес, Маркет) and `avitoFeedOf(seller, offers, fieldsOf?)` as an Avito autoload file, `fieldsOf` giving the fields Avito's category asks. `productOffersOf(products, { siteUrl, pathOf })` makes the offers of `productFields` records, leaving the hidden ones out; a product without a price is left out of both feeds.
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
// src/pages/feeds/yandex.xml.ts
|
|
451
|
+
import { productOffersOf, yandexFeedOf } from "@seamlet/astro/feeds";
|
|
452
|
+
import site from "../../seamlet";
|
|
453
|
+
import { productPages } from "../../schema";
|
|
454
|
+
|
|
455
|
+
export async function GET() {
|
|
456
|
+
const content = await site.loadPublishedContent();
|
|
457
|
+
const offers = productOffersOf(content.products, {
|
|
458
|
+
siteUrl: "https://lesnaya.ru",
|
|
459
|
+
pathOf: productPages.pathOf,
|
|
460
|
+
});
|
|
461
|
+
const feed = yandexFeedOf(
|
|
462
|
+
{
|
|
463
|
+
name: "Лесная мастерская",
|
|
464
|
+
company: "ООО «Лесная мастерская»",
|
|
465
|
+
url: "https://lesnaya.ru",
|
|
466
|
+
},
|
|
467
|
+
offers,
|
|
468
|
+
new Date(),
|
|
469
|
+
);
|
|
470
|
+
return new Response(feed, {
|
|
471
|
+
headers: { "Content-Type": "application/xml; charset=utf-8" },
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
441
476
|
## What the integration adds
|
|
442
477
|
|
|
443
478
|
- `/preview` and `/preview/<page>`: the preview the CMS's editor frames, the pages of records too (at their address or at the record's id, a page the site does not show too). `GET` shows the published content; `POST` with the content as JSON shows that content without saving it, which is how the editor shows every edit at once. Only the CMS may frame it (`Content-Security-Policy: frame-ancestors`), and it is never indexed or cached; its refusals (an address of no page, a record a draft does not have, a draft that is not JSON or is over 1 MB) say the same.
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
// (`.contacts :global(.seamlet-form-field)`). Without a script it is a form posted to the CMS, and
|
|
4
4
|
// the CMS answers with a page of its own; the package's script sends it in place. The checkbox of
|
|
5
5
|
// consent stands apart from the fields and is never checked beforehand, as the law asks: the
|
|
6
|
-
// visitor consents
|
|
6
|
+
// visitor consents on the terms of the business's policy, a page of the site itself.
|
|
7
7
|
import { cmsOrigin, siteId } from "virtual:seamlet/config";
|
|
8
8
|
import {
|
|
9
|
-
legalPagePathOf,
|
|
10
9
|
maxLengthOf,
|
|
10
|
+
PRIVACY_PAGE_PATH,
|
|
11
11
|
REQUEST_CONSENT_KEY,
|
|
12
12
|
REQUEST_FORM_KEY,
|
|
13
13
|
REQUEST_PAGE_KEY,
|
|
@@ -25,9 +25,7 @@ interface Props {
|
|
|
25
25
|
readonly sentText?: string;
|
|
26
26
|
/** What the visitor reads when the request could not be sent. */
|
|
27
27
|
readonly failedText?: string;
|
|
28
|
-
/** Where the
|
|
29
|
-
readonly consentHref?: string;
|
|
30
|
-
/** Where the business's policy is: the CMS's page of it unless the site has its own. */
|
|
28
|
+
/** Where the business's policy is: the site's `/privacy` unless it says another page. */
|
|
31
29
|
readonly policyHref?: string;
|
|
32
30
|
/** Tells two forms of the same id on one page apart, in the ids of their elements. */
|
|
33
31
|
readonly instance?: string;
|
|
@@ -39,8 +37,7 @@ const {
|
|
|
39
37
|
submitLabel = "Отправить",
|
|
40
38
|
sentText = "Спасибо! Заявка отправлена, мы скоро свяжемся с вами.",
|
|
41
39
|
failedText = "Не получилось отправить заявку. Попробуйте ещё раз чуть позже.",
|
|
42
|
-
|
|
43
|
-
policyHref = new URL(legalPagePathOf(siteId, "privacy"), cmsOrigin).href,
|
|
40
|
+
policyHref = PRIVACY_PAGE_PATH,
|
|
44
41
|
instance = form.id,
|
|
45
42
|
class: className,
|
|
46
43
|
} = Astro.props;
|
|
@@ -145,9 +142,9 @@ const isLineField = (field: RequestField): field is LineField =>
|
|
|
145
142
|
aria-describedby={issueIdOf(REQUEST_CONSENT_KEY)}
|
|
146
143
|
/>
|
|
147
144
|
<label for={idOf(REQUEST_CONSENT_KEY)}>
|
|
148
|
-
Даю{" "}
|
|
149
|
-
<a href={
|
|
150
|
-
|
|
145
|
+
Даю согласие на обработку персональных данных на условиях{" "}
|
|
146
|
+
<a href={policyHref} target="_blank" rel="noopener">
|
|
147
|
+
политики
|
|
151
148
|
</a>
|
|
152
149
|
</label>
|
|
153
150
|
<p
|
|
@@ -157,11 +154,6 @@ const isLineField = (field: RequestField): field is LineField =>
|
|
|
157
154
|
hidden
|
|
158
155
|
/>
|
|
159
156
|
</div>
|
|
160
|
-
<p class="seamlet-form-policy">
|
|
161
|
-
<a href={policyHref} target="_blank" rel="noopener">
|
|
162
|
-
Политика обработки персональных данных
|
|
163
|
-
</a>
|
|
164
|
-
</p>
|
|
165
157
|
<button class="seamlet-form-submit" type="submit">
|
|
166
158
|
{submitLabel}
|
|
167
159
|
</button>
|
package/dist/bridge.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { F as Fields } from './
|
|
2
|
-
import { P as PageMessage, E as EditorMessage } from './messages-
|
|
1
|
+
import { F as Fields } from './content-ZG6F3MPA.js';
|
|
2
|
+
import { P as PageMessage, E as EditorMessage } from './messages-d-elsH_0.js';
|
|
3
|
+
import './parse-content-Dtec5MKj.js';
|
|
3
4
|
|
|
4
5
|
interface BridgeOptions {
|
|
5
6
|
/** The origin of the CMS whose editor may frame the page, such as `https://cms.example.com`. */
|
package/dist/bridge.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
shortcutOf,
|
|
19
19
|
toggleList,
|
|
20
20
|
toggleMark
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-XZDRTVJH.js";
|
|
22
22
|
import {
|
|
23
23
|
FIELD_PATH_ATTRIBUTE,
|
|
24
24
|
REVEALED_ATTRIBUTE,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
readRichText,
|
|
29
29
|
resolveFieldPath,
|
|
30
30
|
safeHref
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-PAGIPRTS.js";
|
|
32
32
|
|
|
33
33
|
// src/bridge/typed-fields.ts
|
|
34
34
|
function typedKindAt(schema, path) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
pagePathOf
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CTS7Q45A.js";
|
|
4
4
|
import {
|
|
5
5
|
FIELD_PATH_SEPARATOR,
|
|
6
6
|
collectionAt,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
newRecord,
|
|
10
10
|
recordAt,
|
|
11
11
|
recordPageAt
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PAGIPRTS.js";
|
|
13
13
|
|
|
14
14
|
// src/preview-requests.ts
|
|
15
15
|
var MAX_DRAFT_BYTES = 1024 * 1024;
|
|
@@ -1002,6 +1002,28 @@ function percentOf(fraction) {
|
|
|
1002
1002
|
return `${String(rounded)}%`;
|
|
1003
1003
|
}
|
|
1004
1004
|
|
|
1005
|
+
// src/schema/rates.ts
|
|
1006
|
+
function ratesField(options = {}) {
|
|
1007
|
+
return collection({
|
|
1008
|
+
label: options.label ?? "\u0420\u0430\u0441\u0446\u0435\u043D\u043A\u0438 \u043A\u0430\u043B\u044C\u043A\u0443\u043B\u044F\u0442\u043E\u0440\u0430",
|
|
1009
|
+
itemTitle: "name",
|
|
1010
|
+
item: {
|
|
1011
|
+
name: text({ label: "\u0427\u0442\u043E \u0441\u0447\u0438\u0442\u0430\u0435\u043C", maxLength: 80 }),
|
|
1012
|
+
unit: text({ label: "\u0415\u0434\u0438\u043D\u0438\u0446\u0430", maxLength: 12 }),
|
|
1013
|
+
price: number({ label: "\u0426\u0435\u043D\u0430 \u0437\u0430 \u0435\u0434\u0438\u043D\u0438\u0446\u0443, \u20BD", min: 0 })
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
function estimateOf(rates, amounts) {
|
|
1018
|
+
const total = rates.reduce((sum, rate) => {
|
|
1019
|
+
const price = rate.price ?? 0;
|
|
1020
|
+
const amount = rate.id === void 0 ? 0 : amounts[rate.id] ?? 0;
|
|
1021
|
+
const isCounted = Number.isFinite(amount) && amount > 0;
|
|
1022
|
+
return isCounted ? sum + amount * price : sum;
|
|
1023
|
+
}, 0);
|
|
1024
|
+
return Math.round(total);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1005
1027
|
// src/schema/presets.ts
|
|
1006
1028
|
function seoFields(options = {}) {
|
|
1007
1029
|
return group({
|
|
@@ -1805,8 +1827,59 @@ function isFilledValue(reading) {
|
|
|
1805
1827
|
function requestsPathOf(siteId) {
|
|
1806
1828
|
return `/api/sites/${siteId}/requests`;
|
|
1807
1829
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1830
|
+
|
|
1831
|
+
// src/schema/privacy-policy.ts
|
|
1832
|
+
var PRIVACY_PAGE_PATH = "/privacy";
|
|
1833
|
+
var WITHDRAWAL_DAYS = 30;
|
|
1834
|
+
var ANSWER_WORKING_DAYS = 10;
|
|
1835
|
+
function privacyPolicyFields(options = {}) {
|
|
1836
|
+
return group({
|
|
1837
|
+
label: options.label ?? "\u041F\u043E\u043B\u0438\u0442\u0438\u043A\u0430 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445",
|
|
1838
|
+
fields: {
|
|
1839
|
+
title: text({ label: "\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A", maxLength: 120 }),
|
|
1840
|
+
text: richText({ label: "\u0422\u0435\u043A\u0441\u0442" })
|
|
1841
|
+
}
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
function privacyPolicyTextOf(source) {
|
|
1845
|
+
const { operator, siteTitle } = source;
|
|
1846
|
+
const operatorName = `${operator.name} (\u0418\u041D\u041D ${operator.inn}, \u0430\u0434\u0440\u0435\u0441: ${operator.address})`;
|
|
1847
|
+
const sentData = sentDataOf(source.forms);
|
|
1848
|
+
return richTextOf(
|
|
1849
|
+
[
|
|
1850
|
+
"1. \u041E\u0431\u0449\u0438\u0435 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u044F",
|
|
1851
|
+
`1.1. \u042D\u0442\u0430 \u043F\u043E\u043B\u0438\u0442\u0438\u043A\u0430 \u043E\u043F\u0438\u0441\u044B\u0432\u0430\u0435\u0442, \u043A\u0430\u043A ${operatorName} \u2014 \u0434\u0430\u043B\u0435\u0435 \xAB\u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\xBB \u2014 \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\u0442 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u0435\u0439 \u0441\u0430\u0439\u0442\u0430 \xAB${siteTitle}\xBB, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u044E\u0442 \u0437\u0430\u044F\u0432\u043A\u0438 \u0447\u0435\u0440\u0435\u0437 \u0435\u0433\u043E \u0444\u043E\u0440\u043C\u044B.`,
|
|
1852
|
+
"1.2. \u041F\u043E\u043B\u0438\u0442\u0438\u043A\u0430 \u0441\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0430 \u043F\u043E \u0424\u0435\u0434\u0435\u0440\u0430\u043B\u044C\u043D\u043E\u043C\u0443 \u0437\u0430\u043A\u043E\u043D\u0443 \u043E\u0442 27.07.2006 \u2116 152-\u0424\u0417 \xAB\u041E \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445\xBB.",
|
|
1853
|
+
"2. \u041A\u0430\u043A\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u044E\u0442\u0441\u044F",
|
|
1854
|
+
`2.1. \u0421\u0432\u0435\u0434\u0435\u043D\u0438\u044F, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u0441\u0430\u043C \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0432 \u0444\u043E\u0440\u043C\u0435 \u0437\u0430\u044F\u0432\u043A\u0438: ${sentData}.`,
|
|
1855
|
+
"2.2. \u0410\u0434\u0440\u0435\u0441 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B, \u0441 \u043A\u043E\u0442\u043E\u0440\u043E\u0439 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0430 \u0437\u0430\u044F\u0432\u043A\u0430, \u0438 \u0432\u0440\u0435\u043C\u044F \u0435\u0451 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438.",
|
|
1856
|
+
"2.3. \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u043D\u0435 \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\u0442 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 \u0438 \u0431\u0438\u043E\u043C\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u0438 \u043F\u0440\u043E\u0441\u0438\u0442 \u043D\u0435 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0438\u0445 \u0432 \u0437\u0430\u044F\u0432\u043A\u0435.",
|
|
1857
|
+
"3. \u0426\u0435\u043B\u044C, \u043E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0435 \u0438 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435",
|
|
1858
|
+
"3.1. \u0426\u0435\u043B\u044C \u2014 \u0440\u0430\u0441\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C \u0437\u0430\u044F\u0432\u043A\u0443 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044F \u0438 \u0441\u0432\u044F\u0437\u0430\u0442\u044C\u0441\u044F \u0441 \u043D\u0438\u043C \u043F\u043E \u043D\u0435\u0439.",
|
|
1859
|
+
"3.2. \u041E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0435 \u2014 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044F. \u041E\u0442\u043C\u0435\u0447\u0430\u044F \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0432 \u0444\u043E\u0440\u043C\u0435 \u043F\u0435\u0440\u0435\u0434 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u043E\u0439 \u0437\u0430\u044F\u0432\u043A\u0438, \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u043E, \u0441\u0432\u043E\u0435\u0439 \u0432\u043E\u043B\u0435\u0439 \u0438 \u0432 \u0441\u0432\u043E\u0451\u043C \u0438\u043D\u0442\u0435\u0440\u0435\u0441\u0435 \u0434\u0430\u0451\u0442 \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0443 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u043D\u0430 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0443 \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 \u043D\u0430 \u0443\u0441\u043B\u043E\u0432\u0438\u044F\u0445 \u044D\u0442\u043E\u0439 \u043F\u043E\u043B\u0438\u0442\u0438\u043A\u0438.",
|
|
1860
|
+
"4. \u041A\u0430\u043A \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u044E\u0442\u0441\u044F \u0434\u0430\u043D\u043D\u044B\u0435",
|
|
1861
|
+
"4.1. \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442, \u0437\u0430\u043F\u0438\u0441\u044B\u0432\u0430\u0435\u0442, \u0445\u0440\u0430\u043D\u0438\u0442, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442, \u0443\u0434\u0430\u043B\u044F\u0435\u0442 \u0438 \u0443\u043D\u0438\u0447\u0442\u043E\u0436\u0430\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0435 \u0441 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438.",
|
|
1862
|
+
"4.2. \u041F\u0440\u0438\u0451\u043C \u0437\u0430\u044F\u0432\u043E\u043A \u0441 \u0444\u043E\u0440\u043C \u0441\u0430\u0439\u0442\u0430 \u043F\u043E \u043F\u043E\u0440\u0443\u0447\u0435\u043D\u0438\u044E \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0430 \u043E\u0431\u0435\u0441\u043F\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 Seamlet: \u043E\u043D \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0437\u0430\u044F\u0432\u043A\u0443 \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0443 \u0438 \u043D\u0435 \u0445\u0440\u0430\u043D\u0438\u0442 \u0435\u0451 \u0434\u043E\u043B\u044C\u0448\u0435, \u0447\u0435\u043C \u043D\u0443\u0436\u043D\u043E \u0434\u043B\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438, \u0441\u043E\u0431\u043B\u044E\u0434\u0430\u044F \u043A\u043E\u043D\u0444\u0438\u0434\u0435\u043D\u0446\u0438\u0430\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u0438 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u044F \u0441\u0442\u0430\u0442\u044C\u0438 19 \u0424\u0435\u0434\u0435\u0440\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0437\u0430\u043A\u043E\u043D\u0430 \u2116 152-\u0424\u0417. \u0414\u0430\u043D\u043D\u044B\u0435 \u0445\u0440\u0430\u043D\u044F\u0442\u0441\u044F \u0432 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u043E\u0439 \u0424\u0435\u0434\u0435\u0440\u0430\u0446\u0438\u0438.",
|
|
1863
|
+
"4.3. \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u043D\u0435 \u0440\u0430\u0441\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u044F\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0435 \u0438 \u043D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0438\u0445 \u0442\u0440\u0435\u0442\u044C\u0438\u043C \u043B\u0438\u0446\u0430\u043C, \u043A\u0440\u043E\u043C\u0435 \u0441\u043B\u0443\u0447\u0430\u0435\u0432, \u043F\u0440\u0435\u0434\u0443\u0441\u043C\u043E\u0442\u0440\u0435\u043D\u043D\u044B\u0445 \u0437\u0430\u043A\u043E\u043D\u043E\u043C.",
|
|
1864
|
+
"5. \u0421\u0440\u043E\u043A\u0438",
|
|
1865
|
+
"5.1. \u0414\u0430\u043D\u043D\u044B\u0435 \u0445\u0440\u0430\u043D\u044F\u0442\u0441\u044F, \u043F\u043E\u043A\u0430 \u044D\u0442\u043E \u043D\u0443\u0436\u043D\u043E \u0434\u043B\u044F \u0440\u0430\u0441\u0441\u043C\u043E\u0442\u0440\u0435\u043D\u0438\u044F \u0437\u0430\u044F\u0432\u043A\u0438, \u043D\u043E \u043D\u0435 \u0434\u043E\u043B\u044C\u0448\u0435 \u043E\u0434\u043D\u043E\u0433\u043E \u0433\u043E\u0434\u0430 \u0441\u043E \u0434\u043D\u044F \u0435\u0451 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438, \u043F\u043E\u0441\u043B\u0435 \u0447\u0435\u0433\u043E \u0443\u0434\u0430\u043B\u044F\u044E\u0442\u0441\u044F.",
|
|
1866
|
+
`5.2. \u041F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u043C\u043E\u0436\u0435\u0442 \u043E\u0442\u043E\u0437\u0432\u0430\u0442\u044C \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435, \u043D\u0430\u043F\u0438\u0441\u0430\u0432 \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0443 \u043D\u0430 ${operator.email}. \u0422\u043E\u0433\u0434\u0430 \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u043F\u0440\u0435\u043A\u0440\u0430\u0442\u0438\u0442 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0443 \u0438 \u0443\u0434\u0430\u043B\u0438\u0442 \u0434\u0430\u043D\u043D\u044B\u0435 \u0432 \u0442\u0435\u0447\u0435\u043D\u0438\u0435 ${String(WITHDRAWAL_DAYS)} \u0434\u043D\u0435\u0439, \u0435\u0441\u043B\u0438 \u0438\u043D\u043E\u0435 \u043D\u0435 \u043F\u0440\u0435\u0434\u0443\u0441\u043C\u043E\u0442\u0440\u0435\u043D\u043E \u0437\u0430\u043A\u043E\u043D\u043E\u043C.`,
|
|
1867
|
+
"6. \u041F\u0440\u0430\u0432\u0430 \u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044F",
|
|
1868
|
+
`6.1. \u041F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B\u044C \u0432\u043F\u0440\u0430\u0432\u0435 \u0443\u0437\u043D\u0430\u0442\u044C, \u043A\u0430\u043A \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u044E\u0442\u0441\u044F \u0435\u0433\u043E \u0434\u0430\u043D\u043D\u044B\u0435, \u043F\u043E\u0442\u0440\u0435\u0431\u043E\u0432\u0430\u0442\u044C \u0443\u0442\u043E\u0447\u043D\u0438\u0442\u044C, \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0438\u043B\u0438 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0445, \u043E\u0442\u043E\u0437\u0432\u0430\u0442\u044C \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0438 \u043E\u0431\u0436\u0430\u043B\u043E\u0432\u0430\u0442\u044C \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0430 \u0432 \u0420\u043E\u0441\u043A\u043E\u043C\u043D\u0430\u0434\u0437\u043E\u0440\u0435 \u0438\u043B\u0438 \u0432 \u0441\u0443\u0434\u0435. \u0414\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u0434\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u043D\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440\u0443 \u043D\u0430 ${operator.email}; \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0432 \u0442\u0435\u0447\u0435\u043D\u0438\u0435 ${String(ANSWER_WORKING_DAYS)} \u0440\u0430\u0431\u043E\u0447\u0438\u0445 \u0434\u043D\u0435\u0439.`,
|
|
1869
|
+
"7. \u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u0438\u0442\u0438\u043A\u0438",
|
|
1870
|
+
"7.1. \u041E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u043C\u043E\u0436\u0435\u0442 \u0438\u0437\u043C\u0435\u043D\u044F\u0442\u044C \u043F\u043E\u043B\u0438\u0442\u0438\u043A\u0443. \u041D\u043E\u0432\u0430\u044F \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u044F \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0441 \u043C\u043E\u043C\u0435\u043D\u0442\u0430 \u043F\u0443\u0431\u043B\u0438\u043A\u0430\u0446\u0438\u0438 \u043D\u0430 \u044D\u0442\u043E\u0439 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435."
|
|
1871
|
+
].join("\n\n")
|
|
1872
|
+
);
|
|
1873
|
+
}
|
|
1874
|
+
function sentDataOf(forms) {
|
|
1875
|
+
const labels = forms.flatMap(
|
|
1876
|
+
(form) => Object.values(form.fields).map((field) => lowercaseFirst(field.label))
|
|
1877
|
+
);
|
|
1878
|
+
const unique = [...new Set(labels)];
|
|
1879
|
+
return unique.length === 0 ? "\u0438\u043C\u044F \u0438 \u043A\u043E\u043D\u0442\u0430\u043A\u0442\u044B" : unique.join(", ");
|
|
1880
|
+
}
|
|
1881
|
+
function lowercaseFirst(label) {
|
|
1882
|
+
return `${label.charAt(0).toLocaleLowerCase("ru")}${label.slice(1)}`;
|
|
1810
1883
|
}
|
|
1811
1884
|
|
|
1812
1885
|
// src/schema/request-events.ts
|
|
@@ -1868,6 +1941,8 @@ export {
|
|
|
1868
1941
|
REVEALED_ATTRIBUTE,
|
|
1869
1942
|
REVEAL_EVENT,
|
|
1870
1943
|
imagePosition,
|
|
1944
|
+
ratesField,
|
|
1945
|
+
estimateOf,
|
|
1871
1946
|
seoFields,
|
|
1872
1947
|
contactsFields,
|
|
1873
1948
|
WEEKDAYS,
|
|
@@ -1917,7 +1992,9 @@ export {
|
|
|
1917
1992
|
isPhoneNumber,
|
|
1918
1993
|
isEmailAddress,
|
|
1919
1994
|
requestsPathOf,
|
|
1920
|
-
|
|
1995
|
+
PRIVACY_PAGE_PATH,
|
|
1996
|
+
privacyPolicyFields,
|
|
1997
|
+
privacyPolicyTextOf,
|
|
1921
1998
|
REQUEST_SEND_EVENT,
|
|
1922
1999
|
REQUEST_SENT_EVENT,
|
|
1923
2000
|
REQUEST_FAILED_EVENT
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
SITE_MODULE_FILE
|
|
4
|
-
} from "./chunk-QCVWHHJC.js";
|
|
5
2
|
import {
|
|
6
3
|
SITE_CONFIG_FILE,
|
|
7
4
|
isSiteId,
|
|
8
5
|
readSiteConfig
|
|
9
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PAGIPRTS.js";
|
|
7
|
+
import {
|
|
8
|
+
SITE_MODULE_FILE
|
|
9
|
+
} from "./chunk-QCVWHHJC.js";
|
|
10
10
|
|
|
11
11
|
// src/cli.ts
|
|
12
12
|
import process from "process";
|
package/dist/client.js
CHANGED
|
@@ -16,7 +16,7 @@ if (isFramed && isPreview) {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
if (document.querySelector(REQUEST_FORM_SELECTOR) !== null) {
|
|
19
|
-
void import("./request-sending-
|
|
19
|
+
void import("./request-sending-WCEHXPWV.js").then(({ connectRequestForms }) => {
|
|
20
20
|
connectRequestForms(document, { isPreview });
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -239,84 +239,4 @@ type FieldValue = string | number | boolean | null | readonly string[] | ImageVa
|
|
|
239
239
|
declare function defaultValue(field: Field): FieldValue;
|
|
240
240
|
declare function defaultContent(fields: Fields): Content;
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
type FieldPath = readonly (string | number)[];
|
|
244
|
-
type ContentIssue = {
|
|
245
|
-
readonly path: FieldPath;
|
|
246
|
-
readonly code: "invalid-type";
|
|
247
|
-
} | {
|
|
248
|
-
readonly path: FieldPath;
|
|
249
|
-
readonly code: "invalid-date";
|
|
250
|
-
} | {
|
|
251
|
-
readonly path: FieldPath;
|
|
252
|
-
readonly code: "invalid-time";
|
|
253
|
-
} | {
|
|
254
|
-
readonly path: FieldPath;
|
|
255
|
-
readonly code: "too-long";
|
|
256
|
-
readonly maxLength: number;
|
|
257
|
-
} | {
|
|
258
|
-
readonly path: FieldPath;
|
|
259
|
-
readonly code: "below-min";
|
|
260
|
-
readonly min: number;
|
|
261
|
-
} | {
|
|
262
|
-
readonly path: FieldPath;
|
|
263
|
-
readonly code: "above-max";
|
|
264
|
-
readonly max: number;
|
|
265
|
-
} | {
|
|
266
|
-
readonly path: FieldPath;
|
|
267
|
-
readonly code: "missing-image-src";
|
|
268
|
-
} | {
|
|
269
|
-
readonly path: FieldPath;
|
|
270
|
-
readonly code: "missing-file-src";
|
|
271
|
-
} | {
|
|
272
|
-
readonly path: FieldPath;
|
|
273
|
-
readonly code: "missing-link-href";
|
|
274
|
-
} | {
|
|
275
|
-
readonly path: FieldPath;
|
|
276
|
-
readonly code: "unsupported-link-href";
|
|
277
|
-
} | {
|
|
278
|
-
readonly path: FieldPath;
|
|
279
|
-
readonly code: "unsupported-url";
|
|
280
|
-
} | {
|
|
281
|
-
readonly path: FieldPath;
|
|
282
|
-
readonly code: "unknown-choice";
|
|
283
|
-
readonly value: string;
|
|
284
|
-
} | {
|
|
285
|
-
readonly path: FieldPath;
|
|
286
|
-
readonly code: "missing-record";
|
|
287
|
-
readonly id: string;
|
|
288
|
-
}
|
|
289
|
-
/** A slug with a character an address does not have. */
|
|
290
|
-
| {
|
|
291
|
-
readonly path: FieldPath;
|
|
292
|
-
readonly code: "invalid-slug";
|
|
293
|
-
}
|
|
294
|
-
/** A slug another record of the collection has as its slug or its id. */
|
|
295
|
-
| {
|
|
296
|
-
readonly path: FieldPath;
|
|
297
|
-
readonly code: "taken-slug";
|
|
298
|
-
};
|
|
299
|
-
interface ParsedContent<C> {
|
|
300
|
-
readonly content: C;
|
|
301
|
-
readonly issues: readonly ContentIssue[];
|
|
302
|
-
}
|
|
303
|
-
declare function formatFieldPath(path: FieldPath): string;
|
|
304
|
-
/**
|
|
305
|
-
* The length that `maxLength` limits: characters as people see them (grapheme clusters), so
|
|
306
|
-
* "й" and "👍🏽" are one character each, whatever number of code units they take.
|
|
307
|
-
*/
|
|
308
|
-
declare function countCharacters(text: string): number;
|
|
309
|
-
/**
|
|
310
|
-
* Brings any input to the shape of the schema, so the result is always content of that schema:
|
|
311
|
-
* - a field missing from the input (the schema grew after the content was saved) gets its default;
|
|
312
|
-
* - a value of the wrong type or format gets the default too, and an issue;
|
|
313
|
-
* - a value of the right type that breaks a rule of its field (too long, below the minimum) is
|
|
314
|
-
* kept, with an issue: nothing a person typed is lost;
|
|
315
|
-
* - keys the schema does not know are dropped; a record keeps its id (see withRecordIds);
|
|
316
|
-
* - a reference to a record its collection does not have (removed since) is kept, with an issue;
|
|
317
|
-
* - a slug another record of the collection has is kept, with an issue.
|
|
318
|
-
* Content with issues is valid to show and edit, but not to save.
|
|
319
|
-
*/
|
|
320
|
-
declare function parseContent<F extends Fields>(schema: F, input: unknown): ParsedContent<ContentOf<F>>;
|
|
321
|
-
|
|
322
|
-
export { link as $, choice as A, choices as B, type Content as C, type DateField as D, collection as E, type Fields as F, type GroupField as G, countCharacters as H, type ImageField as I, date as J, defaultContent as K, type LinkValue as L, defaultValue as M, type NumberField as N, type OptionValue as O, type ParsedContent as P, defineSchema as Q, type RichText as R, type SlugField as S, type TextField as T, type UrlField as U, type ValueOf as V, file as W, formatFieldPath as X, group as Y, image as Z, linesOf as _, type FieldPath as a, normalizedLine as a0, number as a1, parseContent as a2, plainTextOf as a3, readRichText as a4, reference as a5, references as a6, richText as a7, richTextOf as a8, slug as a9, text as aa, time as ab, toggle as ac, url as ad, type ContentOf as b, type Field as c, type CollectionField as d, type RecordFields as e, type RecordOf as f, type ContentIssue as g, type ImageValue as h, type LinkField as i, type ChoicesField as j, type TimeField as k, type RichTextField as l, type ToggleField as m, type ChoiceField as n, type ChoiceOption as o, type FieldKind as p, type FieldValue as q, type FileField as r, type FileValue as s, type ImageFocus as t, type ReferenceField as u, type ReferencesField as v, type RichBlock as w, type RichLine as x, type RichSpan as y, asOneParagraph as z };
|
|
242
|
+
export { reference as $, collection as A, date as B, type Content as C, type DateField as D, defaultContent as E, type Fields as F, type GroupField as G, defaultValue as H, type ImageField as I, defineSchema as J, file as K, type LinkField as L, group as M, type NumberField as N, type OptionValue as O, image as P, linesOf as Q, type RichTextField as R, type SlugField as S, type TextField as T, type UrlField as U, type ValueOf as V, link as W, normalizedLine as X, number as Y, plainTextOf as Z, readRichText as _, type CollectionField as a, references as a0, richText as a1, richTextOf as a2, slug as a3, text as a4, time as a5, toggle as a6, url as a7, type ToggleField as b, type ChoicesField as c, type TimeField as d, type ContentOf as e, type RichText as f, type RecordOf as g, type Field as h, type RecordFields as i, type ImageValue as j, type LinkValue as k, type ChoiceField as l, type ChoiceOption as m, type FieldKind as n, type FieldValue as o, type FileField as p, type FileValue as q, type ImageFocus as r, type ReferenceField as s, type ReferencesField as t, type RichBlock as u, type RichLine as v, type RichSpan as w, asOneParagraph as x, choice as y, choices as z };
|
package/dist/feeds.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { g as RecordOf } from './content-ZG6F3MPA.js';
|
|
2
|
+
import { p as productFields } from './presets-Ch54FeQK.js';
|
|
3
|
+
|
|
4
|
+
interface FeedOffer {
|
|
5
|
+
/** Stays the same while the product lives: the record's id. */
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
/** The whole address of the product's page, or of the catalog when products have no pages. */
|
|
9
|
+
readonly url: string;
|
|
10
|
+
/** In rubles; a product without a price is left out of the feeds, which require one. */
|
|
11
|
+
readonly price: number | null;
|
|
12
|
+
readonly description: string;
|
|
13
|
+
/** Whole addresses of its photos, the main one first. */
|
|
14
|
+
readonly pictures: readonly string[];
|
|
15
|
+
/** The name of its category, if the catalog has them. */
|
|
16
|
+
readonly category?: string;
|
|
17
|
+
}
|
|
18
|
+
type ProductRecord = RecordOf<ReturnType<typeof productFields>>;
|
|
19
|
+
interface ProductOffersOptions {
|
|
20
|
+
/** The site's address: `https://lesnaya.ru`. */
|
|
21
|
+
readonly siteUrl: string;
|
|
22
|
+
/** The page of a product (`recordPages(...).pathOf`), or none: the catalog's page is used. */
|
|
23
|
+
readonly pathOf?: (product: ProductRecord) => string | undefined;
|
|
24
|
+
/** The page of the catalog, for products without pages of their own. */
|
|
25
|
+
readonly catalogPath?: string;
|
|
26
|
+
readonly categoryOf?: (product: ProductRecord) => string | undefined;
|
|
27
|
+
}
|
|
28
|
+
/** The offers of the products a visitor sees: hidden ones and ones without an id are left out. */
|
|
29
|
+
declare function productOffersOf(products: readonly ProductRecord[], options: ProductOffersOptions): readonly FeedOffer[];
|
|
30
|
+
|
|
31
|
+
interface AvitoSeller {
|
|
32
|
+
/** Where the goods are: the address of the shop or the workshop. */
|
|
33
|
+
readonly address: string;
|
|
34
|
+
readonly contactPhone: string;
|
|
35
|
+
/** The category of Avito the ads go to: «Ремонт и строительство». */
|
|
36
|
+
readonly category: string;
|
|
37
|
+
}
|
|
38
|
+
declare function avitoFeedOf(seller: AvitoSeller, offers: readonly FeedOffer[], fieldsOf?: (offer: FeedOffer) => Readonly<Record<string, string>>): string;
|
|
39
|
+
|
|
40
|
+
interface YandexShop {
|
|
41
|
+
/** The short name buyers know: «Лесная мастерская». */
|
|
42
|
+
readonly name: string;
|
|
43
|
+
/** The company's full name: «ООО «Лесная мастерская»». */
|
|
44
|
+
readonly company: string;
|
|
45
|
+
/** The site's address. */
|
|
46
|
+
readonly url: string;
|
|
47
|
+
}
|
|
48
|
+
declare function yandexFeedOf(shop: YandexShop, offers: readonly FeedOffer[], madeAt: Date): string;
|
|
49
|
+
|
|
50
|
+
export { type AvitoSeller, type FeedOffer, type ProductOffersOptions, type ProductRecord, type YandexShop, avitoFeedOf, productOffersOf, yandexFeedOf };
|