@ikas/component-cli 1.4.0-beta.20 → 1.4.0-beta.201
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/build-tools.d.ts +37 -0
- package/dist/build-tools.d.ts.map +1 -0
- package/dist/build-tools.js +36 -0
- package/dist/build-tools.js.map +1 -0
- package/dist/commands/add-sections-to-page.d.ts +3 -0
- package/dist/commands/add-sections-to-page.d.ts.map +1 -0
- package/dist/commands/add-sections-to-page.js +39 -0
- package/dist/commands/add-sections-to-page.js.map +1 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +11 -2
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +5 -165
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/config.d.ts +35 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +1082 -147
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/create-design-tokens.d.ts +24 -0
- package/dist/commands/create-design-tokens.d.ts.map +1 -0
- package/dist/commands/create-design-tokens.js +327 -0
- package/dist/commands/create-design-tokens.js.map +1 -0
- package/dist/commands/create-global-variable.d.ts +3 -0
- package/dist/commands/create-global-variable.d.ts.map +1 -0
- package/dist/commands/create-global-variable.js +73 -0
- package/dist/commands/create-global-variable.js.map +1 -0
- package/dist/commands/create-page.d.ts +3 -0
- package/dist/commands/create-page.d.ts.map +1 -0
- package/dist/commands/create-page.js +31 -0
- package/dist/commands/create-page.js.map +1 -0
- package/dist/commands/delete-page.d.ts +3 -0
- package/dist/commands/delete-page.d.ts.map +1 -0
- package/dist/commands/delete-page.js +28 -0
- package/dist/commands/delete-page.js.map +1 -0
- package/dist/commands/delete-theme-globals.d.ts +4 -0
- package/dist/commands/delete-theme-globals.d.ts.map +1 -0
- package/dist/commands/delete-theme-globals.js +48 -0
- package/dist/commands/delete-theme-globals.js.map +1 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +170 -31
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/enable-builtin-pages.d.ts +3 -0
- package/dist/commands/enable-builtin-pages.d.ts.map +1 -0
- package/dist/commands/enable-builtin-pages.js +27 -0
- package/dist/commands/enable-builtin-pages.js.map +1 -0
- package/dist/commands/get-component-props.d.ts +3 -0
- package/dist/commands/get-component-props.d.ts.map +1 -0
- package/dist/commands/get-component-props.js +32 -0
- package/dist/commands/get-component-props.js.map +1 -0
- package/dist/commands/get-page-by-type.d.ts +3 -0
- package/dist/commands/get-page-by-type.d.ts.map +1 -0
- package/dist/commands/get-page-by-type.js +25 -0
- package/dist/commands/get-page-by-type.js.map +1 -0
- package/dist/commands/get-section-values.d.ts +3 -0
- package/dist/commands/get-section-values.d.ts.map +1 -0
- package/dist/commands/get-section-values.js +39 -0
- package/dist/commands/get-section-values.js.map +1 -0
- package/dist/commands/list-builtin-pages.d.ts +3 -0
- package/dist/commands/list-builtin-pages.d.ts.map +1 -0
- package/dist/commands/list-builtin-pages.js +28 -0
- package/dist/commands/list-builtin-pages.js.map +1 -0
- package/dist/commands/list-entities.d.ts +3 -0
- package/dist/commands/list-entities.d.ts.map +1 -0
- package/dist/commands/list-entities.js +32 -0
- package/dist/commands/list-entities.js.map +1 -0
- package/dist/commands/list-page-sections.d.ts.map +1 -1
- package/dist/commands/list-page-sections.js +8 -2
- package/dist/commands/list-page-sections.js.map +1 -1
- package/dist/commands/list-theme-globals.d.ts +3 -0
- package/dist/commands/list-theme-globals.d.ts.map +1 -0
- package/dist/commands/list-theme-globals.js +22 -0
- package/dist/commands/list-theme-globals.js.map +1 -0
- package/dist/commands/move-page-section.d.ts +3 -0
- package/dist/commands/move-page-section.d.ts.map +1 -0
- package/dist/commands/move-page-section.js +62 -0
- package/dist/commands/move-page-section.js.map +1 -0
- package/dist/commands/publish-theme.d.ts +3 -0
- package/dist/commands/publish-theme.d.ts.map +1 -0
- package/dist/commands/publish-theme.js +29 -0
- package/dist/commands/publish-theme.js.map +1 -0
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +54 -3
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/remove-page-section.d.ts +3 -0
- package/dist/commands/remove-page-section.d.ts.map +1 -0
- package/dist/commands/remove-page-section.js +40 -0
- package/dist/commands/remove-page-section.js.map +1 -0
- package/dist/commands/search-products.d.ts +3 -0
- package/dist/commands/search-products.d.ts.map +1 -0
- package/dist/commands/search-products.js +40 -0
- package/dist/commands/search-products.js.map +1 -0
- package/dist/commands/update-builtin-page-prop.d.ts +3 -0
- package/dist/commands/update-builtin-page-prop.d.ts.map +1 -0
- package/dist/commands/update-builtin-page-prop.js +49 -0
- package/dist/commands/update-builtin-page-prop.js.map +1 -0
- package/dist/commands/update-global-variable.d.ts +3 -0
- package/dist/commands/update-global-variable.d.ts.map +1 -0
- package/dist/commands/update-global-variable.js +70 -0
- package/dist/commands/update-global-variable.js.map +1 -0
- package/dist/commands/update-page-sections.d.ts +3 -0
- package/dist/commands/update-page-sections.d.ts.map +1 -0
- package/dist/commands/update-page-sections.js +39 -0
- package/dist/commands/update-page-sections.js.map +1 -0
- package/dist/commands/update-section-prop.d.ts.map +1 -1
- package/dist/commands/update-section-prop.js +25 -8
- package/dist/commands/update-section-prop.js.map +1 -1
- package/dist/commands/upload-image.d.ts.map +1 -1
- package/dist/commands/upload-image.js +5 -46
- package/dist/commands/upload-image.js.map +1 -1
- package/dist/commands/upload-images.d.ts +3 -0
- package/dist/commands/upload-images.d.ts.map +1 -0
- package/dist/commands/upload-images.js +48 -0
- package/dist/commands/upload-images.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/compile.d.ts +17 -2
- package/dist/utils/compile.d.ts.map +1 -1
- package/dist/utils/compile.js +750 -117
- package/dist/utils/compile.js.map +1 -1
- package/dist/utils/component-helpers.d.ts +145 -2
- package/dist/utils/component-helpers.d.ts.map +1 -1
- package/dist/utils/component-helpers.js +397 -29
- package/dist/utils/component-helpers.js.map +1 -1
- package/dist/utils/css-import-resolver.d.ts +4 -1
- package/dist/utils/css-import-resolver.d.ts.map +1 -1
- package/dist/utils/css-import-resolver.js +9 -1
- package/dist/utils/css-import-resolver.js.map +1 -1
- package/dist/utils/editor-action-client.d.ts +4 -3
- package/dist/utils/editor-action-client.d.ts.map +1 -1
- package/dist/utils/editor-action-client.js +55 -19
- package/dist/utils/editor-action-client.js.map +1 -1
- package/dist/utils/esm-transform.d.ts +30 -0
- package/dist/utils/esm-transform.d.ts.map +1 -1
- package/dist/utils/esm-transform.js +169 -2
- package/dist/utils/esm-transform.js.map +1 -1
- package/dist/utils/find-component-for-file.d.ts +12 -0
- package/dist/utils/find-component-for-file.d.ts.map +1 -0
- package/dist/utils/find-component-for-file.js +24 -0
- package/dist/utils/find-component-for-file.js.map +1 -0
- package/dist/utils/forbid-deep-imports.d.ts +3 -0
- package/dist/utils/forbid-deep-imports.d.ts.map +1 -0
- package/dist/utils/forbid-deep-imports.js +54 -0
- package/dist/utils/forbid-deep-imports.js.map +1 -0
- package/dist/utils/forbid-external-packages.d.ts +26 -0
- package/dist/utils/forbid-external-packages.d.ts.map +1 -0
- package/dist/utils/forbid-external-packages.js +99 -0
- package/dist/utils/forbid-external-packages.js.map +1 -0
- package/dist/utils/load-image.d.ts +16 -0
- package/dist/utils/load-image.d.ts.map +1 -0
- package/dist/utils/load-image.js +50 -0
- package/dist/utils/load-image.js.map +1 -0
- package/dist/utils/vendor-storefront.d.ts +13 -0
- package/dist/utils/vendor-storefront.d.ts.map +1 -0
- package/dist/utils/vendor-storefront.js +91 -0
- package/dist/utils/vendor-storefront.js.map +1 -0
- package/dist/utils/websocket-server.d.ts +88 -5
- package/dist/utils/websocket-server.d.ts.map +1 -1
- package/dist/utils/websocket-server.js +241 -44
- package/dist/utils/websocket-server.js.map +1 -1
- package/package.json +17 -2
- package/templates/add/section.css +11 -0
- package/dist/commands/create.d.ts +0 -4
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -228
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/proxy.d.ts +0 -39
- package/dist/commands/proxy.d.ts.map +0 -1
- package/dist/commands/proxy.js +0 -210
- package/dist/commands/proxy.js.map +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentDefinition } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Get the component definition that contains a file path.
|
|
4
|
+
*
|
|
5
|
+
* Accepts relative or absolute paths: chokidar emits paths relative to cwd for the dev
|
|
6
|
+
* server's relative watch patterns, so the incoming path is resolved here (normalize alone
|
|
7
|
+
* would leave it relative and it could never match the absolute entry/styles/dir paths below).
|
|
8
|
+
*/
|
|
9
|
+
export declare function findComponentForFile(config: {
|
|
10
|
+
components: ComponentDefinition[];
|
|
11
|
+
}, filePath: string): ComponentDefinition | null;
|
|
12
|
+
//# sourceMappingURL=find-component-for-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-component-for-file.d.ts","sourceRoot":"","sources":["../../src/utils/find-component-for-file.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE;IAAE,UAAU,EAAE,mBAAmB,EAAE,CAAA;CAAE,EAC7C,QAAQ,EAAE,MAAM,GACf,mBAAmB,GAAG,IAAI,CAmB5B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
/**
|
|
3
|
+
* Get the component definition that contains a file path.
|
|
4
|
+
*
|
|
5
|
+
* Accepts relative or absolute paths: chokidar emits paths relative to cwd for the dev
|
|
6
|
+
* server's relative watch patterns, so the incoming path is resolved here (normalize alone
|
|
7
|
+
* would leave it relative and it could never match the absolute entry/styles/dir paths below).
|
|
8
|
+
*/
|
|
9
|
+
export function findComponentForFile(config, filePath) {
|
|
10
|
+
const normalizedPath = path.resolve(filePath);
|
|
11
|
+
for (const component of config.components) {
|
|
12
|
+
const entryPath = path.resolve(process.cwd(), component.entry);
|
|
13
|
+
const stylesPath = path.resolve(process.cwd(), component.styles);
|
|
14
|
+
const componentDir = path.dirname(entryPath);
|
|
15
|
+
// Check if the file is the entry, styles, or in the component directory
|
|
16
|
+
if (normalizedPath === entryPath ||
|
|
17
|
+
normalizedPath === stylesPath ||
|
|
18
|
+
normalizedPath.startsWith(componentDir + path.sep)) {
|
|
19
|
+
return component;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=find-component-for-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-component-for-file.js","sourceRoot":"","sources":["../../src/utils/find-component-for-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAA6C,EAC7C,QAAgB;IAEhB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE9C,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QACjE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE7C,wEAAwE;QACxE,IACE,cAAc,KAAK,SAAS;YAC5B,cAAc,KAAK,UAAU;YAC7B,cAAc,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAClD,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forbid-deep-imports.d.ts","sourceRoot":"","sources":["../../src/utils/forbid-deep-imports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AA2BtC,wBAAgB,iCAAiC,IAAI,MAAM,CA6B1D"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fail the build on deep imports into the storefront packages.
|
|
3
|
+
*
|
|
4
|
+
* `@ikas/bp-storefront` (and its `-models` / `-config` / `-api` siblings) are marked
|
|
5
|
+
* EXTERNAL during compilation, so esbuild does NOT resolve their subpaths — a hand-written
|
|
6
|
+
* deep import like `@ikas/bp-storefront/dist/functions/api/cart` would otherwise sail through
|
|
7
|
+
* the bundle untouched and only break later (the published storefront exposes the package as
|
|
8
|
+
* window globals keyed off the ROOT export names; a `/dist/...` or `/src/...` subpath has no
|
|
9
|
+
* corresponding global, so the component throws at runtime in the canvas/published theme).
|
|
10
|
+
*
|
|
11
|
+
* The public contract is: import ONLY from the bare package root. Anything after the package
|
|
12
|
+
* name is a private path. This plugin turns that contract into a hard compile error with a
|
|
13
|
+
* message pointing at the correct root import, instead of letting the component build "succeed"
|
|
14
|
+
* and fail in the browser. Models often reach for these subpaths when they can't find a public
|
|
15
|
+
* helper (e.g. coupon code) — the error nudges them back to the documented root exports.
|
|
16
|
+
*/
|
|
17
|
+
// Matches `@ikas/bp-storefront` (and its -models / -config / -api siblings) with an OPTIONAL
|
|
18
|
+
// subpath. Group 1 = package root, group 2 = the subpath (including its leading "/"), if any.
|
|
19
|
+
//
|
|
20
|
+
// NOTE: these packages MUST NOT also sit in esbuild's `external: [...]` array. esbuild applies
|
|
21
|
+
// the external array BEFORE running plugin onResolve callbacks, so an external-listed deep
|
|
22
|
+
// import is short-circuited and the plugin never sees it. We therefore externalize the valid
|
|
23
|
+
// ROOT import from inside this plugin instead, which lets the same callback reject subpaths.
|
|
24
|
+
const STOREFRONT_PKG = /^(@ikas\/bp-storefront(?:-(?:models|config|api))?)(\/.*)?$/;
|
|
25
|
+
export function forbidDeepStorefrontImportsPlugin() {
|
|
26
|
+
return {
|
|
27
|
+
name: "ikas-forbid-deep-storefront-imports",
|
|
28
|
+
setup(build) {
|
|
29
|
+
build.onResolve({ filter: STOREFRONT_PKG }, (args) => {
|
|
30
|
+
const [, root, subpath] = args.path.match(STOREFRONT_PKG);
|
|
31
|
+
// Bare root import (or a lone trailing slash) — the allowed form. Externalize it, the
|
|
32
|
+
// same way the old `external: [...]` entry did, so the published storefront's window
|
|
33
|
+
// globals satisfy it.
|
|
34
|
+
if (!subpath || subpath === "/") {
|
|
35
|
+
return { path: root, external: true };
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
errors: [
|
|
39
|
+
{
|
|
40
|
+
text: `Deep import "${args.path}" is not allowed. Import only from the package root ` +
|
|
41
|
+
`"${root}" — e.g. import { saveCouponCode, getCart } from "${root}". ` +
|
|
42
|
+
`Subpaths like "/dist/..." or "/src/..." are private: they bundle fine but have ` +
|
|
43
|
+
`no window global in the published storefront, so the component breaks at runtime. ` +
|
|
44
|
+
`If a helper seems missing from the root, it almost always has a public name there ` +
|
|
45
|
+
`(coupon code, for instance, is getCouponCodeForm / setCouponCodeFormCouponCode / ` +
|
|
46
|
+
`submitCouponCodeForm).`,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=forbid-deep-imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forbid-deep-imports.js","sourceRoot":"","sources":["../../src/utils/forbid-deep-imports.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,6FAA6F;AAC7F,8FAA8F;AAC9F,EAAE;AACF,+FAA+F;AAC/F,2FAA2F;AAC3F,6FAA6F;AAC7F,6FAA6F;AAC7F,MAAM,cAAc,GAAG,4DAA4D,CAAC;AAEpF,MAAM,UAAU,iCAAiC;IAC/C,OAAO;QACL,IAAI,EAAE,qCAAqC;QAC3C,KAAK,CAAC,KAAK;YACT,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBACnD,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAE,CAAC;gBAC3D,sFAAsF;gBACtF,qFAAqF;gBACrF,sBAAsB;gBACtB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;oBAChC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACxC,CAAC;gBACD,OAAO;oBACL,MAAM,EAAE;wBACN;4BACE,IAAI,EACF,gBAAgB,IAAI,CAAC,IAAI,sDAAsD;gCAC/E,IAAI,IAAI,qDAAqD,IAAI,KAAK;gCACtE,iFAAiF;gCACjF,oFAAoF;gCACpF,oFAAoF;gCACpF,mFAAmF;gCACnF,wBAAwB;yBAC3B;qBACF;iBACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
/**
|
|
3
|
+
* Fail the build when a code component imports an npm package that is not on the allowlist.
|
|
4
|
+
*
|
|
5
|
+
* Themes are untrusted source. Only the reference-theme baseline packages plus `three` and
|
|
6
|
+
* `animejs` may be bundled into a component. Anything else (lodash, axios, a random UI kit, ...)
|
|
7
|
+
* becomes a hard compile error instead of a silently-bundled dependency — so installing an extra
|
|
8
|
+
* package and importing it blows the build up immediately with an actionable message.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: esbuild applies the `external: [...]` array BEFORE plugin onResolve, so the externalized
|
|
11
|
+
* runtime packages (preact, preact/hooks, mobx, preact-render-to-string) are short-circuited and
|
|
12
|
+
* never reach this plugin — they are allowed implicitly. Non-external subpaths (e.g.
|
|
13
|
+
* `preact/compat`) DO reach here and resolve to an allowed root.
|
|
14
|
+
*/
|
|
15
|
+
export declare function forbidExternalPackagesPlugin(options?: {
|
|
16
|
+
/**
|
|
17
|
+
* Importers whose bare imports bypass the allowlist entirely.
|
|
18
|
+
*
|
|
19
|
+
* Set only when a package is vendored into the artifact (see `vendorStorefrontPlugin`). The
|
|
20
|
+
* allowlist governs what a component *author* may reach for; once we choose to bundle the
|
|
21
|
+
* storefront SDK, its own dependencies (`lodash`, `uuid`, ...) come along as a consequence of
|
|
22
|
+
* that choice, and rejecting them would just be the build arguing with itself.
|
|
23
|
+
*/
|
|
24
|
+
allowFrom?: (importer: string) => boolean;
|
|
25
|
+
}): Plugin;
|
|
26
|
+
//# sourceMappingURL=forbid-external-packages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forbid-external-packages.d.ts","sourceRoot":"","sources":["../../src/utils/forbid-external-packages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAqDtC;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,CAAC,EAAE;IACrD;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C,GAAG,MAAM,CAoCT"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { builtinModules } from "module";
|
|
3
|
+
/**
|
|
4
|
+
* Allowlist of npm packages a theme's code components are permitted to import.
|
|
5
|
+
*
|
|
6
|
+
* Intentionally STATIC — it is NOT derived from the theme's own package.json. The whole point
|
|
7
|
+
* is to stop themes from pulling in arbitrary third-party packages, so trusting their manifest
|
|
8
|
+
* would defeat the purpose: a theme could just add the dependency there. Instead we pin the set
|
|
9
|
+
* here, mirroring apps/reference-theme/package.json's runtime dependencies plus the two
|
|
10
|
+
* explicitly-permitted libraries.
|
|
11
|
+
*
|
|
12
|
+
* The list holds package ROOTS. Subpaths resolve to their root (e.g. `preact/hooks` → `preact`,
|
|
13
|
+
* `three/examples/jsm/...` → `three`), so every subpath of an allowed package is allowed too.
|
|
14
|
+
* Deep imports into the storefront SDK are separately restricted by
|
|
15
|
+
* `forbidDeepStorefrontImportsPlugin` (which runs first).
|
|
16
|
+
*/
|
|
17
|
+
const ALLOWED_PACKAGE_ROOTS = new Set([
|
|
18
|
+
// Preact runtime (root + any subpath: preact/hooks, preact/compat, preact/jsx-runtime, ...).
|
|
19
|
+
// The bare `preact` / `preact/hooks` specifiers are externalized (short-circuited before this
|
|
20
|
+
// plugin runs), but non-external subpaths like `preact/compat` still resolve through here.
|
|
21
|
+
"preact",
|
|
22
|
+
// MobX reactivity — pulled in by the injected observer runtime. Externalized in both builds,
|
|
23
|
+
// so this is a guard in case the externals list ever changes rather than a reachable import.
|
|
24
|
+
"mobx",
|
|
25
|
+
// ikas storefront SDK (deep-import rules enforced by forbidDeepStorefrontImportsPlugin)
|
|
26
|
+
"@ikas/bp-storefront",
|
|
27
|
+
"@ikas/bp-storefront-models",
|
|
28
|
+
"@ikas/bp-storefront-config",
|
|
29
|
+
"@ikas/bp-storefront-api",
|
|
30
|
+
// Virtual module injected by ikasComponentUtilsPlugin
|
|
31
|
+
"@ikas/component-utils",
|
|
32
|
+
// Explicitly permitted third-party libraries for themes
|
|
33
|
+
"three",
|
|
34
|
+
"animejs",
|
|
35
|
+
]);
|
|
36
|
+
// Node built-ins (with and without the `node:` prefix). Only an already-allowed package would
|
|
37
|
+
// reach for these, and platform:node externalizes them anyway — never flag them.
|
|
38
|
+
const NODE_BUILTINS = new Set([
|
|
39
|
+
...builtinModules,
|
|
40
|
+
...builtinModules.map((m) => `node:${m}`),
|
|
41
|
+
]);
|
|
42
|
+
/** Extract the package root from a bare import specifier (handles `@scope/name`). */
|
|
43
|
+
function packageRootOf(specifier) {
|
|
44
|
+
if (specifier.startsWith("@")) {
|
|
45
|
+
const parts = specifier.split("/");
|
|
46
|
+
return parts.slice(0, 2).join("/");
|
|
47
|
+
}
|
|
48
|
+
return specifier.split("/")[0];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Fail the build when a code component imports an npm package that is not on the allowlist.
|
|
52
|
+
*
|
|
53
|
+
* Themes are untrusted source. Only the reference-theme baseline packages plus `three` and
|
|
54
|
+
* `animejs` may be bundled into a component. Anything else (lodash, axios, a random UI kit, ...)
|
|
55
|
+
* becomes a hard compile error instead of a silently-bundled dependency — so installing an extra
|
|
56
|
+
* package and importing it blows the build up immediately with an actionable message.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: esbuild applies the `external: [...]` array BEFORE plugin onResolve, so the externalized
|
|
59
|
+
* runtime packages (preact, preact/hooks, mobx, preact-render-to-string) are short-circuited and
|
|
60
|
+
* never reach this plugin — they are allowed implicitly. Non-external subpaths (e.g.
|
|
61
|
+
* `preact/compat`) DO reach here and resolve to an allowed root.
|
|
62
|
+
*/
|
|
63
|
+
export function forbidExternalPackagesPlugin(options) {
|
|
64
|
+
return {
|
|
65
|
+
name: "ikas-forbid-external-packages",
|
|
66
|
+
setup(build) {
|
|
67
|
+
// Bare specifiers only — skip relative ("./", "../") and absolute ("/") imports.
|
|
68
|
+
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
69
|
+
const specifier = args.path;
|
|
70
|
+
// Windows absolute paths (C:\..., C:/..., \\server\...) start with neither "." nor "/",
|
|
71
|
+
// so they slip past the bare-specifier filter above (esbuild's Go regex has no lookahead
|
|
72
|
+
// to exclude drive letters). Entry points and the injected JSX shim arrive here as
|
|
73
|
+
// absolute paths on Windows. win32.isAbsolute also accepts POSIX "/" paths, so this one
|
|
74
|
+
// check is safe on every platform — and bare npm specifiers can never contain ":".
|
|
75
|
+
if (path.win32.isAbsolute(specifier))
|
|
76
|
+
return undefined;
|
|
77
|
+
if (NODE_BUILTINS.has(specifier))
|
|
78
|
+
return undefined;
|
|
79
|
+
if (options?.allowFrom?.(args.importer))
|
|
80
|
+
return undefined;
|
|
81
|
+
const root = packageRootOf(specifier);
|
|
82
|
+
if (ALLOWED_PACKAGE_ROOTS.has(root))
|
|
83
|
+
return undefined;
|
|
84
|
+
return {
|
|
85
|
+
errors: [
|
|
86
|
+
{
|
|
87
|
+
text: `Package "${root}" is not allowed in ikas themes. ` +
|
|
88
|
+
`Code components may only import the default theme packages plus "three" and "animejs", ` +
|
|
89
|
+
`so installing and importing "${specifier}" fails the build by design. ` +
|
|
90
|
+
`Remove the dependency (inline the code you need, or switch to an allowed package). ` +
|
|
91
|
+
`Allowed packages: ${Array.from(ALLOWED_PACKAGE_ROOTS).sort().join(", ")}.`,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=forbid-external-packages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forbid-external-packages.js","sourceRoot":"","sources":["../../src/utils/forbid-external-packages.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAS;IAC5C,6FAA6F;IAC7F,8FAA8F;IAC9F,2FAA2F;IAC3F,QAAQ;IACR,6FAA6F;IAC7F,6FAA6F;IAC7F,MAAM;IACN,wFAAwF;IACxF,qBAAqB;IACrB,4BAA4B;IAC5B,4BAA4B;IAC5B,yBAAyB;IACzB,sDAAsD;IACtD,uBAAuB;IACvB,wDAAwD;IACxD,OAAO;IACP,SAAS;CACV,CAAC,CAAC;AAEH,8FAA8F;AAC9F,iFAAiF;AACjF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAS;IACpC,GAAG,cAAc;IACjB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC1C,CAAC,CAAC;AAEH,qFAAqF;AACrF,SAAS,aAAa,CAAC,SAAiB;IACtC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAU5C;IACC,OAAO;QACL,IAAI,EAAE,+BAA+B;QACrC,KAAK,CAAC,KAAK;YACT,iFAAiF;YACjF,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;gBAE5B,wFAAwF;gBACxF,yFAAyF;gBACzF,mFAAmF;gBACnF,wFAAwF;gBACxF,mFAAmF;gBACnF,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;oBAAE,OAAO,SAAS,CAAC;gBAEvD,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC;oBAAE,OAAO,SAAS,CAAC;gBACnD,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAAE,OAAO,SAAS,CAAC;gBAE1D,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,OAAO,SAAS,CAAC;gBAEtD,OAAO;oBACL,MAAM,EAAE;wBACN;4BACE,IAAI,EACF,YAAY,IAAI,mCAAmC;gCACnD,yFAAyF;gCACzF,gCAAgC,SAAS,+BAA+B;gCACxE,qFAAqF;gCACrF,qBAAqB,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;yBAC9E;qBACF;iBACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const VALID_IMAGE_TYPES: string[];
|
|
2
|
+
export interface ImageSource {
|
|
3
|
+
file?: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface LoadedImage {
|
|
7
|
+
base64: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
fileName: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Read an image from a local file path or URL and return its base64 (raw, no
|
|
13
|
+
* data: prefix), mime type, and a file name. Validates type and the 10MB limit.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadImageSource(src: ImageSource): Promise<LoadedImage>;
|
|
16
|
+
//# sourceMappingURL=load-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-image.d.ts","sourceRoot":"","sources":["../../src/utils/load-image.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,iBAAiB,UAA6B,CAAC;AAG5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAsC5E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { basename, extname } from "node:path";
|
|
3
|
+
const MIME_BY_EXT = {
|
|
4
|
+
".png": "image/png",
|
|
5
|
+
".jpg": "image/jpeg",
|
|
6
|
+
".jpeg": "image/jpeg",
|
|
7
|
+
".webp": "image/webp",
|
|
8
|
+
".gif": "image/gif",
|
|
9
|
+
};
|
|
10
|
+
export const VALID_IMAGE_TYPES = Object.values(MIME_BY_EXT);
|
|
11
|
+
const MAX_SIZE_BYTES = 10 * 1024 * 1024; // 10MB, mirrors the editor's IMAGE_UPLOAD_LIMIT_SIZE
|
|
12
|
+
/**
|
|
13
|
+
* Read an image from a local file path or URL and return its base64 (raw, no
|
|
14
|
+
* data: prefix), mime type, and a file name. Validates type and the 10MB limit.
|
|
15
|
+
*/
|
|
16
|
+
export async function loadImageSource(src) {
|
|
17
|
+
if (src.file && src.url) {
|
|
18
|
+
throw new Error("Provide only one of file or url, not both");
|
|
19
|
+
}
|
|
20
|
+
if (src.file) {
|
|
21
|
+
const buffer = await readFile(src.file);
|
|
22
|
+
const ext = extname(src.file).toLowerCase();
|
|
23
|
+
const mimeType = MIME_BY_EXT[ext];
|
|
24
|
+
if (!mimeType) {
|
|
25
|
+
throw new Error(`Unsupported image extension "${ext || "(none)"}" for ${src.file}. Supported: ${Object.keys(MIME_BY_EXT).join(", ")}`);
|
|
26
|
+
}
|
|
27
|
+
if (buffer.byteLength > MAX_SIZE_BYTES) {
|
|
28
|
+
throw new Error(`${src.file} is ${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB; the limit is 10MB`);
|
|
29
|
+
}
|
|
30
|
+
return { base64: buffer.toString("base64"), mimeType, fileName: basename(src.file) };
|
|
31
|
+
}
|
|
32
|
+
if (src.url) {
|
|
33
|
+
const res = await fetch(src.url);
|
|
34
|
+
if (!res.ok) {
|
|
35
|
+
throw new Error(`Failed to fetch ${src.url}: ${res.status} ${res.statusText}`);
|
|
36
|
+
}
|
|
37
|
+
const mimeType = (res.headers.get("content-type") || "").split(";")[0].trim();
|
|
38
|
+
if (!VALID_IMAGE_TYPES.includes(mimeType)) {
|
|
39
|
+
throw new Error(`${src.url} returned content-type "${mimeType || "(none)"}". Supported: ${VALID_IMAGE_TYPES.join(", ")}`);
|
|
40
|
+
}
|
|
41
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
42
|
+
if (buffer.byteLength > MAX_SIZE_BYTES) {
|
|
43
|
+
throw new Error(`${src.url} is ${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB; the limit is 10MB`);
|
|
44
|
+
}
|
|
45
|
+
const urlName = basename(new URL(src.url).pathname) || "image";
|
|
46
|
+
return { base64: buffer.toString("base64"), mimeType, fileName: urlName };
|
|
47
|
+
}
|
|
48
|
+
throw new Error("Provide a file path or url");
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=load-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-image.js","sourceRoot":"","sources":["../../src/utils/load-image.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
export declare function isVendoredDependencyFile(file: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Bundle the storefront SDK into the component artifact.
|
|
5
|
+
*
|
|
6
|
+
* Deep imports stay forbidden for *component* source — the public contract is still "import only
|
|
7
|
+
* from the package root", and a component reaching into `/src/...` is still a bug worth failing
|
|
8
|
+
* on. But the SDK's own modules deep-import each other constantly (97 lazy `import()` calls into
|
|
9
|
+
* `@ikas/bp-storefront-api/src/__api/...` alone), and those are internal business. So the rule is
|
|
10
|
+
* keyed on who is importing, not on what is imported.
|
|
11
|
+
*/
|
|
12
|
+
export declare function vendorStorefrontPlugin(): Plugin;
|
|
13
|
+
//# sourceMappingURL=vendor-storefront.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-storefront.d.ts","sourceRoot":"","sources":["../../src/utils/vendor-storefront.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAqCtC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAK9D;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA+B/C"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
/**
|
|
5
|
+
* Compile the storefront SDK *into* the artifact instead of resolving it against the host.
|
|
6
|
+
*
|
|
7
|
+
* The default path (`forbidDeepStorefrontImportsPlugin`) leaves `@ikas/bp-storefront*` external,
|
|
8
|
+
* so a theme has to hand the component every named export it uses at runtime. That makes the set
|
|
9
|
+
* of names a contract between two independently-released things: publish a component that reaches
|
|
10
|
+
* for a name older themes lack and the page renders an error box for every visitor, with nothing
|
|
11
|
+
* to fall back to.
|
|
12
|
+
*
|
|
13
|
+
* Vendoring removes the contract rather than versioning it. The artifact carries the SDK code it
|
|
14
|
+
* was built against, so what a host must still provide shrinks to the handful of packages that
|
|
15
|
+
* genuinely have to be shared (`preact`, `preact/hooks`, `mobx` — see the externals in compile.ts)
|
|
16
|
+
* and cannot grow when we add a feature.
|
|
17
|
+
*
|
|
18
|
+
* The trade is duplication: a page rendering a vendored component ships this code even though the
|
|
19
|
+
* theme already has its own copy. That is the point — the two copies are free to be different
|
|
20
|
+
* versions.
|
|
21
|
+
*/
|
|
22
|
+
/** `@ikas/bp-storefront` and its siblings, with an optional subpath. */
|
|
23
|
+
const VENDORED_PKG = /^(@ikas\/bp-storefront(?:-(?:models|config|api|api-client))?)(\/.*)?$/;
|
|
24
|
+
/**
|
|
25
|
+
* True for files that belong to a vendored dependency rather than to component source.
|
|
26
|
+
*
|
|
27
|
+
* Two shapes, because the SDK resolves differently depending on where the build runs: an npm
|
|
28
|
+
* install puts it under `node_modules/@ikas/bp-storefront*`, while inside this monorepo npm
|
|
29
|
+
* workspaces symlink it and esbuild reports the real path under `packages/storefront*`.
|
|
30
|
+
*/
|
|
31
|
+
const VENDORED_FILE = /[\\/](?:node_modules[\\/]@ikas[\\/]bp-storefront[^\\/]*|packages[\\/]storefront(?:-(?:api|api-client|config|models))?)[\\/]/;
|
|
32
|
+
export function isVendoredDependencyFile(file) {
|
|
33
|
+
if (!file)
|
|
34
|
+
return false;
|
|
35
|
+
// Anything already inside node_modules is a transitive dependency of a package we chose to
|
|
36
|
+
// vendor, not something a component author wrote — the allowlist has no say over it.
|
|
37
|
+
return file.includes(`${path.sep}node_modules${path.sep}`) || VENDORED_FILE.test(file);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Stand-in for `isomorphic-fetch`, which the SDK imports in three places.
|
|
41
|
+
*
|
|
42
|
+
* That package pulls `node-fetch` in, which references `global` and dies in a browser with
|
|
43
|
+
* "global is not defined" — a failure the monorepo never sees while the SDK is merely *external*,
|
|
44
|
+
* because nothing bundles it there. Vendoring is exactly what makes it reachable, so it has to be
|
|
45
|
+
* aliased away here rather than left to be discovered at runtime.
|
|
46
|
+
*
|
|
47
|
+
* Both build targets already have a native `fetch` (browsers, and Node 18+ for the SSR build), so
|
|
48
|
+
* the shim is a forwarder. It calls through `globalThis` on every invocation instead of capturing
|
|
49
|
+
* the function, which keeps `this` correct (a bare reference throws "Illegal invocation") and lets
|
|
50
|
+
* a host install a polyfill after this module is evaluated.
|
|
51
|
+
*/
|
|
52
|
+
const FETCH_SHIM = path.join(os.tmpdir(), "ikas-vendored-fetch-shim.mjs");
|
|
53
|
+
fs.writeFileSync(FETCH_SHIM, "const f = (...args) => globalThis.fetch(...args);\nexport default f;\nexport { f as fetch };\n");
|
|
54
|
+
/**
|
|
55
|
+
* Bundle the storefront SDK into the component artifact.
|
|
56
|
+
*
|
|
57
|
+
* Deep imports stay forbidden for *component* source — the public contract is still "import only
|
|
58
|
+
* from the package root", and a component reaching into `/src/...` is still a bug worth failing
|
|
59
|
+
* on. But the SDK's own modules deep-import each other constantly (97 lazy `import()` calls into
|
|
60
|
+
* `@ikas/bp-storefront-api/src/__api/...` alone), and those are internal business. So the rule is
|
|
61
|
+
* keyed on who is importing, not on what is imported.
|
|
62
|
+
*/
|
|
63
|
+
export function vendorStorefrontPlugin() {
|
|
64
|
+
return {
|
|
65
|
+
name: "ikas-vendor-storefront",
|
|
66
|
+
setup(build) {
|
|
67
|
+
build.onResolve({ filter: /^isomorphic-fetch$/ }, () => ({ path: FETCH_SHIM }));
|
|
68
|
+
build.onResolve({ filter: VENDORED_PKG }, (args) => {
|
|
69
|
+
const [, root, subpath] = args.path.match(VENDORED_PKG);
|
|
70
|
+
if (subpath && subpath !== "/" && !isVendoredDependencyFile(args.importer)) {
|
|
71
|
+
return {
|
|
72
|
+
errors: [
|
|
73
|
+
{
|
|
74
|
+
text: `Deep import "${args.path}" is not allowed. Import only from the package root ` +
|
|
75
|
+
`"${root}" — e.g. import { saveCouponCode, getCart } from "${root}". ` +
|
|
76
|
+
`Subpaths like "/dist/..." or "/src/..." are private and may be renamed without ` +
|
|
77
|
+
`notice. If a helper seems missing from the root, it almost always has a public ` +
|
|
78
|
+
`name there (coupon code, for instance, is getCouponCodeForm / ` +
|
|
79
|
+
`setCouponCodeFormCouponCode / submitCouponCodeForm).`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Returning nothing hands the specifier back to esbuild's normal resolution, which is
|
|
85
|
+
// what pulls the source into the bundle. The default path returns `external: true` here.
|
|
86
|
+
return undefined;
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=vendor-storefront.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-storefront.js","sourceRoot":"","sources":["../../src/utils/vendor-storefront.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;;;;;;;;;;;;GAiBG;AAEH,wEAAwE;AACxE,MAAM,YAAY,GAAG,uEAAuE,CAAC;AAE7F;;;;;;GAMG;AACH,MAAM,aAAa,GACjB,6HAA6H,CAAC;AAEhI,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,2FAA2F;IAC3F,qFAAqF;IACrF,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,eAAe,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,8BAA8B,CAAC,CAAC;AAC1E,EAAE,CAAC,aAAa,CACd,UAAU,EACV,gGAAgG,CACjG,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,KAAK,CAAC,KAAK;YACT,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YAEhF,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;gBACjD,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAE,CAAC;gBAEzD,IAAI,OAAO,IAAI,OAAO,KAAK,GAAG,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC3E,OAAO;wBACL,MAAM,EAAE;4BACN;gCACE,IAAI,EACF,gBAAgB,IAAI,CAAC,IAAI,sDAAsD;oCAC/E,IAAI,IAAI,qDAAqD,IAAI,KAAK;oCACtE,iFAAiF;oCACjF,iFAAiF;oCACjF,gEAAgE;oCAChE,sDAAsD;6BACzD;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED,sFAAsF;gBACtF,yFAAyF;gBACzF,OAAO,SAAS,CAAC;YACnB,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|