@teleporthq/teleport-shared 0.43.59 → 0.43.61

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.
Files changed (41) hide show
  1. package/__tests__/utils/local-imports.ts +174 -0
  2. package/__tests__/utils/page-dependencies-prefix.ts +89 -0
  3. package/dist/cjs/index.d.ts +3 -1
  4. package/dist/cjs/index.d.ts.map +1 -1
  5. package/dist/cjs/index.js +5 -1
  6. package/dist/cjs/index.js.map +1 -1
  7. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  8. package/dist/cjs/utils/generic.d.ts +46 -0
  9. package/dist/cjs/utils/generic.d.ts.map +1 -1
  10. package/dist/cjs/utils/generic.js +67 -1
  11. package/dist/cjs/utils/generic.js.map +1 -1
  12. package/dist/cjs/utils/local-imports.d.ts +48 -0
  13. package/dist/cjs/utils/local-imports.d.ts.map +1 -0
  14. package/dist/cjs/utils/local-imports.js +168 -0
  15. package/dist/cjs/utils/local-imports.js.map +1 -0
  16. package/dist/cjs/utils/product-discounts.d.ts +27 -0
  17. package/dist/cjs/utils/product-discounts.d.ts.map +1 -0
  18. package/dist/cjs/utils/product-discounts.js +31 -0
  19. package/dist/cjs/utils/product-discounts.js.map +1 -0
  20. package/dist/esm/index.d.ts +3 -1
  21. package/dist/esm/index.d.ts.map +1 -1
  22. package/dist/esm/index.js +3 -1
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  25. package/dist/esm/utils/generic.d.ts +46 -0
  26. package/dist/esm/utils/generic.d.ts.map +1 -1
  27. package/dist/esm/utils/generic.js +64 -0
  28. package/dist/esm/utils/generic.js.map +1 -1
  29. package/dist/esm/utils/local-imports.d.ts +48 -0
  30. package/dist/esm/utils/local-imports.d.ts.map +1 -0
  31. package/dist/esm/utils/local-imports.js +161 -0
  32. package/dist/esm/utils/local-imports.js.map +1 -0
  33. package/dist/esm/utils/product-discounts.d.ts +27 -0
  34. package/dist/esm/utils/product-discounts.d.ts.map +1 -0
  35. package/dist/esm/utils/product-discounts.js +27 -0
  36. package/dist/esm/utils/product-discounts.js.map +1 -0
  37. package/package.json +3 -3
  38. package/src/index.ts +4 -0
  39. package/src/utils/generic.ts +57 -0
  40. package/src/utils/local-imports.ts +226 -0
  41. package/src/utils/product-discounts.ts +122 -0
@@ -1,6 +1,26 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
2
22
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getValueFromPath = exports.dynamicPathExistsInDefinitions = exports.generateLocalDependenciesPrefix = exports.localRelativePath = void 0;
23
+ exports.getValueFromPath = exports.dynamicPathExistsInDefinitions = exports.generatePageToRootPrefix = exports.generatePageDependenciesPrefix = exports.DEFAULT_PAGES_PATH = exports.generateLocalDependenciesPrefix = exports.localRelativePath = void 0;
4
24
  var path_1 = require("path");
