@laioutr/app-shopware 0.16.0 → 0.18.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/dist/module.json +1 -1
- package/dist/module.mjs +1 -1
- package/dist/runtime/server/orchestr/auth/login-oauth.action.d.ts +10 -0
- package/dist/runtime/server/orchestr/auth/login-oauth.action.js +13 -0
- package/dist/runtime/server/orchestr/customer/get-current.action.d.ts +10 -0
- package/dist/runtime/server/orchestr/customer/get-current.action.js +22 -0
- package/dist/runtime/server/orchestr/menu/byAlias.template.js +1 -1
- package/dist/runtime/server/orchestr/product/base.resolver.js +16 -1
- package/dist/runtime/server/orchestr/product/reviews.link.js +12 -1
- package/dist/runtime/server/orchestr/product-variant/base.resolver.js +9 -4
- package/dist/runtime/server/orchestr-helper/requestedFields.js +18 -3
- package/dist/runtime/server/shopware-helper/optionGroupsMapper.d.ts +23 -0
- package/dist/runtime/server/shopware-helper/optionGroupsMapper.js +37 -0
- package/dist/runtime/server/shopware-helper/wellKnownOptionName.d.ts +2 -0
- package/dist/runtime/server/shopware-helper/wellKnownOptionName.js +278 -0
- package/package.json +3 -3
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { CHECKOUT_ENDPOINT_PATH, ADOPT_SESSION_ENDPOINT_PATH, ORDER_HANDOFF_ENDP
|
|
|
4
4
|
import { registerLaioutrApp } from '@laioutr-core/kit';
|
|
5
5
|
|
|
6
6
|
const name = "@laioutr/app-shopware";
|
|
7
|
-
const version = "0.
|
|
7
|
+
const version = "0.18.0";
|
|
8
8
|
|
|
9
9
|
const module$1 = defineNuxtModule({
|
|
10
10
|
meta: {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send a visitor asking for their account to Shopware's own login page. Shopware authenticates
|
|
3
|
+
* with credentials rather than an OAuth handshake, so this answers the union's `account` arm and
|
|
4
|
+
* the storefront navigates there.
|
|
5
|
+
*
|
|
6
|
+
* `returnTo` is dropped: Shopware's login redirect takes one of its own route names, not a URL,
|
|
7
|
+
* so a laioutr path cannot travel through it.
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: any;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useRuntimeConfig } from "#imports";
|
|
2
|
+
import { AuthLoginOauthAction } from "@laioutr-core/canonical-types/ecommerce";
|
|
3
|
+
import { defineShopwareAction } from "../../middleware/defineShopware.js";
|
|
4
|
+
export default defineShopwareAction(AuthLoginOauthAction, async () => {
|
|
5
|
+
const { storefrontUrl } = useRuntimeConfig()["@laioutr/app-shopware"];
|
|
6
|
+
if (!storefrontUrl) {
|
|
7
|
+
throw new Error("storefrontUrl is not configured, so there is no Shopware login page to send the customer to");
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
type: "account",
|
|
11
|
+
link: { type: "url", href: new URL("/account/login", storefrontUrl).toString() }
|
|
12
|
+
};
|
|
13
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the customer behind the request's context token. Shopware answers `403` when the token
|
|
3
|
+
* belongs to a guest context, which is the signal callers use to tell a session from none.
|
|
4
|
+
*
|
|
5
|
+
* `addresses` stays empty: Shopware returns addresses only as an association, and each one needs
|
|
6
|
+
* its `countryId` resolved to the ISO code `MailingAddress` requires. Nothing reads them yet, so
|
|
7
|
+
* the lookup is not made — extend this handler before relying on the field.
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: any;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CustomerGetCurrentAction, UnauthenticatedError } from "@laioutr-core/canonical-types/ecommerce";
|
|
2
|
+
import { defineShopwareAction } from "../../middleware/defineShopware.js";
|
|
3
|
+
export default defineShopwareAction(CustomerGetCurrentAction, async ({ context }) => {
|
|
4
|
+
let customer;
|
|
5
|
+
try {
|
|
6
|
+
customer = await context.storefrontClient.invoke("readCustomer post /account/customer", {});
|
|
7
|
+
} catch {
|
|
8
|
+
throw new UnauthenticatedError();
|
|
9
|
+
}
|
|
10
|
+
const firstName = customer.firstName ?? "";
|
|
11
|
+
const lastName = customer.lastName ?? "";
|
|
12
|
+
const displayName = `${firstName} ${lastName}`.trim();
|
|
13
|
+
return {
|
|
14
|
+
customer: {
|
|
15
|
+
id: customer.id,
|
|
16
|
+
email: customer.email,
|
|
17
|
+
displayName: displayName || (customer.email ?? ""),
|
|
18
|
+
person: { firstName, lastName, salutation: customer.salutation?.salutationKey, title: customer.title ?? void 0 },
|
|
19
|
+
addresses: []
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
});
|
|
@@ -2,7 +2,7 @@ import { MenuByAliasQuery } from "@laioutr-core/canonical-types/ecommerce";
|
|
|
2
2
|
import { defineShopwareQueryTemplateProvider } from "../../middleware/defineShopware.js";
|
|
3
3
|
export default defineShopwareQueryTemplateProvider({
|
|
4
4
|
for: MenuByAliasQuery,
|
|
5
|
-
run: async (
|
|
5
|
+
run: async () => [
|
|
6
6
|
{
|
|
7
7
|
input: {
|
|
8
8
|
alias: "main-navigation"
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
ProductFlags,
|
|
7
7
|
ProductInfo,
|
|
8
8
|
ProductMedia,
|
|
9
|
+
ProductOptionGroups,
|
|
9
10
|
ProductPrices,
|
|
10
11
|
ProductRating,
|
|
11
12
|
ProductSeo
|
|
@@ -16,6 +17,7 @@ import { defineShopwareComponentResolver } from "../../middleware/defineShopware
|
|
|
16
17
|
import { fetchAllProducts } from "../../shopware-helper/fetchAllProductVariants.js";
|
|
17
18
|
import { entitySlug } from "../../shopware-helper/mappers/slugMapper.js";
|
|
18
19
|
import { mapMedia } from "../../shopware-helper/mediaMapper.js";
|
|
20
|
+
import { mapProductOptionGroups } from "../../shopware-helper/optionGroupsMapper.js";
|
|
19
21
|
import { swTranslated } from "../../shopware-helper/swTranslated.js";
|
|
20
22
|
export default defineShopwareComponentResolver({
|
|
21
23
|
label: "Shopware Product Connector",
|
|
@@ -29,6 +31,7 @@ export default defineShopwareComponentResolver({
|
|
|
29
31
|
ProductSeo,
|
|
30
32
|
ProductDescription,
|
|
31
33
|
ProductDefaultVariant,
|
|
34
|
+
ProductOptionGroups,
|
|
32
35
|
ProductRating
|
|
33
36
|
],
|
|
34
37
|
resolve: async ({ entityIds, context, $entity, passthrough }) => {
|
|
@@ -65,8 +68,15 @@ export default defineShopwareComponentResolver({
|
|
|
65
68
|
slug: entitySlug(rawProduct)
|
|
66
69
|
},
|
|
67
70
|
defaultVariant: {
|
|
68
|
-
id: rawVariant.id
|
|
71
|
+
id: rawVariant.id,
|
|
72
|
+
sku: rawVariant.productNumber ?? void 0,
|
|
73
|
+
// Typed locally because the resolver hands `rawVariant` back as `any`.
|
|
74
|
+
options: rawVariant.options?.map((option) => swTranslated(option, "name") ?? "").filter(Boolean),
|
|
75
|
+
status: rawVariant.available ? "inStock" : "outOfStock"
|
|
69
76
|
},
|
|
77
|
+
// The configurator hangs off the parent, never the variant the rest of this
|
|
78
|
+
// projection reads from.
|
|
79
|
+
optionGroups: mapProductOptionGroups(rawProduct),
|
|
70
80
|
info: {
|
|
71
81
|
cover: mappedCover,
|
|
72
82
|
shortDescription: swTranslated(rawProduct, "description") || swTranslated(rawVariant, "description"),
|
|
@@ -120,6 +130,11 @@ export default defineShopwareComponentResolver({
|
|
|
120
130
|
components: {
|
|
121
131
|
prices: {
|
|
122
132
|
ttl: "15 minutes"
|
|
133
|
+
},
|
|
134
|
+
// Half of it is stock-derived, so it decays like prices rather than living for
|
|
135
|
+
// the resolver's full day. `optionGroups` needs no override: nothing in it is.
|
|
136
|
+
defaultVariant: {
|
|
137
|
+
ttl: "15 minutes"
|
|
123
138
|
}
|
|
124
139
|
}
|
|
125
140
|
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { ProductReviewsLink } from "@laioutr-core/canonical-types/ecommerce";
|
|
2
2
|
import { currentProductIdsToken } from "../../const/passthroughTokens.js";
|
|
3
3
|
import { defineShopwareLink } from "../../middleware/defineShopware.js";
|
|
4
|
-
|
|
4
|
+
const REVIEW_SORTINGS = {
|
|
5
|
+
newest: { field: "createdAt", order: "DESC" },
|
|
6
|
+
oldest: { field: "createdAt", order: "ASC" },
|
|
7
|
+
"rating-high": { field: "points", order: "DESC" },
|
|
8
|
+
"rating-low": { field: "points", order: "ASC" }
|
|
9
|
+
};
|
|
10
|
+
export default defineShopwareLink(ProductReviewsLink, async ({ entityIds, context, pagination, sorting, filter, passthrough }) => {
|
|
5
11
|
const { storefrontClient } = context;
|
|
12
|
+
const sort = sorting ? REVIEW_SORTINGS[sorting] : void 0;
|
|
13
|
+
const points = Number(filter?.points);
|
|
14
|
+
const criteriaFilter = Number.isFinite(points) ? [{ type: "equals", field: "points", value: points }] : void 0;
|
|
6
15
|
const productToReviews = {};
|
|
7
16
|
await Promise.all(
|
|
8
17
|
entityIds.map(async (entityId) => {
|
|
@@ -11,6 +20,8 @@ export default defineShopwareLink(ProductReviewsLink, async ({ entityIds, contex
|
|
|
11
20
|
body: {
|
|
12
21
|
page: pagination.page,
|
|
13
22
|
limit: pagination.limit,
|
|
23
|
+
...sort ? { sort: [sort] } : {},
|
|
24
|
+
...criteriaFilter ? { filter: criteriaFilter } : {},
|
|
14
25
|
includes: {
|
|
15
26
|
product_review: ["id"]
|
|
16
27
|
}
|
|
@@ -15,6 +15,7 @@ import { resolveProductVariantFields } from "../../orchestr-helper/requestedFiel
|
|
|
15
15
|
import { toRequestCriteria } from "../../shopware-helper/criteria.js";
|
|
16
16
|
import { mapMedia } from "../../shopware-helper/mediaMapper.js";
|
|
17
17
|
import { swTranslated } from "../../shopware-helper/swTranslated.js";
|
|
18
|
+
import { guessWellKnownName } from "../../shopware-helper/wellKnownOptionName.js";
|
|
18
19
|
export default defineShopwareComponentResolver({
|
|
19
20
|
entityType: "ProductVariant",
|
|
20
21
|
label: "Shopware Product Variant Connector",
|
|
@@ -119,10 +120,14 @@ export default defineShopwareComponentResolver({
|
|
|
119
120
|
required: true
|
|
120
121
|
}),
|
|
121
122
|
options: () => ({
|
|
122
|
-
selected: entity.options?.map((option) =>
|
|
123
|
-
name
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
selected: entity.options?.map((option) => {
|
|
124
|
+
const name = swTranslated(option.group, "name") ?? swTranslated(option, "name") ?? "Unknown Property";
|
|
125
|
+
return {
|
|
126
|
+
name,
|
|
127
|
+
wellKnownName: guessWellKnownName(name),
|
|
128
|
+
value: swTranslated(option, "name") ?? swTranslated(option, "option") ?? "Unknown Value"
|
|
129
|
+
};
|
|
130
|
+
}) ?? []
|
|
126
131
|
})
|
|
127
132
|
})
|
|
128
133
|
)
|
|
@@ -49,7 +49,16 @@ export const resolveProductFields = async (resolveCriteria) => {
|
|
|
49
49
|
return resolveCriteria("product", {
|
|
50
50
|
associations: {
|
|
51
51
|
cover: { associations: { media: {} } },
|
|
52
|
-
media: { associations: { media: {} } }
|
|
52
|
+
media: { associations: { media: {} } },
|
|
53
|
+
// Only the parent carries the configurator, which is what defines the option
|
|
54
|
+
// axes; `properties` on the same row are filterable facets and never do.
|
|
55
|
+
// `media` needs its own association: without it the option's swatch image is
|
|
56
|
+
// never returned, whatever the group's displayType claims.
|
|
57
|
+
configuratorSettings: { associations: { option: { associations: { group: {}, media: {} } } } },
|
|
58
|
+
// Only the variant projection's `includes` are merged below, never its
|
|
59
|
+
// associations, so the selected options need associating here too or the
|
|
60
|
+
// default variant reports none.
|
|
61
|
+
options: { associations: { group: {} } }
|
|
53
62
|
},
|
|
54
63
|
includes: mergeIncludes(
|
|
55
64
|
{
|
|
@@ -74,10 +83,16 @@ export const resolveProductFields = async (resolveCriteria) => {
|
|
|
74
83
|
"calculatedPrice",
|
|
75
84
|
"calculatedPrices",
|
|
76
85
|
"ratingAverage",
|
|
77
|
-
"productReviews"
|
|
86
|
+
"productReviews",
|
|
87
|
+
"configuratorSettings"
|
|
78
88
|
],
|
|
79
89
|
product_media: ["id", "mediaId", "media"],
|
|
80
|
-
media: MediaIncludes
|
|
90
|
+
media: MediaIncludes,
|
|
91
|
+
product_configurator_setting: ["id", "optionId", "option", "position"],
|
|
92
|
+
// Merged with the variant projection's narrower list, which carries neither
|
|
93
|
+
// the swatch fields nor the ordering the configurator is authored in.
|
|
94
|
+
property_group_option: ["colorHexCode", "media", "position"],
|
|
95
|
+
property_group: ["displayType", "position"]
|
|
81
96
|
},
|
|
82
97
|
variantFields.includes
|
|
83
98
|
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ShopwareProduct } from '../types/shopware.js';
|
|
2
|
+
import type { Swatch } from '@laioutr-core/core-types/common';
|
|
3
|
+
/**
|
|
4
|
+
* The option axes a product offers, read from its configurator.
|
|
5
|
+
*
|
|
6
|
+
* The configurator is what defines a variant; `properties` on the same product are
|
|
7
|
+
* filterable facets and never do. Only the parent carries it, so this must be given
|
|
8
|
+
* the parent row rather than the variant the rest of the projection reads from.
|
|
9
|
+
*
|
|
10
|
+
* Per-value stock and a per-value variant id are deliberately absent: both would
|
|
11
|
+
* mean loading every child variant, which is the cost this component exists to
|
|
12
|
+
* avoid. A consumer that needs them falls back to the variants link.
|
|
13
|
+
*/
|
|
14
|
+
export declare const mapProductOptionGroups: (product: Pick<ShopwareProduct, "configuratorSettings">) => {
|
|
15
|
+
groups: {
|
|
16
|
+
name: string;
|
|
17
|
+
wellKnownName: import("@laioutr-core/canonical-types/entity/product-variant").WellKnownOptionName | undefined;
|
|
18
|
+
values: {
|
|
19
|
+
value: string;
|
|
20
|
+
swatch: Swatch | undefined;
|
|
21
|
+
}[];
|
|
22
|
+
}[];
|
|
23
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { mapMedia } from "./mediaMapper.js";
|
|
2
|
+
import { swTranslated } from "./swTranslated.js";
|
|
3
|
+
import { guessWellKnownName } from "./wellKnownOptionName.js";
|
|
4
|
+
const byPosition = (a, b) => (a.position ?? 0) - (b.position ?? 0);
|
|
5
|
+
const bySettingThenOption = (a, b) => (a.position ?? 0) - (b.position ?? 0) || (a.option.position ?? 0) - (b.option.position ?? 0);
|
|
6
|
+
const mapSwatch = (option) => {
|
|
7
|
+
const hex = swTranslated(option, "colorHexCode") ?? option.colorHexCode;
|
|
8
|
+
if (hex) return ["color", hex];
|
|
9
|
+
const media = option.media ? mapMedia(option.media) : void 0;
|
|
10
|
+
return media?.type === "image" ? ["image", media] : void 0;
|
|
11
|
+
};
|
|
12
|
+
export const mapProductOptionGroups = (product) => {
|
|
13
|
+
const settings = (product.configuratorSettings ?? []).filter((setting) => !!setting.option);
|
|
14
|
+
const groups = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const setting of settings) {
|
|
16
|
+
const group = setting.option.group;
|
|
17
|
+
const key = group?.id ?? swTranslated(group, "name") ?? "";
|
|
18
|
+
const existing = groups.get(key);
|
|
19
|
+
if (existing) {
|
|
20
|
+
existing.settings.push(setting);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
groups.set(key, { name: swTranslated(group, "name") ?? "", position: group?.position ?? 0, settings: [setting] });
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
groups: [...groups.values()].sort(byPosition).map((group) => ({
|
|
27
|
+
name: group.name,
|
|
28
|
+
wellKnownName: guessWellKnownName(group.name),
|
|
29
|
+
// The merchant's configurator order, which is what keeps a size run out of
|
|
30
|
+
// alphabetical order.
|
|
31
|
+
values: [...group.settings].sort(bySettingThenOption).map((setting) => ({
|
|
32
|
+
value: swTranslated(setting.option, "name") ?? "",
|
|
33
|
+
swatch: mapSwatch(setting.option)
|
|
34
|
+
}))
|
|
35
|
+
}))
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
const OPTION_NAME_ALIASES = {
|
|
2
|
+
color: [
|
|
3
|
+
"color",
|
|
4
|
+
// en (US), es
|
|
5
|
+
"colour",
|
|
6
|
+
// en (GB)
|
|
7
|
+
"farbe",
|
|
8
|
+
// de
|
|
9
|
+
"farbton",
|
|
10
|
+
// de — shade rather than colour, and a real axis name in the wild
|
|
11
|
+
"kleur",
|
|
12
|
+
// nl
|
|
13
|
+
"couleur",
|
|
14
|
+
// fr
|
|
15
|
+
"colore",
|
|
16
|
+
// it
|
|
17
|
+
"cor",
|
|
18
|
+
// pt
|
|
19
|
+
"kolor",
|
|
20
|
+
// pl
|
|
21
|
+
"barva",
|
|
22
|
+
// cs, sl
|
|
23
|
+
"farba",
|
|
24
|
+
// sk
|
|
25
|
+
"boja",
|
|
26
|
+
// hr
|
|
27
|
+
"sz\xEDn",
|
|
28
|
+
// hu
|
|
29
|
+
"culoare",
|
|
30
|
+
// ro
|
|
31
|
+
"\u0446\u0432\u044F\u0442",
|
|
32
|
+
// bg
|
|
33
|
+
"\u03C7\u03C1\u03CE\u03BC\u03B1",
|
|
34
|
+
// el
|
|
35
|
+
"f\xE4rg",
|
|
36
|
+
// sv
|
|
37
|
+
"farve",
|
|
38
|
+
// da
|
|
39
|
+
"farge",
|
|
40
|
+
// no
|
|
41
|
+
"v\xE4ri",
|
|
42
|
+
// fi
|
|
43
|
+
"litur",
|
|
44
|
+
// is
|
|
45
|
+
"v\xE4rv",
|
|
46
|
+
// et
|
|
47
|
+
"kr\u0101sa",
|
|
48
|
+
// lv
|
|
49
|
+
"spalva",
|
|
50
|
+
// lt
|
|
51
|
+
"renk",
|
|
52
|
+
// tr
|
|
53
|
+
"\u8272",
|
|
54
|
+
// ja
|
|
55
|
+
"\u30AB\u30E9\u30FC",
|
|
56
|
+
// ja
|
|
57
|
+
"\uC0C9\uC0C1",
|
|
58
|
+
// ko
|
|
59
|
+
"\uCEEC\uB7EC",
|
|
60
|
+
// ko
|
|
61
|
+
"\u989C\u8272",
|
|
62
|
+
// zh-Hans
|
|
63
|
+
"\u984F\u8272"
|
|
64
|
+
// zh-Hant
|
|
65
|
+
],
|
|
66
|
+
size: [
|
|
67
|
+
"size",
|
|
68
|
+
// en
|
|
69
|
+
"gr\xF6\xDFe",
|
|
70
|
+
// de
|
|
71
|
+
"groesse",
|
|
72
|
+
// de, ASCII transliteration — "oe" survives diacritic folding
|
|
73
|
+
"maat",
|
|
74
|
+
// nl
|
|
75
|
+
"grootte",
|
|
76
|
+
// nl
|
|
77
|
+
"taille",
|
|
78
|
+
// fr
|
|
79
|
+
"pointure",
|
|
80
|
+
// fr, footwear
|
|
81
|
+
"taglia",
|
|
82
|
+
// it
|
|
83
|
+
"misura",
|
|
84
|
+
// it
|
|
85
|
+
"talla",
|
|
86
|
+
// es
|
|
87
|
+
"tama\xF1o",
|
|
88
|
+
// es
|
|
89
|
+
"tamanho",
|
|
90
|
+
// pt
|
|
91
|
+
"rozmiar",
|
|
92
|
+
// pl
|
|
93
|
+
"velikost",
|
|
94
|
+
// cs, sl
|
|
95
|
+
"ve\u013Ekos\u0165",
|
|
96
|
+
// sk
|
|
97
|
+
"veli\u010Dina",
|
|
98
|
+
// hr
|
|
99
|
+
"m\xE9ret",
|
|
100
|
+
// hu
|
|
101
|
+
"m\u0103rime",
|
|
102
|
+
// ro
|
|
103
|
+
"\u0440\u0430\u0437\u043C\u0435\u0440",
|
|
104
|
+
// bg
|
|
105
|
+
"\u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2",
|
|
106
|
+
// el
|
|
107
|
+
"storlek",
|
|
108
|
+
// sv
|
|
109
|
+
"st\xF8rrelse",
|
|
110
|
+
// da, no
|
|
111
|
+
"koko",
|
|
112
|
+
// fi
|
|
113
|
+
"st\xE6r\xF0",
|
|
114
|
+
// is
|
|
115
|
+
"suurus",
|
|
116
|
+
// et
|
|
117
|
+
"izm\u0113rs",
|
|
118
|
+
// lv
|
|
119
|
+
"dydis",
|
|
120
|
+
// lt
|
|
121
|
+
"beden",
|
|
122
|
+
// tr
|
|
123
|
+
"\u30B5\u30A4\u30BA",
|
|
124
|
+
// ja
|
|
125
|
+
"\uC0AC\uC774\uC988",
|
|
126
|
+
// ko
|
|
127
|
+
"\uD06C\uAE30",
|
|
128
|
+
// ko
|
|
129
|
+
"\u5C3A\u5BF8",
|
|
130
|
+
// zh
|
|
131
|
+
"\u5C3A\u7801",
|
|
132
|
+
// zh-Hans
|
|
133
|
+
"\u5C3A\u78BC"
|
|
134
|
+
// zh-Hant
|
|
135
|
+
],
|
|
136
|
+
material: [
|
|
137
|
+
"material",
|
|
138
|
+
// en, de, es, pt, ro, sv, sl, and cs/sk `materiál` once folded
|
|
139
|
+
"materiaal",
|
|
140
|
+
// nl
|
|
141
|
+
"mati\xE8re",
|
|
142
|
+
// fr
|
|
143
|
+
"mat\xE9riau",
|
|
144
|
+
// fr
|
|
145
|
+
"materiale",
|
|
146
|
+
// it, da, no
|
|
147
|
+
"materia\u0142",
|
|
148
|
+
// pl
|
|
149
|
+
"materijal",
|
|
150
|
+
// hr
|
|
151
|
+
"anyag",
|
|
152
|
+
// hu
|
|
153
|
+
"\u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B",
|
|
154
|
+
// bg
|
|
155
|
+
"\u03C5\u03BB\u03B9\u03BA\u03CC",
|
|
156
|
+
// el
|
|
157
|
+
"materiaali",
|
|
158
|
+
// fi
|
|
159
|
+
"efni",
|
|
160
|
+
// is
|
|
161
|
+
"materjal",
|
|
162
|
+
// et
|
|
163
|
+
"materi\u0101ls",
|
|
164
|
+
// lv
|
|
165
|
+
"med\u017Eiaga",
|
|
166
|
+
// lt
|
|
167
|
+
"malzeme",
|
|
168
|
+
// tr
|
|
169
|
+
"\u7D20\u6750",
|
|
170
|
+
// ja
|
|
171
|
+
"\u6750\u8CEA",
|
|
172
|
+
// ja, zh-Hant
|
|
173
|
+
"\uC18C\uC7AC",
|
|
174
|
+
// ko
|
|
175
|
+
"\uC7AC\uC9C8",
|
|
176
|
+
// ko
|
|
177
|
+
"\u6750\u6599",
|
|
178
|
+
// zh
|
|
179
|
+
"\u6750\u8D28"
|
|
180
|
+
// zh-Hans
|
|
181
|
+
],
|
|
182
|
+
style: [
|
|
183
|
+
"style",
|
|
184
|
+
// en, fr
|
|
185
|
+
"stil",
|
|
186
|
+
// de, sv, da, no, hr, tr
|
|
187
|
+
"stijl",
|
|
188
|
+
// nl
|
|
189
|
+
"stile",
|
|
190
|
+
// it
|
|
191
|
+
"estilo",
|
|
192
|
+
// es, pt
|
|
193
|
+
"styl",
|
|
194
|
+
// pl, cs, and sk `štýl` once folded
|
|
195
|
+
"slog",
|
|
196
|
+
// sl
|
|
197
|
+
"st\xEDlus",
|
|
198
|
+
// hu
|
|
199
|
+
"\u0441\u0442\u0438\u043B",
|
|
200
|
+
// bg
|
|
201
|
+
"\u03C3\u03C4\u03C5\u03BB",
|
|
202
|
+
// el
|
|
203
|
+
"tyyli",
|
|
204
|
+
// fi
|
|
205
|
+
"st\xEDll",
|
|
206
|
+
// is
|
|
207
|
+
"stiil",
|
|
208
|
+
// et
|
|
209
|
+
"stils",
|
|
210
|
+
// lv
|
|
211
|
+
"stilius",
|
|
212
|
+
// lt
|
|
213
|
+
"\u30B9\u30BF\u30A4\u30EB",
|
|
214
|
+
// ja
|
|
215
|
+
"\uC2A4\uD0C0\uC77C",
|
|
216
|
+
// ko
|
|
217
|
+
"\u6B3E\u5F0F"
|
|
218
|
+
// zh
|
|
219
|
+
],
|
|
220
|
+
type: [
|
|
221
|
+
"type",
|
|
222
|
+
// en, nl, fr, da, no
|
|
223
|
+
"typ",
|
|
224
|
+
// de, pl, cs, sk, sv
|
|
225
|
+
"tipo",
|
|
226
|
+
// it, es, pt
|
|
227
|
+
"tip",
|
|
228
|
+
// sl, hr, tr
|
|
229
|
+
"vrsta",
|
|
230
|
+
// sl, hr
|
|
231
|
+
"rodzaj",
|
|
232
|
+
// pl
|
|
233
|
+
"t\xEDpus",
|
|
234
|
+
// hu
|
|
235
|
+
"\u0442\u0438\u043F",
|
|
236
|
+
// bg
|
|
237
|
+
"\u03C4\u03CD\u03C0\u03BF\u03C2",
|
|
238
|
+
// el
|
|
239
|
+
"tyyppi",
|
|
240
|
+
// fi
|
|
241
|
+
"tegund",
|
|
242
|
+
// is
|
|
243
|
+
"t\xFC\xFCp",
|
|
244
|
+
// et
|
|
245
|
+
"veids",
|
|
246
|
+
// lv
|
|
247
|
+
"tipas",
|
|
248
|
+
// lt
|
|
249
|
+
"\u30BF\u30A4\u30D7",
|
|
250
|
+
// ja
|
|
251
|
+
"\u7A2E\u985E",
|
|
252
|
+
// ja
|
|
253
|
+
"\uC720\uD615",
|
|
254
|
+
// ko
|
|
255
|
+
"\uD0C0\uC785",
|
|
256
|
+
// ko
|
|
257
|
+
"\u7C7B\u578B",
|
|
258
|
+
// zh-Hans
|
|
259
|
+
"\u985E\u578B"
|
|
260
|
+
// zh-Hant
|
|
261
|
+
]
|
|
262
|
+
};
|
|
263
|
+
const normalizeOptionName = (name) => name.trim().toLowerCase().replace(/ß/g, "ss").normalize("NFD").replace(/\p{M}/gu, "");
|
|
264
|
+
const OPTION_NAME_LOOKUP = new Map(
|
|
265
|
+
Object.entries(OPTION_NAME_ALIASES).flatMap(
|
|
266
|
+
([wellKnownName, aliases]) => aliases.map((alias) => [normalizeOptionName(alias), wellKnownName])
|
|
267
|
+
)
|
|
268
|
+
);
|
|
269
|
+
export const guessWellKnownName = (name) => {
|
|
270
|
+
const normalized = normalizeOptionName(name);
|
|
271
|
+
const exact = OPTION_NAME_LOOKUP.get(normalized);
|
|
272
|
+
if (exact) return exact;
|
|
273
|
+
for (const token of normalized.split(/[^\p{L}\p{N}]+/u)) {
|
|
274
|
+
const match = OPTION_NAME_LOOKUP.get(token);
|
|
275
|
+
if (match) return match;
|
|
276
|
+
}
|
|
277
|
+
return void 0;
|
|
278
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laioutr/app-shopware",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Laioutr integration with Shopware 6",
|
|
5
5
|
"repository": "github:laioutr/app-shopware",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@changesets/cli": "^2.31.0",
|
|
42
42
|
"@laioutr-app/ui": "^2.10.6",
|
|
43
|
-
"@laioutr-core/canonical-types": "^0.
|
|
43
|
+
"@laioutr-core/canonical-types": "^0.31.0",
|
|
44
44
|
"@laioutr-core/core-types": "^0.40.3",
|
|
45
45
|
"@laioutr-core/devtools": "^0.40.3",
|
|
46
46
|
"@laioutr-core/frontend-core": "^0.40.3",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"vue-tsc": "2.2.10"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
-
"@laioutr-core/canonical-types": ">=0.
|
|
72
|
+
"@laioutr-core/canonical-types": ">=0.31.0",
|
|
73
73
|
"@laioutr-core/core-types": ">=0.40.3",
|
|
74
74
|
"@laioutr-core/frontend-core": ">=0.40.3",
|
|
75
75
|
"@laioutr-core/kit": ">=0.40.3",
|