5
25
  /**
6
26
  * `path.relative()`-equivalent that is correct regardless of which `path`
@@ -67,6 +87,52 @@ var generateLocalDependenciesPrefix = function (fromPath, toPath) {
67
87
  return dependencyPrefix;
68
88
  };
69
89
  exports.generateLocalDependenciesPrefix = generateLocalDependenciesPrefix;
90
+ /**
91
+ * The folder every framework-agnostic page path in this repo is relative to by
92
+ * default. Next.js is the only target that emits pages through the plugins
93
+ * below, and its pages root is `pages/` (see the `pages.path` of the strategy
94
+ * in teleport-project-generator-next). Used only as a fallback for callers that
95
+ * do not receive `GeneratorOptions.pagesPath`.
96
+ */
97
+ exports.DEFAULT_PAGES_PATH = ['pages'];
98
+ /**
99
+ * Import prefix from a PAGE file to a folder that lives at the PROJECT ROOT
100
+ * (`resources/`, `utils/`, `components/` ...). Returns a prefix ending in '/',
101
+ * so callers append the file name: `${prefix}${fileName}`.
102
+ *
103
+ * ⛔ A page's `outputOptions.folderPath` is relative to the PAGES ROOT
104
+ * (`['resources']` for `pages/resources/[id].js`), while every folder path in
105
+ * the project strategy is relative to the PROJECT ROOT. Handing those two
106
+ * coordinate systems to a single `path.relative()` call cancels segments that
107
+ * only LOOK common: `relative('/resources/[id]', '/resources/fetch_items')`
108
+ * returned `'../fetch_items'`, which resolves to `pages/fetch_items` — a
109
+ * "Module not found: Can't resolve '../fetch_items'" at `next build` time for
110
+ * every page whose folder happens to be named after a root folder (a
111
+ * `/resources/[id]` route against the `resources/` folder, a `/utils/[id]` one
112
+ * against `utils/`, ...). Every other page built fine, which is exactly why it
113
+ * survived so long.
114
+ *
115
+ * Rebasing the page folder onto the pages root puts both sides in the same
116
+ * coordinate system, so only genuinely shared ancestors are cancelled. The math
117
+ * runs through `generateLocalDependenciesPrefix` — plain array bookkeeping, no
118
+ * `path.relative()` — so it is also immune to the truncated `relative()` that
119
+ * Next's compiled `path-browserify` ships (see `localRelativePath` above).
120
+ */
121
+ var generatePageDependenciesPrefix = function (params) {
122
+ var toPath = params.toPath, folderPath = params.folderPath, pagesPath = params.pagesPath;
123
+ // `folderPath` comes straight out of the UIDL, where it can be absent (or a
124
+ // JSON null) for a page at the pages root — never let that throw on a spread.
125
+ return (0, exports.generateLocalDependenciesPrefix)(__spreadArray(__spreadArray([], (pagesPath || exports.DEFAULT_PAGES_PATH), true), (folderPath || []), true), toPath);
126
+ };
127
+ exports.generatePageDependenciesPrefix = generatePageDependenciesPrefix;
128
+ /**
129
+ * Prefix from a PAGE file back to the PROJECT ROOT ('../', '../../', ...), for
130
+ * callers that build the rest of the path themselves
131
+ * (`${prefix}utils/workflows/runtime`). Same coordinate-system correction as
132
+ * `generatePageDependenciesPrefix`, which it delegates to.
133
+ */
134
+ var generatePageToRootPrefix = function (params) { return (0, exports.generatePageDependenciesPrefix)(__assign(__assign({}, params), { toPath: [] })); };
135
+ exports.generatePageToRootPrefix = generatePageToRootPrefix;
70
136
  var removeCommonStartingPointsFromPaths = function (paths) {
71
137
  var pathsClone = JSON.parse(JSON.stringify(paths));
72
138
  var shortestPathLength = Math.min.apply(Math, pathsClone.map(function (path) {
@@ -1 +1 @@
1
- {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../../src/utils/generic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../../src/utils/generic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { GeneratedFolder } from '@teleporthq/teleport-types';
2
+ /**
3
+ * Safety net for the whole family of "Module not found" build breaks: a plugin
4
+ * emits a relative import whose specifier points at a file the generator never
5
+ * writes. The generated project still LOOKS fine — the defect only surfaces
6
+ * when `next build` (or Vercel) compiles the page, which is far away from the
7
+ * code that computed the path.
8
+ *
9
+ * The one that motivated this module: a page in `pages/resources/` importing
10
+ * from the project's root `resources/` folder collapsed to `../fetch_items`
11
+ * because the page-relative and root-relative folder paths were mixed in a
12
+ * single `path.relative()` call (fixed at the source — see
13
+ * `generatePageDependenciesPrefix` in ./generic). Nothing in the pipeline
14
+ * noticed, so the check below runs over the finished file tree and reports
15
+ * every relative specifier that resolves to no generated file.
16
+ *
17
+ * Report-only by design: a false positive (a string literal that merely looks
18
+ * like an import) must never be able to fail a generation or, worse, rewrite
19
+ * someone's code.
20
+ */
21
+ /** One generated file, addressed by its PROJECT-ROOT-relative path. */
22
+ export interface ProjectFileEntry {
23
+ /** e.g. `pages/resources/[id].js` — always '/'-separated, no leading slash. */
24
+ path: string;
25
+ content: string;
26
+ }
27
+ export interface UnresolvedLocalImport {
28
+ /** Project-root-relative path of the file holding the import. */
29
+ filePath: string;
30
+ /** The specifier exactly as it appears in the source. */
31
+ specifier: string;
32
+ }
33
+ /**
34
+ * Flatten a generated project into project-root-relative file entries. The root
35
+ * folder's own name is the project directory itself, so it is not part of any
36
+ * path.
37
+ */
38
+ export declare const collectProjectFiles: (folder: GeneratedFolder) => ProjectFileEntry[];
39
+ /**
40
+ * Every relative import in `files` that resolves to no file in `files`.
41
+ * Deterministically ordered (file, then specifier) so callers can snapshot it.
42
+ */
43
+ export declare const findUnresolvedLocalImports: (files: ProjectFileEntry[]) => UnresolvedLocalImport[];
44
+ /** `findUnresolvedLocalImports` over a generated project folder. */
45
+ export declare const findUnresolvedLocalImportsInProject: (folder: GeneratedFolder) => UnresolvedLocalImport[];
46
+ /** Human-readable report. Returns an empty string when there is nothing to report. */
47
+ export declare const formatUnresolvedLocalImports: (unresolved: UnresolvedLocalImport[]) => string;
48
+ //# sourceMappingURL=local-imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-imports.d.ts","sourceRoot":"","sources":["../../../src/utils/local-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAE3E;;;;;;;;;;;;;;;;;;GAkBG;AAEH,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAA;IAChB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;CAClB;AAkHD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,WAAY,eAAe,KAAG,gBAAgB,EAmB7E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,UAAW,gBAAgB,EAAE,KAAG,qBAAqB,EA2B3F,CAAA;AAED,oEAAoE;AACpE,eAAO,MAAM,mCAAmC,WACtC,eAAe,KACtB,qBAAqB,EAA6D,CAAA;AAErF,sFAAsF;AACtF,eAAO,MAAM,4BAA4B,eAAgB,qBAAqB,EAAE,KAAG,MAYlF,CAAA"}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatUnresolvedLocalImports = exports.findUnresolvedLocalImportsInProject = exports.findUnresolvedLocalImports = exports.collectProjectFiles = void 0;
4
+ /** File types whose contents are parsed for import specifiers. */
5
+ var SCANNED_EXTENSIONS = ['js', 'jsx', 'mjs', 'cjs', 'ts', 'tsx'];
6
+ /**
7
+ * Extensions a bundler appends to an extensionless specifier. The empty string
8
+ * comes first so a specifier that already carries its extension (`./style.css`)
9
+ * matches as-is.
10
+ */
11
+ var RESOLVED_EXTENSIONS = [
12
+ '',
13
+ '.js',
14
+ '.jsx',
15
+ '.mjs',
16
+ '.cjs',
17
+ '.ts',
18
+ '.tsx',
19
+ '.json',
20
+ '.css',
21
+ '.scss',
22
+ '.sass',
23
+ '.less',
24
+ '.vue',
25
+ '.svelte',
26
+ '.md',
27
+ '.svg',
28
+ ];
29
+ /** Extensions tried for a specifier that points at a folder (`./utils` → `./utils/index.js`). */
30
+ var INDEX_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.vue', '.json'];
31
+ /**
32
+ * Every shape a relative module specifier takes in generated code. Kept as
33
+ * separate, deliberately narrow patterns rather than one clever regex: an
34
+ * over-eager match here would only ever produce noise in a warning.
35
+ */
36
+ var IMPORT_PATTERNS = [
37
+ // import x from './y' / export { x } from './y' (incl. multi-line import lists)
38
+ /\bfrom\s*['"](\.[^'"\n]*)['"]/g,
39
+ // import('./y')
40
+ /\bimport\s*\(\s*['"](\.[^'"\n]*)['"]\s*\)/g,
41
+ // require('./y')
42
+ /\brequire\s*\(\s*['"](\.[^'"\n]*)['"]\s*\)/g,
43
+ // import './y' (side-effect only)
44
+ /\bimport\s+['"](\.[^'"\n]*)['"]/g,
45
+ ];
46
+ var getFileName = function (file) {
47
+ return file.fileType ? "".concat(file.name, ".").concat(file.fileType) : file.name;
48
+ };
49
+ var getExtension = function (filePath) {
50
+ var fileName = filePath.slice(filePath.lastIndexOf('/') + 1);
51
+ var dotIndex = fileName.lastIndexOf('.');
52
+ return dotIndex > 0 ? fileName.slice(dotIndex + 1).toLowerCase() : '';
53
+ };
54
+ /**
55
+ * Resolve `specifier` against the folder holding `filePath`, purely on the
56
+ * segment arrays. Node's `path` is deliberately not used: this code also runs
57
+ * inside teleport-gui's packer Web Worker, where 'path' is swapped for Next's
58
+ * compiled `path-browserify` (see `localRelativePath` in ./generic).
59
+ *
60
+ * Returns null when the specifier climbs above the project root — nothing above
61
+ * it is ever generated, so such an import is unresolvable by definition.
62
+ */
63
+ var resolveSpecifier = function (filePath, specifier) {
64
+ var segments = filePath.split('/').slice(0, -1);
65
+ for (var _i = 0, _a = specifier.split('/'); _i < _a.length; _i++) {
66
+ var part = _a[_i];
67
+ if (part === '' || part === '.') {
68
+ continue;
69
+ }
70
+ if (part === '..') {
71
+ if (segments.length === 0) {
72
+ return null;
73
+ }
74
+ segments.pop();
75
+ continue;
76
+ }
77
+ segments.push(part);
78
+ }
79
+ return segments.join('/');
80
+ };
81
+ /** Drop a bundler suffix (`./icon.svg?inline`, `./font.woff#iefix`) before resolving. */
82
+ var stripSpecifierSuffix = function (specifier) {
83
+ var cutIndex = Math.min.apply(Math, ['?', '#'].map(function (marker) {
84
+ var index = specifier.indexOf(marker);
85
+ return index === -1 ? specifier.length : index;
86
+ }));
87
+ return specifier.slice(0, cutIndex);
88
+ };
89
+ var extractSpecifiers = function (content) {
90
+ var specifiers = new Set();
91
+ IMPORT_PATTERNS.forEach(function (pattern) {
92
+ // Patterns are module-level (and therefore stateful through `lastIndex`) —
93
+ // reset before each file so a previous scan can't skip the first match.
94
+ pattern.lastIndex = 0;
95
+ var match = pattern.exec(content);
96
+ while (match !== null) {
97
+ specifiers.add(match[1]);
98
+ match = pattern.exec(content);
99
+ }
100
+ });
101
+ return Array.from(specifiers);
102
+ };
103
+ /**
104
+ * Flatten a generated project into project-root-relative file entries. The root
105
+ * folder's own name is the project directory itself, so it is not part of any
106
+ * path.
107
+ */
108
+ var collectProjectFiles = function (folder) {
109
+ var entries = [];
110
+ var walk = function (currentFolder, prefix) {
111
+ currentFolder.files.forEach(function (file) {
112
+ entries.push({
113
+ path: "".concat(prefix).concat(getFileName(file)),
114
+ content: file.contentEncoding === 'base64' ? '' : file.content || '',
115
+ });
116
+ });
117
+ currentFolder.subFolders.forEach(function (subFolder) {
118
+ walk(subFolder, "".concat(prefix).concat(subFolder.name, "/"));
119
+ });
120
+ };
121
+ walk(folder, '');
122
+ return entries;
123
+ };
124
+ exports.collectProjectFiles = collectProjectFiles;
125
+ /**
126
+ * Every relative import in `files` that resolves to no file in `files`.
127
+ * Deterministically ordered (file, then specifier) so callers can snapshot it.
128
+ */
129
+ var findUnresolvedLocalImports = function (files) {
130
+ var existingPaths = new Set(files.map(function (file) { return file.path; }));
131
+ var unresolved = [];
132
+ var resolvesToAFile = function (target) {
133
+ return RESOLVED_EXTENSIONS.some(function (extension) { return existingPaths.has("".concat(target).concat(extension)); }) ||
134
+ INDEX_EXTENSIONS.some(function (extension) { return existingPaths.has("".concat(target, "/index").concat(extension)); });
135
+ };
136
+ files.forEach(function (file) {
137
+ if (SCANNED_EXTENSIONS.indexOf(getExtension(file.path)) === -1) {
138
+ return;
139
+ }
140
+ extractSpecifiers(file.content).forEach(function (specifier) {
141
+ var target = resolveSpecifier(file.path, stripSpecifierSuffix(specifier));
142
+ if (target === null || !resolvesToAFile(target)) {
143
+ unresolved.push({ filePath: file.path, specifier: specifier });
144
+ }
145
+ });
146
+ });
147
+ return unresolved.sort(function (first, second) {
148
+ return first.filePath === second.filePath
149
+ ? first.specifier.localeCompare(second.specifier)
150
+ : first.filePath.localeCompare(second.filePath);
151
+ });
152
+ };
153
+ exports.findUnresolvedLocalImports = findUnresolvedLocalImports;
154
+ /** `findUnresolvedLocalImports` over a generated project folder. */
155
+ var findUnresolvedLocalImportsInProject = function (folder) { return (0, exports.findUnresolvedLocalImports)((0, exports.collectProjectFiles)(folder)); };
156
+ exports.findUnresolvedLocalImportsInProject = findUnresolvedLocalImportsInProject;
157
+ /** Human-readable report. Returns an empty string when there is nothing to report. */
158
+ var formatUnresolvedLocalImports = function (unresolved) {
159
+ if (unresolved.length === 0) {
160
+ return '';
161
+ }
162
+ var lines = unresolved.map(function (item) { return " ".concat(item.filePath, " \u2192 '").concat(item.specifier, "'"); });
163
+ return ("".concat(unresolved.length, " generated import").concat(unresolved.length === 1 ? '' : 's', " ") +
164
+ "resolve".concat(unresolved.length === 1 ? 's' : '', " to no generated file \u2014 ") +
165
+ "the build will fail with \"Module not found\":\n".concat(lines.join('\n')));
166
+ };
167
+ exports.formatUnresolvedLocalImports = formatUnresolvedLocalImports;
168
+ //# sourceMappingURL=local-imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-imports.js","sourceRoot":"","sources":["../../../src/utils/local-imports.ts"],"names":[],"mappings":";;;AAoCA,kEAAkE;AAClE,IAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;AAEnE;;;;GAIG;AACH,IAAM,mBAAmB,GAAG;IAC1B,EAAE;IACF,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,MAAM;IACN,SAAS;IACT,KAAK;IACL,MAAM;CACP,CAAA;AAED,iGAAiG;AACjG,IAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAExF;;;;GAIG;AACH,IAAM,eAAe,GAAa;IAChC,gFAAgF;IAChF,gCAAgC;IAChC,gBAAgB;IAChB,4CAA4C;IAC5C,iBAAiB;IACjB,6CAA6C;IAC7C,kCAAkC;IAClC,kCAAkC;CACnC,CAAA;AAED,IAAM,WAAW,GAAG,UAAC,IAAmB;IACtC,OAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAG,IAAI,CAAC,IAAI,cAAI,IAAI,CAAC,QAAQ,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;AAA3D,CAA2D,CAAA;AAE7D,IAAM,YAAY,GAAG,UAAC,QAAgB;IACpC,IAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9D,IAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IAC1C,OAAO,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AACvE,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,IAAM,gBAAgB,GAAG,UAAC,QAAgB,EAAE,SAAiB;IAC3D,IAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAEjD,KAAmB,UAAoB,EAApB,KAAA,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAApB,cAAoB,EAApB,IAAoB,EAAE;QAApC,IAAM,IAAI,SAAA;QACb,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,EAAE;YAC/B,SAAQ;SACT;QACD,IAAI,IAAI,KAAK,IAAI,EAAE;YACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzB,OAAO,IAAI,CAAA;aACZ;YACD,QAAQ,CAAC,GAAG,EAAE,CAAA;YACd,SAAQ;SACT;QACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;KACpB;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,yFAAyF;AACzF,IAAM,oBAAoB,GAAG,UAAC,SAAiB;IAC7C,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,OAAR,IAAI,EAChB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,UAAC,MAAM;QACvB,IAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACvC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;IAChD,CAAC,CAAC,CACH,CAAA;IACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AACrC,CAAC,CAAA;AAED,IAAM,iBAAiB,GAAG,UAAC,OAAe;IACxC,IAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IAEpC,eAAe,CAAC,OAAO,CAAC,UAAC,OAAO;QAC9B,2EAA2E;QAC3E,wEAAwE;QACxE,OAAO,CAAC,SAAS,GAAG,CAAC,CAAA;QACrB,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjC,OAAO,KAAK,KAAK,IAAI,EAAE;YACrB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YACxB,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;SAC9B;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;AAC/B,CAAC,CAAA;AAED;;;;GAIG;AACI,IAAM,mBAAmB,GAAG,UAAC,MAAuB;IACzD,IAAM,OAAO,GAAuB,EAAE,CAAA;IAEtC,IAAM,IAAI,GAAG,UAAC,aAA8B,EAAE,MAAc;QAC1D,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,UAAC,IAAI;YAC/B,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,UAAG,MAAM,SAAG,WAAW,CAAC,IAAI,CAAC,CAAE;gBACrC,OAAO,EAAE,IAAI,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE;aACrE,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,UAAC,SAAS;YACzC,IAAI,CAAC,SAAS,EAAE,UAAG,MAAM,SAAG,SAAS,CAAC,IAAI,MAAG,CAAC,CAAA;QAChD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAEhB,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAnBY,QAAA,mBAAmB,uBAmB/B;AAED;;;GAGG;AACI,IAAM,0BAA0B,GAAG,UAAC,KAAyB;IAClE,IAAM,aAAa,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAC,IAAI,IAAK,OAAA,IAAI,CAAC,IAAI,EAAT,CAAS,CAAC,CAAC,CAAA;IAC7D,IAAM,UAAU,GAA4B,EAAE,CAAA;IAE9C,IAAM,eAAe,GAAG,UAAC,MAAc;QACrC,OAAA,mBAAmB,CAAC,IAAI,CAAC,UAAC,SAAS,IAAK,OAAA,aAAa,CAAC,GAAG,CAAC,UAAG,MAAM,SAAG,SAAS,CAAE,CAAC,EAA1C,CAA0C,CAAC;YACnF,gBAAgB,CAAC,IAAI,CAAC,UAAC,SAAS,IAAK,OAAA,aAAa,CAAC,GAAG,CAAC,UAAG,MAAM,mBAAS,SAAS,CAAE,CAAC,EAAhD,CAAgD,CAAC;IADtF,CACsF,CAAA;IAExF,KAAK,CAAC,OAAO,CAAC,UAAC,IAAI;QACjB,IAAI,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;YAC9D,OAAM;SACP;QAED,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAC,SAAS;YAChD,IAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAA;YAE3E,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE;gBAC/C,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,WAAA,EAAE,CAAC,CAAA;aACpD;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,UAAU,CAAC,IAAI,CAAC,UAAC,KAAK,EAAE,MAAM;QACnC,OAAA,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ;YAChC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC;YACjD,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC;IAFjD,CAEiD,CAClD,CAAA;AACH,CAAC,CAAA;AA3BY,QAAA,0BAA0B,8BA2BtC;AAED,oEAAoE;AAC7D,IAAM,mCAAmC,GAAG,UACjD,MAAuB,IACK,OAAA,IAAA,kCAA0B,EAAC,IAAA,2BAAmB,EAAC,MAAM,CAAC,CAAC,EAAvD,CAAuD,CAAA;AAFxE,QAAA,mCAAmC,uCAEqC;AAErF,sFAAsF;AAC/E,IAAM,4BAA4B,GAAG,UAAC,UAAmC;IAC9E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;QAC3B,OAAO,EAAE,CAAA;KACV;IAED,IAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,UAAC,IAAI,IAAK,OAAA,YAAK,IAAI,CAAC,QAAQ,wBAAS,IAAI,CAAC,SAAS,MAAG,EAA5C,CAA4C,CAAC,CAAA;IAEpF,OAAO,CACL,UAAG,UAAU,CAAC,MAAM,8BAAoB,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAG;QAC7E,iBAAU,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,kCAA0B;QACtE,0DAAiD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAE,CACpE,CAAA;AACH,CAAC,CAAA;AAZY,QAAA,4BAA4B,gCAYxC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The per-product discount rule, as ES5 source for embedding into generated
3
+ * runtime code (the data-source product transform, the storefront cart
4
+ * provider) that cannot import from this package.
5
+ *
6
+ * ⚠️ THIRD MIRROR. The same arithmetic exists in teleport-gui as
7
+ * `features/e-commerce/utils/product-discounts.ts` (the editor/canvas copy) and
8
+ * `features/workflows/templates/builders/ecommerce/product-discount-script.ts`
9
+ * (the copy baked into the add-to-cart workflow). All three must agree to the
10
+ * cent, or the price on the card, the price added to the cart and the price
11
+ * stored on the order will differ. The GUI's
12
+ * `utils/__tests__/product-discount-parity.spec.ts` pins the first two together;
13
+ * this one is covered by `__tests__/product-discounts.test.ts` here.
14
+ *
15
+ * Two rules the whole feature rests on:
16
+ *
17
+ * - Discounts come off the NET price, BEFORE storefront tax. Tax is a
18
+ * percentage of what is actually charged.
19
+ * - The stored `price` column never changes. A discount is a scheduled VIEW of
20
+ * the price, resolved on every read, so it starts and expires on its own.
21
+ *
22
+ * Everything is prefixed `__pd` so the block can be concatenated into any
23
+ * generated module without colliding with its locals — including alongside the
24
+ * `applyStorefrontTax` helpers, which it is always emitted with.
25
+ */
26
+ export declare const generateProductDiscountHelperCode: () => string;
27
+ //# sourceMappingURL=product-discounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-discounts.d.ts","sourceRoot":"","sources":["../../../src/utils/product-discounts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,iCAAiC,QAAO,MAgGpD,CAAA"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateProductDiscountHelperCode = void 0;
4
+ /**
5
+ * The per-product discount rule, as ES5 source for embedding into generated
6
+ * runtime code (the data-source product transform, the storefront cart
7
+ * provider) that cannot import from this package.
8
+ *
9
+ * ⚠️ THIRD MIRROR. The same arithmetic exists in teleport-gui as
10
+ * `features/e-commerce/utils/product-discounts.ts` (the editor/canvas copy) and
11
+ * `features/workflows/templates/builders/ecommerce/product-discount-script.ts`
12
+ * (the copy baked into the add-to-cart workflow). All three must agree to the
13
+ * cent, or the price on the card, the price added to the cart and the price
14
+ * stored on the order will differ. The GUI's
15
+ * `utils/__tests__/product-discount-parity.spec.ts` pins the first two together;
16
+ * this one is covered by `__tests__/product-discounts.test.ts` here.
17
+ *
18
+ * Two rules the whole feature rests on:
19
+ *
20
+ * - Discounts come off the NET price, BEFORE storefront tax. Tax is a
21
+ * percentage of what is actually charged.
22
+ * - The stored `price` column never changes. A discount is a scheduled VIEW of
23
+ * the price, resolved on every read, so it starts and expires on its own.
24
+ *
25
+ * Everything is prefixed `__pd` so the block can be concatenated into any
26
+ * generated module without colliding with its locals — including alongside the
27
+ * `applyStorefrontTax` helpers, which it is always emitted with.
28
+ */
29
+ var generateProductDiscountHelperCode = function () { return "\n// \u2500\u2500 Per-product discounts \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Rides the product row as a JSON `discounts` column: an array of\n// { id, type: 'percentage'|'fixed', value, startsAt, endsAt } with ISO UTC\n// bounds and a HALF-OPEN [startsAt, endsAt) window, so back-to-back discounts\n// hand over with no overlap and no gap.\nfunction __pdRound2(n) { return Math.round(n * 100) / 100; }\n\nfunction __pdSafe(n) {\n var x = typeof n === 'number' ? n : parseFloat(n);\n return isFinite(x) ? x : 0;\n}\n\n// A bound that was written but cannot be read makes the window meaningless, so\n// the entry is dropped rather than silently becoming unbounded.\nfunction __pdBound(value) {\n if (value === null || value === undefined || value === '') { return { ok: true, time: null }; }\n var parsed = Date.parse(String(value));\n if (!isFinite(parsed)) { return { ok: false, time: null }; }\n return { ok: true, time: parsed };\n}\n\n// The column arrives as JSON text on SQL backends and as a real array on the\n// document stores, and it is hand-editable through the admin panel. Anything\n// unparseable means \"no discounts\" rather than an exception inside a render.\nfunction __pdParseDiscounts(raw) {\n var source = raw;\n if (typeof source === 'string') {\n if (source === '') { return []; }\n try { source = JSON.parse(source); } catch (e) { return []; }\n }\n if (Object.prototype.toString.call(source) !== '[object Array]') { return []; }\n var out = [];\n for (var i = 0; i < source.length; i++) {\n var entry = source[i];\n if (!entry || typeof entry !== 'object') { continue; }\n if (entry.type !== 'percentage' && entry.type !== 'fixed') { continue; }\n var value = __pdSafe(entry.value);\n if (value <= 0) { continue; }\n if (entry.type === 'percentage' && value > 100) { continue; }\n var start = __pdBound(entry.startsAt);\n var end = __pdBound(entry.endsAt);\n if (!start.ok || !end.ok) { continue; }\n out.push({\n type: entry.type,\n value: value,\n startTime: start.time === null ? -Infinity : start.time,\n endTime: end.time === null ? Infinity : end.time\n });\n }\n return out;\n}\n\n// Valid data has at most one live entry \u2014 the merchant panel refuses\n// overlapping windows \u2014 but the column is hand-editable, so first-live-wins\n// keeps the runtime deterministic instead of trusting.\nfunction __pdResolveActive(raw, nowMs) {\n var list = __pdParseDiscounts(raw);\n var now = isFinite(nowMs) ? Number(nowMs) : Date.now();\n for (var i = 0; i < list.length; i++) {\n if (list[i].startTime <= now && now < list[i].endTime) {\n return { type: list[i].type, value: list[i].value };\n }\n }\n return null;\n}\n\n// NET in, NET out \u2014 tax is added on top of the result. Clamped at both ends: a\n// fixed amount larger than the price makes the product free, never negative.\nfunction __pdDiscountedPrice(netPrice, discount) {\n var base = __pdRound2(__pdSafe(netPrice));\n if (base <= 0) { return Math.max(0, base); }\n if (!discount) { return base; }\n var value = Math.max(0, __pdSafe(discount.value));\n var discounted = discount.type === 'percentage'\n ? base * (1 - Math.min(value, 100) / 100)\n : base - value;\n return Math.max(0, __pdRound2(discounted));\n}\n\nfunction __pdDiscountAmount(netPrice, discount) {\n var base = Math.max(0, __pdRound2(__pdSafe(netPrice)));\n return __pdRound2(base - __pdDiscountedPrice(base, discount));\n}\n\n// \"10% off\" / \"$10 off\" / \"10 kr off\" \u2014 the badge copy. Symbol-based rather\n// than Intl-based, because it sits beside prices the storefront renders as a\n// symbol glued to two decimals.\nfunction __pdDiscountLabel(discount, currencySymbol, symbolPosition) {\n if (!discount) { return ''; }\n var value = __pdSafe(discount.value);\n var text = (Math.round(value * 100) / 100).toString();\n if (discount.type === 'percentage') { return text + '% off'; }\n var symbol = currencySymbol || '$';\n return (symbolPosition === 'after' ? text + ' ' + symbol : symbol + text) + ' off';\n}\n"; };
30
+ exports.generateProductDiscountHelperCode = generateProductDiscountHelperCode;
31
+ //# sourceMappingURL=product-discounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-discounts.js","sourceRoot":"","sources":["../../../src/utils/product-discounts.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACI,IAAM,iCAAiC,GAAG,cAAc,OAAA,uxIAgG9D,EAhG8D,CAgG9D,CAAA;AAhGY,QAAA,iCAAiC,qCAgG7C"}
@@ -2,6 +2,7 @@ import * as Constants from './constants';
2
2
  import * as StringUtils from './utils/string-utils';
3
3
  import * as UIDLUtils from './utils/uidl-utils';
4
4
  import * as GenericUtils from './utils/generic';
5
+ import * as LocalImports from './utils/local-imports';
5
6
  import * as JSIdentifiers from './utils/js-identifiers';
6
7
  import * as ASTScope from './utils/ast-scope';
7
8
  import * as ASTStatementOrder from './utils/ast-statement-order';
@@ -11,7 +12,8 @@ import * as LayoutTopology from './utils/layout-topology';
11
12
  import * as HtmlContentModel from './utils/html-content-model';
12
13
  import * as StyleDeclarations from './utils/style-declarations';
13
14
  import * as StorefrontTax from './utils/storefront-tax';
15
+ import * as ProductDiscounts from './utils/product-discounts';
14
16
  import * as EmailDate from './utils/email-date';
15
17
  import * as DataCache from './cache';
16
- export { Constants, StringUtils, UIDLUtils, GenericUtils, JSIdentifiers, ASTScope, ASTStatementOrder, ASTEffectCleanup, RoutePaths, LayoutTopology, HtmlContentModel, StyleDeclarations, StorefrontTax, EmailDate, DataCache, };
18
+ export { Constants, StringUtils, UIDLUtils, GenericUtils, LocalImports, JSIdentifiers, ASTScope, ASTStatementOrder, ASTEffectCleanup, RoutePaths, LayoutTopology, HtmlContentModel, StyleDeclarations, StorefrontTax, ProductDiscounts, EmailDate, DataCache, };
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,WAAW,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,iBAAiB,MAAM,6BAA6B,CAAA;AAChE,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,iBAAiB,MAAM,4BAA4B,CAAA;AAC/D,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,SAAS,MAAM,SAAS,CAAA;AAEpC,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,SAAS,GACV,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,WAAW,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,iBAAiB,MAAM,6BAA6B,CAAA;AAChE,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,iBAAiB,MAAM,4BAA4B,CAAA;AAC/D,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,gBAAgB,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,SAAS,MAAM,SAAS,CAAA;AAEpC,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,SAAS,GACV,CAAA"}
package/dist/esm/index.js CHANGED
@@ -2,6 +2,7 @@ import * as Constants from './constants';
2
2
  import * as StringUtils from './utils/string-utils';
3
3
  import * as UIDLUtils from './utils/uidl-utils';
4
4
  import * as GenericUtils from './utils/generic';
5
+ import * as LocalImports from './utils/local-imports';
5
6
  import * as JSIdentifiers from './utils/js-identifiers';
6
7
  import * as ASTScope from './utils/ast-scope';
7
8
  import * as ASTStatementOrder from './utils/ast-statement-order';
@@ -11,7 +12,8 @@ import * as LayoutTopology from './utils/layout-topology';
11
12
  import * as HtmlContentModel from './utils/html-content-model';
12
13
  import * as StyleDeclarations from './utils/style-declarations';
13
14
  import * as StorefrontTax from './utils/storefront-tax';
15
+ import * as ProductDiscounts from './utils/product-discounts';
14
16
  import * as EmailDate from './utils/email-date';
15
17
  import * as DataCache from './cache';
16
- export { Constants, StringUtils, UIDLUtils, GenericUtils, JSIdentifiers, ASTScope, ASTStatementOrder, ASTEffectCleanup, RoutePaths, LayoutTopology, HtmlContentModel, StyleDeclarations, StorefrontTax, EmailDate, DataCache, };
18
+ export { Constants, StringUtils, UIDLUtils, GenericUtils, LocalImports, JSIdentifiers, ASTScope, ASTStatementOrder, ASTEffectCleanup, RoutePaths, LayoutTopology, HtmlContentModel, StyleDeclarations, StorefrontTax, ProductDiscounts, EmailDate, DataCache, };
17
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,WAAW,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,iBAAiB,MAAM,6BAA6B,CAAA;AAChE,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,iBAAiB,MAAM,4BAA4B,CAAA;AAC/D,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,SAAS,MAAM,SAAS,CAAA;AAEpC,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,SAAS,GACV,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,WAAW,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,iBAAiB,MAAM,6BAA6B,CAAA;AAChE,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,iBAAiB,MAAM,4BAA4B,CAAA;AAC/D,OAAO,KAAK,aAAa,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,gBAAgB,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAA;AAC/C,OAAO,KAAK,SAAS,MAAM,SAAS,CAAA;AAEpC,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,SAAS,GACV,CAAA"}