@commerce-klaus/typescript-sfcc 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ [![NPM version][npm-image]][npm-url] [![Downloads][npm-downloads-image]][npm-url]
2
+
3
+ # @commerce-klaus/typescript-sfcc
4
+
5
+ TypeScript tooling for Salesforce Commerce Cloud cartridge projects.
6
+
7
+ The package currently ships two main entry points:
8
+
9
+ - a tsserver plugin that resolves SFCC-specific module patterns such as `~/...`, `*/...`, cartridge aliases, and `module.superModule`
10
+ - a CLI that typechecks cartridge projects with the same resolution behavior
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pnpm add -D @commerce-klaus/typescript-sfcc typescript
16
+ ```
17
+
18
+ ## tsserver Plugin
19
+
20
+ Add the plugin to your cartridge `jsconfig.json` or `tsconfig.json`:
21
+
22
+ ```json
23
+ {
24
+ "compilerOptions": {
25
+ "plugins": [{ "name": "@commerce-klaus/typescript-sfcc" }]
26
+ }
27
+ }
28
+ ```
29
+
30
+ ## CLI
31
+
32
+ Run the cartridge typecheck from your project root:
33
+
34
+ ```bash
35
+ pnpm exec sfcc-ts-typecheck --project cartridges/jsconfig.json
36
+ ```
37
+
38
+ [npm-url]: https://www.npmjs.com/package/@commerce-klaus/typescript-sfcc
39
+ [npm-image]: https://badgen.net/npm/v/@commerce-klaus/typescript-sfcc
40
+ [npm-downloads-image]: https://badgen.net/npm/dw/@commerce-klaus/typescript-sfcc
package/dist/index.cjs ADDED
@@ -0,0 +1,25 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_shared = require("./shared-tI7NsvoF.cjs");
3
+ const require_typecheck = require("./typecheck.cjs");
4
+ //#region src/index.ts
5
+ require_shared.init_shared();
6
+ //#endregion
7
+ exports.SUPER_MODULE_TOKEN = require_shared.SUPER_MODULE_TOKEN;
8
+ exports.SUPPORTED_RUNTIME_EXTENSIONS = require_shared.SUPPORTED_RUNTIME_EXTENSIONS;
9
+ exports.createFormatHost = require_typecheck.createFormatHost;
10
+ exports.createSfccModuleResolver = require_shared.createSfccModuleResolver;
11
+ exports.createSfccPaths = require_shared.createSfccPaths;
12
+ exports.findCartridgesDir = require_shared.findCartridgesDir;
13
+ exports.findContainingCartridgeRoot = require_shared.findContainingCartridgeRoot;
14
+ exports.formatDiagnostics = require_typecheck.formatDiagnostics;
15
+ exports.inferCartridgeOrder = require_shared.inferCartridgeOrder;
16
+ exports.injectTopLevelStatement = require_shared.injectTopLevelStatement;
17
+ exports.parseConfigFile = require_typecheck.parseConfigFile;
18
+ exports.readSolutionReferences = require_shared.readSolutionReferences;
19
+ exports.resolveCandidateFile = require_shared.resolveCandidateFile;
20
+ exports.resolveSuperModuleSpecifier = require_shared.resolveSuperModuleSpecifier;
21
+ exports.runProjectTypecheck = require_typecheck.runProjectTypecheck;
22
+ exports.stripExt = require_shared.stripExt;
23
+ exports.toPosixPath = require_shared.toPosixPath;
24
+ exports.transformSuperModuleSource = require_shared.transformSuperModuleSource;
25
+ exports.typecheckSolutionProjects = require_typecheck.typecheckSolutionProjects;
@@ -0,0 +1,19 @@
1
+ import { createFormatHost, formatDiagnostics, parseConfigFile, runProjectTypecheck, typecheckSolutionProjects } from "./typecheck.cjs";
2
+
3
+ //#region src/shared.d.ts
4
+ declare const SUPPORTED_RUNTIME_EXTENSIONS: readonly ["js", "ds", "json"];
5
+ declare const SUPER_MODULE_TOKEN = "__sfcc_superModule__";
6
+ declare function findCartridgesDir(startDirectory: string): string | undefined;
7
+ declare function readSolutionReferences(solutionConfigPath: string): string[];
8
+ declare function inferCartridgeOrder(cartridgesDir: string, solutionConfigPath?: string): string[];
9
+ declare function findContainingCartridgeRoot(filePath: string, cartridgeRoots: string[]): string | undefined;
10
+ declare function stripExt(filePath: string): string;
11
+ declare function toPosixPath(filePath: string): string;
12
+ declare function resolveCandidateFile(basePath: string, moduleName: string): string | undefined;
13
+ declare function createSfccPaths(configPath: string, cartridgeRoots: string[]): Record<string, string[]>;
14
+ declare function createSfccModuleResolver(cartridgeRoots: string[]): (moduleName: string, containingFile: string) => string | undefined;
15
+ declare function resolveSuperModuleSpecifier(filePath: string, cartridgeRoots: string[]): string | undefined;
16
+ declare function injectTopLevelStatement(sourceCode: string, statement: string): string;
17
+ declare function transformSuperModuleSource(sourceCode: string, filePath: string, cartridgeRoots: string[]): string;
18
+ //#endregion
19
+ export { SUPER_MODULE_TOKEN, SUPPORTED_RUNTIME_EXTENSIONS, createFormatHost, createSfccModuleResolver, createSfccPaths, findCartridgesDir, findContainingCartridgeRoot, formatDiagnostics, inferCartridgeOrder, injectTopLevelStatement, parseConfigFile, readSolutionReferences, resolveCandidateFile, resolveSuperModuleSpecifier, runProjectTypecheck, stripExt, toPosixPath, transformSuperModuleSource, typecheckSolutionProjects };
@@ -0,0 +1,19 @@
1
+ import { createFormatHost, formatDiagnostics, parseConfigFile, runProjectTypecheck, typecheckSolutionProjects } from "./typecheck.mjs";
2
+
3
+ //#region src/shared.d.ts
4
+ declare const SUPPORTED_RUNTIME_EXTENSIONS: readonly ["js", "ds", "json"];
5
+ declare const SUPER_MODULE_TOKEN = "__sfcc_superModule__";
6
+ declare function findCartridgesDir(startDirectory: string): string | undefined;
7
+ declare function readSolutionReferences(solutionConfigPath: string): string[];
8
+ declare function inferCartridgeOrder(cartridgesDir: string, solutionConfigPath?: string): string[];
9
+ declare function findContainingCartridgeRoot(filePath: string, cartridgeRoots: string[]): string | undefined;
10
+ declare function stripExt(filePath: string): string;
11
+ declare function toPosixPath(filePath: string): string;
12
+ declare function resolveCandidateFile(basePath: string, moduleName: string): string | undefined;
13
+ declare function createSfccPaths(configPath: string, cartridgeRoots: string[]): Record<string, string[]>;
14
+ declare function createSfccModuleResolver(cartridgeRoots: string[]): (moduleName: string, containingFile: string) => string | undefined;
15
+ declare function resolveSuperModuleSpecifier(filePath: string, cartridgeRoots: string[]): string | undefined;
16
+ declare function injectTopLevelStatement(sourceCode: string, statement: string): string;
17
+ declare function transformSuperModuleSource(sourceCode: string, filePath: string, cartridgeRoots: string[]): string;
18
+ //#endregion
19
+ export { SUPER_MODULE_TOKEN, SUPPORTED_RUNTIME_EXTENSIONS, createFormatHost, createSfccModuleResolver, createSfccPaths, findCartridgesDir, findContainingCartridgeRoot, formatDiagnostics, inferCartridgeOrder, injectTopLevelStatement, parseConfigFile, readSolutionReferences, resolveCandidateFile, resolveSuperModuleSpecifier, runProjectTypecheck, stripExt, toPosixPath, transformSuperModuleSource, typecheckSolutionProjects };
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ import { a as findCartridgesDir, c as init_shared, d as resolveCandidateFile, f as resolveSuperModuleSpecifier, g as transformSuperModuleSource, h as toPosixPath, i as createSfccPaths, l as injectTopLevelStatement, m as stripExt, n as SUPPORTED_RUNTIME_EXTENSIONS, o as findContainingCartridgeRoot, r as createSfccModuleResolver, s as inferCartridgeOrder, t as SUPER_MODULE_TOKEN, u as readSolutionReferences } from "./shared-j82Y0_wL.mjs";
2
+ import { createFormatHost, formatDiagnostics, parseConfigFile, runProjectTypecheck, typecheckSolutionProjects } from "./typecheck.mjs";
3
+ //#region src/index.ts
4
+ init_shared();
5
+ //#endregion
6
+ export { SUPER_MODULE_TOKEN, SUPPORTED_RUNTIME_EXTENSIONS, createFormatHost, createSfccModuleResolver, createSfccPaths, findCartridgesDir, findContainingCartridgeRoot, formatDiagnostics, inferCartridgeOrder, injectTopLevelStatement, parseConfigFile, readSolutionReferences, resolveCandidateFile, resolveSuperModuleSpecifier, runProjectTypecheck, stripExt, toPosixPath, transformSuperModuleSource, typecheckSolutionProjects };
@@ -0,0 +1,200 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ //#region \0rolldown/runtime.js
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
9
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
10
+ var __exportAll = (all, no_symbols) => {
11
+ let target = {};
12
+ for (var name in all) __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
+ return target;
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
21
+ key = keys[i];
22
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
23
+ get: ((k) => from[k]).bind(null, key),
24
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
25
+ });
26
+ }
27
+ return to;
28
+ };
29
+ var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ //#endregion
31
+ //#region src/shared.ts
32
+ var shared_exports = /* @__PURE__ */ __exportAll({
33
+ SUPER_MODULE_TOKEN: () => SUPER_MODULE_TOKEN,
34
+ SUPPORTED_RUNTIME_EXTENSIONS: () => SUPPORTED_RUNTIME_EXTENSIONS,
35
+ createSfccModuleResolver: () => createSfccModuleResolver,
36
+ createSfccPaths: () => createSfccPaths,
37
+ findCartridgesDir: () => findCartridgesDir,
38
+ findContainingCartridgeRoot: () => findContainingCartridgeRoot,
39
+ inferCartridgeOrder: () => inferCartridgeOrder,
40
+ injectTopLevelStatement: () => injectTopLevelStatement,
41
+ readSolutionReferences: () => readSolutionReferences,
42
+ resolveCandidateFile: () => resolveCandidateFile,
43
+ resolveSuperModuleSpecifier: () => resolveSuperModuleSpecifier,
44
+ stripExt: () => stripExt,
45
+ toPosixPath: () => toPosixPath,
46
+ transformSuperModuleSource: () => transformSuperModuleSource
47
+ });
48
+ function findCartridgesDir(startDirectory) {
49
+ let current = path.resolve(startDirectory);
50
+ while (true) {
51
+ if (path.basename(current) === "cartridges") return current;
52
+ const parent = path.dirname(current);
53
+ if (parent === current) return;
54
+ current = parent;
55
+ }
56
+ }
57
+ function readSolutionReferences(solutionConfigPath) {
58
+ const raw = fs.readFileSync(solutionConfigPath, "utf8");
59
+ const parsed = JSON.parse(raw);
60
+ return (Array.isArray(parsed.references) ? parsed.references : []).map((reference) => {
61
+ const absoluteReference = path.resolve(path.dirname(solutionConfigPath), reference.path ?? "");
62
+ if (absoluteReference.endsWith(".json")) return absoluteReference;
63
+ return path.join(absoluteReference, "jsconfig.json");
64
+ });
65
+ }
66
+ function inferCartridgeOrder(cartridgesDir, solutionConfigPath = path.join(cartridgesDir, "jsconfig.json")) {
67
+ const configured = process.env.SFCC_CARTRIDGE_PATH;
68
+ if (configured?.trim()) return configured.split(":").map((entry) => entry.trim()).filter(Boolean).map((entry) => path.join(cartridgesDir, entry)).filter((entry) => fs.existsSync(entry));
69
+ let fromReferences = [];
70
+ try {
71
+ fromReferences = readSolutionReferences(solutionConfigPath).map((configPath) => path.basename(path.dirname(configPath))).map((name) => path.join(cartridgesDir, name)).filter((cartridgeRoot) => fs.existsSync(cartridgeRoot));
72
+ } catch {
73
+ fromReferences = [];
74
+ }
75
+ const fromFilesystem = fs.readdirSync(cartridgesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path.join(cartridgesDir, entry.name)).sort((left, right) => left.localeCompare(right));
76
+ if (fromReferences.length === 0) return fromFilesystem;
77
+ const seen = new Set(fromReferences);
78
+ for (const cartridgeRoot of fromFilesystem) if (!seen.has(cartridgeRoot)) {
79
+ fromReferences.push(cartridgeRoot);
80
+ seen.add(cartridgeRoot);
81
+ }
82
+ return fromReferences;
83
+ }
84
+ function findContainingCartridgeRoot(filePath, cartridgeRoots) {
85
+ const normalizedPath = path.resolve(filePath);
86
+ return cartridgeRoots.find((cartridgeRoot) => normalizedPath.startsWith(`${cartridgeRoot}${path.sep}`));
87
+ }
88
+ function stripExt(filePath) {
89
+ return filePath.replace(/\.[^.]+$/u, "");
90
+ }
91
+ function toPosixPath(filePath) {
92
+ return filePath.split(path.sep).join("/");
93
+ }
94
+ function resolveCandidateFile(basePath, moduleName) {
95
+ const candidates = [];
96
+ const extension = path.extname(basePath);
97
+ if (extension) {
98
+ candidates.push(basePath);
99
+ if (extension === ".ds") candidates.push(`${basePath.slice(0, -3)}.js`);
100
+ } else {
101
+ candidates.push(basePath);
102
+ for (const runtimeExt of SUPPORTED_RUNTIME_EXTENSIONS) candidates.push(`${basePath}.${runtimeExt}`);
103
+ candidates.push(`${basePath}.d.ts`);
104
+ for (const runtimeExt of SUPPORTED_RUNTIME_EXTENSIONS) candidates.push(path.join(basePath, `index.${runtimeExt}`));
105
+ candidates.push(path.join(basePath, "index.d.ts"));
106
+ if (moduleName.endsWith(".ds")) candidates.push(`${basePath.slice(0, -3)}.js`);
107
+ }
108
+ for (const candidate of candidates) if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;
109
+ }
110
+ function createSfccPaths(configPath, cartridgeRoots) {
111
+ const configDir = path.dirname(configPath);
112
+ const paths = {
113
+ "dw/*": ["../../node_modules/sfcc-dts/@types/sfcc/dw/*"],
114
+ "~/*": ["./*"]
115
+ };
116
+ for (const cartridgeRoot of cartridgeRoots) {
117
+ const alias = path.basename(cartridgeRoot);
118
+ const relative = path.relative(configDir, cartridgeRoot).replaceAll("\\", "/");
119
+ paths[`${alias}/*`] = [relative ? `${relative}/*` : "./*"];
120
+ }
121
+ const modulesRoot = cartridgeRoots.find((cartridgeRoot) => path.basename(cartridgeRoot) === "modules");
122
+ if (modulesRoot) {
123
+ const base = path.relative(configDir, modulesRoot).replaceAll("\\", "/") || ".";
124
+ paths.server = [`${base}/server`];
125
+ paths["server/*"] = [`${base}/server/*`];
126
+ }
127
+ const intNapaliRoot = cartridgeRoots.find((cartridgeRoot) => path.basename(cartridgeRoot) === "int_napali");
128
+ if (intNapaliRoot) {
129
+ const relative = path.relative(configDir, intNapaliRoot).replaceAll("\\", "/");
130
+ paths["bc_napali/*"] = [relative ? `${relative}/*` : "./*"];
131
+ }
132
+ return paths;
133
+ }
134
+ function createSfccModuleResolver(cartridgeRoots) {
135
+ const byAlias = new Map(cartridgeRoots.map((rootPath) => [path.basename(rootPath), rootPath]));
136
+ const modulesRoot = byAlias.get("modules");
137
+ return function resolveSfccModule(moduleName, containingFile) {
138
+ const containingCartridgeRoot = findContainingCartridgeRoot(containingFile, cartridgeRoots);
139
+ if (moduleName === "server" && modulesRoot) return resolveCandidateFile(path.join(modulesRoot, "server"), moduleName);
140
+ if (moduleName.startsWith("server/") && modulesRoot) return resolveCandidateFile(path.join(modulesRoot, moduleName), moduleName);
141
+ if (moduleName.startsWith("~/")) {
142
+ if (!containingCartridgeRoot) return;
143
+ return resolveCandidateFile(path.join(containingCartridgeRoot, moduleName.slice(2)), moduleName);
144
+ }
145
+ if (moduleName.startsWith("*/")) {
146
+ const relativeToCartridge = moduleName.slice(2);
147
+ if (!relativeToCartridge) return;
148
+ for (const cartridgeRoot of cartridgeRoots) {
149
+ const resolved = resolveCandidateFile(path.join(cartridgeRoot, relativeToCartridge), moduleName);
150
+ if (resolved) return resolved;
151
+ }
152
+ }
153
+ const aliasMatch = /^([A-Za-z0-9_-]+)\/(cartridge\/.*)$/u.exec(moduleName);
154
+ if (aliasMatch) {
155
+ const cartridgeRoot = byAlias.get(aliasMatch[1]);
156
+ if (!cartridgeRoot) return;
157
+ return resolveCandidateFile(path.join(cartridgeRoot, aliasMatch[2]), moduleName);
158
+ }
159
+ };
160
+ }
161
+ function resolveSuperModuleSpecifier(filePath, cartridgeRoots) {
162
+ const containingCartridgeRoot = findContainingCartridgeRoot(filePath, cartridgeRoots);
163
+ if (!containingCartridgeRoot) return;
164
+ const relativeModulePath = stripExt(path.relative(containingCartridgeRoot, filePath));
165
+ const ownCartridgeName = path.basename(containingCartridgeRoot);
166
+ const ownCartridgeIndex = cartridgeRoots.findIndex((cartridgeRoot) => path.basename(cartridgeRoot) === ownCartridgeName);
167
+ if (ownCartridgeIndex === -1) return;
168
+ const nextCartridges = cartridgeRoots.slice(ownCartridgeIndex + 1);
169
+ for (const nextCartridgeRoot of nextCartridges) {
170
+ if (!resolveCandidateFile(path.join(nextCartridgeRoot, relativeModulePath), relativeModulePath)) continue;
171
+ return `${path.basename(nextCartridgeRoot)}/${toPosixPath(relativeModulePath)}`;
172
+ }
173
+ }
174
+ function injectTopLevelStatement(sourceCode, statement) {
175
+ if (sourceCode.startsWith("#!")) {
176
+ const firstNewline = sourceCode.indexOf("\n");
177
+ if (firstNewline === -1) return `${sourceCode}\n${statement}\n`;
178
+ return `${sourceCode.slice(0, firstNewline + 1)}${injectTopLevelStatement(sourceCode.slice(firstNewline + 1), statement)}`;
179
+ }
180
+ const useStrictMatch = sourceCode.match(/^(\s*['"]use strict['"];?\s*\r?\n)/u);
181
+ if (useStrictMatch) return `${useStrictMatch[1]}${statement}\n${sourceCode.slice(useStrictMatch[1].length)}`;
182
+ return `${statement}\n${sourceCode}`;
183
+ }
184
+ function transformSuperModuleSource(sourceCode, filePath, cartridgeRoots) {
185
+ if (!sourceCode.includes("module.superModule")) return sourceCode;
186
+ const superModuleSpecifier = resolveSuperModuleSpecifier(filePath, cartridgeRoots);
187
+ if (!superModuleSpecifier) return sourceCode.replaceAll(/\bmodule\.superModule\b/gu, "undefined");
188
+ return injectTopLevelStatement(sourceCode.replaceAll(/\bmodule\.superModule\b/gu, SUPER_MODULE_TOKEN), `const ${SUPER_MODULE_TOKEN} = require(${JSON.stringify(superModuleSpecifier)});`);
189
+ }
190
+ var SUPPORTED_RUNTIME_EXTENSIONS, SUPER_MODULE_TOKEN;
191
+ var init_shared = __esmMin((() => {
192
+ SUPPORTED_RUNTIME_EXTENSIONS = [
193
+ "js",
194
+ "ds",
195
+ "json"
196
+ ];
197
+ SUPER_MODULE_TOKEN = "__sfcc_superModule__";
198
+ }));
199
+ //#endregion
200
+ export { __commonJSMin as _, findCartridgesDir as a, init_shared as c, resolveCandidateFile as d, resolveSuperModuleSpecifier as f, transformSuperModuleSource as g, toPosixPath as h, createSfccPaths as i, injectTopLevelStatement as l, stripExt as m, SUPPORTED_RUNTIME_EXTENSIONS as n, findContainingCartridgeRoot as o, shared_exports as p, createSfccModuleResolver as r, inferCartridgeOrder as s, SUPER_MODULE_TOKEN as t, readSolutionReferences as u, __toCommonJS as v };
@@ -0,0 +1,314 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
9
+ var __exportAll = (all, no_symbols) => {
10
+ let target = {};
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ return target;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
20
+ key = keys[i];
21
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
22
+ get: ((k) => from[k]).bind(null, key),
23
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
24
+ });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
29
+ value: mod,
30
+ enumerable: true
31
+ }) : target, mod));
32
+ var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
+ //#endregion
34
+ let node_fs = require("node:fs");
35
+ node_fs = __toESM(node_fs, 1);
36
+ let node_path = require("node:path");
37
+ node_path = __toESM(node_path, 1);
38
+ //#region src/shared.ts
39
+ var shared_exports = /* @__PURE__ */ __exportAll({
40
+ SUPER_MODULE_TOKEN: () => SUPER_MODULE_TOKEN,
41
+ SUPPORTED_RUNTIME_EXTENSIONS: () => SUPPORTED_RUNTIME_EXTENSIONS,
42
+ createSfccModuleResolver: () => createSfccModuleResolver,
43
+ createSfccPaths: () => createSfccPaths,
44
+ findCartridgesDir: () => findCartridgesDir,
45
+ findContainingCartridgeRoot: () => findContainingCartridgeRoot,
46
+ inferCartridgeOrder: () => inferCartridgeOrder,
47
+ injectTopLevelStatement: () => injectTopLevelStatement,
48
+ readSolutionReferences: () => readSolutionReferences,
49
+ resolveCandidateFile: () => resolveCandidateFile,
50
+ resolveSuperModuleSpecifier: () => resolveSuperModuleSpecifier,
51
+ stripExt: () => stripExt,
52
+ toPosixPath: () => toPosixPath,
53
+ transformSuperModuleSource: () => transformSuperModuleSource
54
+ });
55
+ function findCartridgesDir(startDirectory) {
56
+ let current = node_path.default.resolve(startDirectory);
57
+ while (true) {
58
+ if (node_path.default.basename(current) === "cartridges") return current;
59
+ const parent = node_path.default.dirname(current);
60
+ if (parent === current) return;
61
+ current = parent;
62
+ }
63
+ }
64
+ function readSolutionReferences(solutionConfigPath) {
65
+ const raw = node_fs.default.readFileSync(solutionConfigPath, "utf8");
66
+ const parsed = JSON.parse(raw);
67
+ return (Array.isArray(parsed.references) ? parsed.references : []).map((reference) => {
68
+ const absoluteReference = node_path.default.resolve(node_path.default.dirname(solutionConfigPath), reference.path ?? "");
69
+ if (absoluteReference.endsWith(".json")) return absoluteReference;
70
+ return node_path.default.join(absoluteReference, "jsconfig.json");
71
+ });
72
+ }
73
+ function inferCartridgeOrder(cartridgesDir, solutionConfigPath = node_path.default.join(cartridgesDir, "jsconfig.json")) {
74
+ const configured = process.env.SFCC_CARTRIDGE_PATH;
75
+ if (configured?.trim()) return configured.split(":").map((entry) => entry.trim()).filter(Boolean).map((entry) => node_path.default.join(cartridgesDir, entry)).filter((entry) => node_fs.default.existsSync(entry));
76
+ let fromReferences = [];
77
+ try {
78
+ fromReferences = readSolutionReferences(solutionConfigPath).map((configPath) => node_path.default.basename(node_path.default.dirname(configPath))).map((name) => node_path.default.join(cartridgesDir, name)).filter((cartridgeRoot) => node_fs.default.existsSync(cartridgeRoot));
79
+ } catch {
80
+ fromReferences = [];
81
+ }
82
+ const fromFilesystem = node_fs.default.readdirSync(cartridgesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => node_path.default.join(cartridgesDir, entry.name)).sort((left, right) => left.localeCompare(right));
83
+ if (fromReferences.length === 0) return fromFilesystem;
84
+ const seen = new Set(fromReferences);
85
+ for (const cartridgeRoot of fromFilesystem) if (!seen.has(cartridgeRoot)) {
86
+ fromReferences.push(cartridgeRoot);
87
+ seen.add(cartridgeRoot);
88
+ }
89
+ return fromReferences;
90
+ }
91
+ function findContainingCartridgeRoot(filePath, cartridgeRoots) {
92
+ const normalizedPath = node_path.default.resolve(filePath);
93
+ return cartridgeRoots.find((cartridgeRoot) => normalizedPath.startsWith(`${cartridgeRoot}${node_path.default.sep}`));
94
+ }
95
+ function stripExt(filePath) {
96
+ return filePath.replace(/\.[^.]+$/u, "");
97
+ }
98
+ function toPosixPath(filePath) {
99
+ return filePath.split(node_path.default.sep).join("/");
100
+ }
101
+ function resolveCandidateFile(basePath, moduleName) {
102
+ const candidates = [];
103
+ const extension = node_path.default.extname(basePath);
104
+ if (extension) {
105
+ candidates.push(basePath);
106
+ if (extension === ".ds") candidates.push(`${basePath.slice(0, -3)}.js`);
107
+ } else {
108
+ candidates.push(basePath);
109
+ for (const runtimeExt of SUPPORTED_RUNTIME_EXTENSIONS) candidates.push(`${basePath}.${runtimeExt}`);
110
+ candidates.push(`${basePath}.d.ts`);
111
+ for (const runtimeExt of SUPPORTED_RUNTIME_EXTENSIONS) candidates.push(node_path.default.join(basePath, `index.${runtimeExt}`));
112
+ candidates.push(node_path.default.join(basePath, "index.d.ts"));
113
+ if (moduleName.endsWith(".ds")) candidates.push(`${basePath.slice(0, -3)}.js`);
114
+ }
115
+ for (const candidate of candidates) if (node_fs.default.existsSync(candidate) && node_fs.default.statSync(candidate).isFile()) return candidate;
116
+ }
117
+ function createSfccPaths(configPath, cartridgeRoots) {
118
+ const configDir = node_path.default.dirname(configPath);
119
+ const paths = {
120
+ "dw/*": ["../../node_modules/sfcc-dts/@types/sfcc/dw/*"],
121
+ "~/*": ["./*"]
122
+ };
123
+ for (const cartridgeRoot of cartridgeRoots) {
124
+ const alias = node_path.default.basename(cartridgeRoot);
125
+ const relative = node_path.default.relative(configDir, cartridgeRoot).replaceAll("\\", "/");
126
+ paths[`${alias}/*`] = [relative ? `${relative}/*` : "./*"];
127
+ }
128
+ const modulesRoot = cartridgeRoots.find((cartridgeRoot) => node_path.default.basename(cartridgeRoot) === "modules");
129
+ if (modulesRoot) {
130
+ const base = node_path.default.relative(configDir, modulesRoot).replaceAll("\\", "/") || ".";
131
+ paths.server = [`${base}/server`];
132
+ paths["server/*"] = [`${base}/server/*`];
133
+ }
134
+ const intNapaliRoot = cartridgeRoots.find((cartridgeRoot) => node_path.default.basename(cartridgeRoot) === "int_napali");
135
+ if (intNapaliRoot) {
136
+ const relative = node_path.default.relative(configDir, intNapaliRoot).replaceAll("\\", "/");
137
+ paths["bc_napali/*"] = [relative ? `${relative}/*` : "./*"];
138
+ }
139
+ return paths;
140
+ }
141
+ function createSfccModuleResolver(cartridgeRoots) {
142
+ const byAlias = new Map(cartridgeRoots.map((rootPath) => [node_path.default.basename(rootPath), rootPath]));
143
+ const modulesRoot = byAlias.get("modules");
144
+ return function resolveSfccModule(moduleName, containingFile) {
145
+ const containingCartridgeRoot = findContainingCartridgeRoot(containingFile, cartridgeRoots);
146
+ if (moduleName === "server" && modulesRoot) return resolveCandidateFile(node_path.default.join(modulesRoot, "server"), moduleName);
147
+ if (moduleName.startsWith("server/") && modulesRoot) return resolveCandidateFile(node_path.default.join(modulesRoot, moduleName), moduleName);
148
+ if (moduleName.startsWith("~/")) {
149
+ if (!containingCartridgeRoot) return;
150
+ return resolveCandidateFile(node_path.default.join(containingCartridgeRoot, moduleName.slice(2)), moduleName);
151
+ }
152
+ if (moduleName.startsWith("*/")) {
153
+ const relativeToCartridge = moduleName.slice(2);
154
+ if (!relativeToCartridge) return;
155
+ for (const cartridgeRoot of cartridgeRoots) {
156
+ const resolved = resolveCandidateFile(node_path.default.join(cartridgeRoot, relativeToCartridge), moduleName);
157
+ if (resolved) return resolved;
158
+ }
159
+ }
160
+ const aliasMatch = /^([A-Za-z0-9_-]+)\/(cartridge\/.*)$/u.exec(moduleName);
161
+ if (aliasMatch) {
162
+ const cartridgeRoot = byAlias.get(aliasMatch[1]);
163
+ if (!cartridgeRoot) return;
164
+ return resolveCandidateFile(node_path.default.join(cartridgeRoot, aliasMatch[2]), moduleName);
165
+ }
166
+ };
167
+ }
168
+ function resolveSuperModuleSpecifier(filePath, cartridgeRoots) {
169
+ const containingCartridgeRoot = findContainingCartridgeRoot(filePath, cartridgeRoots);
170
+ if (!containingCartridgeRoot) return;
171
+ const relativeModulePath = stripExt(node_path.default.relative(containingCartridgeRoot, filePath));
172
+ const ownCartridgeName = node_path.default.basename(containingCartridgeRoot);
173
+ const ownCartridgeIndex = cartridgeRoots.findIndex((cartridgeRoot) => node_path.default.basename(cartridgeRoot) === ownCartridgeName);
174
+ if (ownCartridgeIndex === -1) return;
175
+ const nextCartridges = cartridgeRoots.slice(ownCartridgeIndex + 1);
176
+ for (const nextCartridgeRoot of nextCartridges) {
177
+ if (!resolveCandidateFile(node_path.default.join(nextCartridgeRoot, relativeModulePath), relativeModulePath)) continue;
178
+ return `${node_path.default.basename(nextCartridgeRoot)}/${toPosixPath(relativeModulePath)}`;
179
+ }
180
+ }
181
+ function injectTopLevelStatement(sourceCode, statement) {
182
+ if (sourceCode.startsWith("#!")) {
183
+ const firstNewline = sourceCode.indexOf("\n");
184
+ if (firstNewline === -1) return `${sourceCode}\n${statement}\n`;
185
+ return `${sourceCode.slice(0, firstNewline + 1)}${injectTopLevelStatement(sourceCode.slice(firstNewline + 1), statement)}`;
186
+ }
187
+ const useStrictMatch = sourceCode.match(/^(\s*['"]use strict['"];?\s*\r?\n)/u);
188
+ if (useStrictMatch) return `${useStrictMatch[1]}${statement}\n${sourceCode.slice(useStrictMatch[1].length)}`;
189
+ return `${statement}\n${sourceCode}`;
190
+ }
191
+ function transformSuperModuleSource(sourceCode, filePath, cartridgeRoots) {
192
+ if (!sourceCode.includes("module.superModule")) return sourceCode;
193
+ const superModuleSpecifier = resolveSuperModuleSpecifier(filePath, cartridgeRoots);
194
+ if (!superModuleSpecifier) return sourceCode.replaceAll(/\bmodule\.superModule\b/gu, "undefined");
195
+ return injectTopLevelStatement(sourceCode.replaceAll(/\bmodule\.superModule\b/gu, SUPER_MODULE_TOKEN), `const ${SUPER_MODULE_TOKEN} = require(${JSON.stringify(superModuleSpecifier)});`);
196
+ }
197
+ var SUPPORTED_RUNTIME_EXTENSIONS, SUPER_MODULE_TOKEN;
198
+ var init_shared = __esmMin((() => {
199
+ SUPPORTED_RUNTIME_EXTENSIONS = [
200
+ "js",
201
+ "ds",
202
+ "json"
203
+ ];
204
+ SUPER_MODULE_TOKEN = "__sfcc_superModule__";
205
+ }));
206
+ //#endregion
207
+ Object.defineProperty(exports, "SUPER_MODULE_TOKEN", {
208
+ enumerable: true,
209
+ get: function() {
210
+ return SUPER_MODULE_TOKEN;
211
+ }
212
+ });
213
+ Object.defineProperty(exports, "SUPPORTED_RUNTIME_EXTENSIONS", {
214
+ enumerable: true,
215
+ get: function() {
216
+ return SUPPORTED_RUNTIME_EXTENSIONS;
217
+ }
218
+ });
219
+ Object.defineProperty(exports, "__toCommonJS", {
220
+ enumerable: true,
221
+ get: function() {
222
+ return __toCommonJS;
223
+ }
224
+ });
225
+ Object.defineProperty(exports, "__toESM", {
226
+ enumerable: true,
227
+ get: function() {
228
+ return __toESM;
229
+ }
230
+ });
231
+ Object.defineProperty(exports, "createSfccModuleResolver", {
232
+ enumerable: true,
233
+ get: function() {
234
+ return createSfccModuleResolver;
235
+ }
236
+ });
237
+ Object.defineProperty(exports, "createSfccPaths", {
238
+ enumerable: true,
239
+ get: function() {
240
+ return createSfccPaths;
241
+ }
242
+ });
243
+ Object.defineProperty(exports, "findCartridgesDir", {
244
+ enumerable: true,
245
+ get: function() {
246
+ return findCartridgesDir;
247
+ }
248
+ });
249
+ Object.defineProperty(exports, "findContainingCartridgeRoot", {
250
+ enumerable: true,
251
+ get: function() {
252
+ return findContainingCartridgeRoot;
253
+ }
254
+ });
255
+ Object.defineProperty(exports, "inferCartridgeOrder", {
256
+ enumerable: true,
257
+ get: function() {
258
+ return inferCartridgeOrder;
259
+ }
260
+ });
261
+ Object.defineProperty(exports, "init_shared", {
262
+ enumerable: true,
263
+ get: function() {
264
+ return init_shared;
265
+ }
266
+ });
267
+ Object.defineProperty(exports, "injectTopLevelStatement", {
268
+ enumerable: true,
269
+ get: function() {
270
+ return injectTopLevelStatement;
271
+ }
272
+ });
273
+ Object.defineProperty(exports, "readSolutionReferences", {
274
+ enumerable: true,
275
+ get: function() {
276
+ return readSolutionReferences;
277
+ }
278
+ });
279
+ Object.defineProperty(exports, "resolveCandidateFile", {
280
+ enumerable: true,
281
+ get: function() {
282
+ return resolveCandidateFile;
283
+ }
284
+ });
285
+ Object.defineProperty(exports, "resolveSuperModuleSpecifier", {
286
+ enumerable: true,
287
+ get: function() {
288
+ return resolveSuperModuleSpecifier;
289
+ }
290
+ });
291
+ Object.defineProperty(exports, "shared_exports", {
292
+ enumerable: true,
293
+ get: function() {
294
+ return shared_exports;
295
+ }
296
+ });
297
+ Object.defineProperty(exports, "stripExt", {
298
+ enumerable: true,
299
+ get: function() {
300
+ return stripExt;
301
+ }
302
+ });
303
+ Object.defineProperty(exports, "toPosixPath", {
304
+ enumerable: true,
305
+ get: function() {
306
+ return toPosixPath;
307
+ }
308
+ });
309
+ Object.defineProperty(exports, "transformSuperModuleSource", {
310
+ enumerable: true,
311
+ get: function() {
312
+ return transformSuperModuleSource;
313
+ }
314
+ });
@@ -0,0 +1,56 @@
1
+ const require_shared = require("./shared-tI7NsvoF.cjs");
2
+ //#region src/tsserver-plugin.cts
3
+ const { createSfccModuleResolver, findCartridgesDir, inferCartridgeOrder, transformSuperModuleSource } = (require_shared.init_shared(), require_shared.__toCommonJS(require_shared.shared_exports));
4
+ function init(modules) {
5
+ const ts = modules.typescript;
6
+ function create(info) {
7
+ const cartridgesDir = findCartridgesDir(info.project.getCurrentDirectory());
8
+ const cartridgeRoots = cartridgesDir ? inferCartridgeOrder(cartridgesDir) : [];
9
+ const resolveSfccModule = createSfccModuleResolver(cartridgeRoots);
10
+ const host = info.languageServiceHost;
11
+ const compilerOptions = info.project.getCompilationSettings();
12
+ const originalGetScriptSnapshot = host.getScriptSnapshot?.bind(host);
13
+ const originalResolveModuleNames = host.resolveModuleNames?.bind(host);
14
+ const originalResolveModuleNameLiterals = host.resolveModuleNameLiterals?.bind(host);
15
+ host.getScriptSnapshot = (fileName) => {
16
+ const snapshot = originalGetScriptSnapshot?.(fileName);
17
+ if (!snapshot || !fileName.endsWith(".js") || cartridgeRoots.length === 0) return snapshot;
18
+ const sourceCode = snapshot.getText(0, snapshot.getLength());
19
+ const transformedSource = transformSuperModuleSource(sourceCode, fileName, cartridgeRoots);
20
+ if (transformedSource === sourceCode) return snapshot;
21
+ return ts.ScriptSnapshot.fromString(transformedSource);
22
+ };
23
+ host.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference) => {
24
+ const defaultResolved = originalResolveModuleNames ? originalResolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference) : moduleNames.map((moduleName) => ts.resolveModuleName(moduleName, containingFile, compilerOptions, ts.sys).resolvedModule);
25
+ return moduleNames.map((moduleName, index) => {
26
+ const sfccResolved = resolveSfccModule(moduleName, containingFile);
27
+ if (sfccResolved) return toResolvedModule(sfccResolved);
28
+ return defaultResolved[index];
29
+ });
30
+ };
31
+ host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) => {
32
+ const defaultResolved = originalResolveModuleNameLiterals ? originalResolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) : moduleLiterals.map((literal) => ({ resolvedModule: ts.resolveModuleName(literal.text, containingFile, compilerOptions, ts.sys).resolvedModule }));
33
+ return moduleLiterals.map((literal, index) => {
34
+ const sfccResolved = resolveSfccModule(literal.text, containingFile);
35
+ if (sfccResolved) return { resolvedModule: toResolvedModule(sfccResolved) };
36
+ return defaultResolved[index];
37
+ });
38
+ };
39
+ return info.languageService;
40
+ }
41
+ function toResolvedModule(filePath) {
42
+ let extension = ts.Extension.Js;
43
+ if (filePath.endsWith(".d.ts")) extension = ts.Extension.Dts;
44
+ else if (filePath.endsWith(".ts")) extension = ts.Extension.Ts;
45
+ else if (filePath.endsWith(".tsx")) extension = ts.Extension.Tsx;
46
+ else if (filePath.endsWith(".jsx")) extension = ts.Extension.Jsx;
47
+ return {
48
+ resolvedFileName: filePath,
49
+ extension,
50
+ isExternalLibraryImport: false
51
+ };
52
+ }
53
+ return { create };
54
+ }
55
+ module.exports = init;
56
+ //#endregion
@@ -0,0 +1,18 @@
1
+ //#region src/tsserver-plugin.d.cts
2
+ declare function init(modules: {
3
+ typescript: typeof import("typescript");
4
+ }): {
5
+ create: (info: {
6
+ project: {
7
+ getCurrentDirectory(): string;
8
+ getCompilationSettings(): import("typescript").CompilerOptions;
9
+ };
10
+ languageServiceHost: {
11
+ getScriptSnapshot?(fileName: string): import("typescript").IScriptSnapshot | undefined;
12
+ resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: import("typescript").ResolvedProjectReference): Array<import("typescript").ResolvedModule | undefined>;
13
+ resolveModuleNameLiterals?(moduleLiterals: ReadonlyArray<import("typescript").StringLiteralLike>, containingFile: string, redirectedReference: import("typescript").ResolvedProjectReference | undefined, options: import("typescript").CompilerOptions, containingSourceFile: import("typescript").SourceFile | undefined, reusedNames: string[] | undefined): import("typescript").ResolvedModuleWithFailedLookupLocations[];
14
+ };
15
+ languageService: unknown;
16
+ }) => unknown;
17
+ };
18
+ export = init;
@@ -0,0 +1,19 @@
1
+ //#region src/tsserver-plugin.d.cts
2
+ declare function init(modules: {
3
+ typescript: typeof import("typescript");
4
+ }): {
5
+ create: (info: {
6
+ project: {
7
+ getCurrentDirectory(): string;
8
+ getCompilationSettings(): import("typescript").CompilerOptions;
9
+ };
10
+ languageServiceHost: {
11
+ getScriptSnapshot?(fileName: string): import("typescript").IScriptSnapshot | undefined;
12
+ resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: import("typescript").ResolvedProjectReference): Array<import("typescript").ResolvedModule | undefined>;
13
+ resolveModuleNameLiterals?(moduleLiterals: ReadonlyArray<import("typescript").StringLiteralLike>, containingFile: string, redirectedReference: import("typescript").ResolvedProjectReference | undefined, options: import("typescript").CompilerOptions, containingSourceFile: import("typescript").SourceFile | undefined, reusedNames: string[] | undefined): import("typescript").ResolvedModuleWithFailedLookupLocations[];
14
+ };
15
+ languageService: unknown;
16
+ }) => unknown;
17
+ };
18
+ //#endregion
19
+ export { init as default };
@@ -0,0 +1,60 @@
1
+ import { _ as __commonJSMin, c as init_shared, p as shared_exports, v as __toCommonJS } from "./shared-j82Y0_wL.mjs";
2
+ //#region src/tsserver-plugin.cts
3
+ var require_tsserver_plugin = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
+ const { createSfccModuleResolver, findCartridgesDir, inferCartridgeOrder, transformSuperModuleSource } = (init_shared(), __toCommonJS(shared_exports));
5
+ function init(modules) {
6
+ const ts = modules.typescript;
7
+ function create(info) {
8
+ const cartridgesDir = findCartridgesDir(info.project.getCurrentDirectory());
9
+ const cartridgeRoots = cartridgesDir ? inferCartridgeOrder(cartridgesDir) : [];
10
+ const resolveSfccModule = createSfccModuleResolver(cartridgeRoots);
11
+ const host = info.languageServiceHost;
12
+ const compilerOptions = info.project.getCompilationSettings();
13
+ const originalGetScriptSnapshot = host.getScriptSnapshot?.bind(host);
14
+ const originalResolveModuleNames = host.resolveModuleNames?.bind(host);
15
+ const originalResolveModuleNameLiterals = host.resolveModuleNameLiterals?.bind(host);
16
+ host.getScriptSnapshot = (fileName) => {
17
+ const snapshot = originalGetScriptSnapshot?.(fileName);
18
+ if (!snapshot || !fileName.endsWith(".js") || cartridgeRoots.length === 0) return snapshot;
19
+ const sourceCode = snapshot.getText(0, snapshot.getLength());
20
+ const transformedSource = transformSuperModuleSource(sourceCode, fileName, cartridgeRoots);
21
+ if (transformedSource === sourceCode) return snapshot;
22
+ return ts.ScriptSnapshot.fromString(transformedSource);
23
+ };
24
+ host.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference) => {
25
+ const defaultResolved = originalResolveModuleNames ? originalResolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference) : moduleNames.map((moduleName) => ts.resolveModuleName(moduleName, containingFile, compilerOptions, ts.sys).resolvedModule);
26
+ return moduleNames.map((moduleName, index) => {
27
+ const sfccResolved = resolveSfccModule(moduleName, containingFile);
28
+ if (sfccResolved) return toResolvedModule(sfccResolved);
29
+ return defaultResolved[index];
30
+ });
31
+ };
32
+ host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) => {
33
+ const defaultResolved = originalResolveModuleNameLiterals ? originalResolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) : moduleLiterals.map((literal) => ({ resolvedModule: ts.resolveModuleName(literal.text, containingFile, compilerOptions, ts.sys).resolvedModule }));
34
+ return moduleLiterals.map((literal, index) => {
35
+ const sfccResolved = resolveSfccModule(literal.text, containingFile);
36
+ if (sfccResolved) return { resolvedModule: toResolvedModule(sfccResolved) };
37
+ return defaultResolved[index];
38
+ });
39
+ };
40
+ return info.languageService;
41
+ }
42
+ function toResolvedModule(filePath) {
43
+ let extension = ts.Extension.Js;
44
+ if (filePath.endsWith(".d.ts")) extension = ts.Extension.Dts;
45
+ else if (filePath.endsWith(".ts")) extension = ts.Extension.Ts;
46
+ else if (filePath.endsWith(".tsx")) extension = ts.Extension.Tsx;
47
+ else if (filePath.endsWith(".jsx")) extension = ts.Extension.Jsx;
48
+ return {
49
+ resolvedFileName: filePath,
50
+ extension,
51
+ isExternalLibraryImport: false
52
+ };
53
+ }
54
+ return { create };
55
+ }
56
+ module.exports = init;
57
+ }));
58
+ //#endregion
59
+ export default require_tsserver_plugin();
60
+ export {};
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_shared = require("./shared-tI7NsvoF.cjs");
4
+ const require_typecheck = require("./typecheck.cjs");
5
+ let node_path = require("node:path");
6
+ node_path = require_shared.__toESM(node_path, 1);
7
+ let node_url = require("node:url");
8
+ //#region src/typecheck-cartridges.ts
9
+ function runCli(args, options = {}) {
10
+ const currentDirectory = options.currentDirectory ?? process.cwd();
11
+ const writeStdout = options.writeStdout ?? ((text) => process.stdout.write(text));
12
+ const { solutionConfigPath, cartridgesDir } = parseArguments(args, currentDirectory);
13
+ const diagnostics = require_typecheck.typecheckSolutionProjects({
14
+ solutionConfigPath,
15
+ cartridgesDir
16
+ });
17
+ const formatted = require_typecheck.formatDiagnostics(diagnostics, currentDirectory);
18
+ if (formatted) writeStdout(formatted);
19
+ return diagnostics.length > 0 ? 2 : 0;
20
+ }
21
+ function parseArguments(args, currentDirectory) {
22
+ let solutionConfigPath = node_path.default.resolve(currentDirectory, "cartridges", "jsconfig.json");
23
+ let cartridgesDir;
24
+ for (let index = 0; index < args.length; index += 1) {
25
+ const arg = args[index];
26
+ if ((arg === "--project" || arg === "-p") && args[index + 1]) {
27
+ solutionConfigPath = node_path.default.resolve(currentDirectory, args[index + 1]);
28
+ index += 1;
29
+ continue;
30
+ }
31
+ if (arg === "--cartridges-dir" && args[index + 1]) {
32
+ cartridgesDir = node_path.default.resolve(currentDirectory, args[index + 1]);
33
+ index += 1;
34
+ }
35
+ }
36
+ return {
37
+ solutionConfigPath,
38
+ cartridgesDir
39
+ };
40
+ }
41
+ function main(args = process.argv.slice(2), options = {}) {
42
+ const writeStderr = options.writeStderr ?? ((text) => process.stderr.write(text));
43
+ try {
44
+ return runCli(args, options);
45
+ } catch (error) {
46
+ writeStderr(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
47
+ return 1;
48
+ }
49
+ }
50
+ function isDirectExecution() {
51
+ const executedPath = process.argv[1];
52
+ if (!executedPath) return false;
53
+ return node_path.default.resolve(executedPath) === node_path.default.resolve((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
54
+ }
55
+ if (isDirectExecution()) process.exit(main());
56
+ //#endregion
57
+ exports.main = main;
58
+ exports.parseArguments = parseArguments;
59
+ exports.runCli = runCli;
@@ -0,0 +1,14 @@
1
+ //#region src/typecheck-cartridges.d.ts
2
+ interface CliRunOptions {
3
+ currentDirectory?: string;
4
+ writeStdout?: (text: string) => void;
5
+ writeStderr?: (text: string) => void;
6
+ }
7
+ declare function runCli(args: string[], options?: CliRunOptions): number;
8
+ declare function parseArguments(args: string[], currentDirectory: string): {
9
+ solutionConfigPath: string;
10
+ cartridgesDir?: string;
11
+ };
12
+ declare function main(args?: string[], options?: CliRunOptions): number;
13
+ //#endregion
14
+ export { CliRunOptions, main, parseArguments, runCli };
@@ -0,0 +1,14 @@
1
+ //#region src/typecheck-cartridges.d.ts
2
+ interface CliRunOptions {
3
+ currentDirectory?: string;
4
+ writeStdout?: (text: string) => void;
5
+ writeStderr?: (text: string) => void;
6
+ }
7
+ declare function runCli(args: string[], options?: CliRunOptions): number;
8
+ declare function parseArguments(args: string[], currentDirectory: string): {
9
+ solutionConfigPath: string;
10
+ cartridgesDir?: string;
11
+ };
12
+ declare function main(args?: string[], options?: CliRunOptions): number;
13
+ //#endregion
14
+ export { CliRunOptions, main, parseArguments, runCli };
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import { formatDiagnostics, typecheckSolutionProjects } from "./typecheck.mjs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ //#region src/typecheck-cartridges.ts
6
+ function runCli(args, options = {}) {
7
+ const currentDirectory = options.currentDirectory ?? process.cwd();
8
+ const writeStdout = options.writeStdout ?? ((text) => process.stdout.write(text));
9
+ const { solutionConfigPath, cartridgesDir } = parseArguments(args, currentDirectory);
10
+ const diagnostics = typecheckSolutionProjects({
11
+ solutionConfigPath,
12
+ cartridgesDir
13
+ });
14
+ const formatted = formatDiagnostics(diagnostics, currentDirectory);
15
+ if (formatted) writeStdout(formatted);
16
+ return diagnostics.length > 0 ? 2 : 0;
17
+ }
18
+ function parseArguments(args, currentDirectory) {
19
+ let solutionConfigPath = path.resolve(currentDirectory, "cartridges", "jsconfig.json");
20
+ let cartridgesDir;
21
+ for (let index = 0; index < args.length; index += 1) {
22
+ const arg = args[index];
23
+ if ((arg === "--project" || arg === "-p") && args[index + 1]) {
24
+ solutionConfigPath = path.resolve(currentDirectory, args[index + 1]);
25
+ index += 1;
26
+ continue;
27
+ }
28
+ if (arg === "--cartridges-dir" && args[index + 1]) {
29
+ cartridgesDir = path.resolve(currentDirectory, args[index + 1]);
30
+ index += 1;
31
+ }
32
+ }
33
+ return {
34
+ solutionConfigPath,
35
+ cartridgesDir
36
+ };
37
+ }
38
+ function main(args = process.argv.slice(2), options = {}) {
39
+ const writeStderr = options.writeStderr ?? ((text) => process.stderr.write(text));
40
+ try {
41
+ return runCli(args, options);
42
+ } catch (error) {
43
+ writeStderr(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
44
+ return 1;
45
+ }
46
+ }
47
+ function isDirectExecution() {
48
+ const executedPath = process.argv[1];
49
+ if (!executedPath) return false;
50
+ return path.resolve(executedPath) === path.resolve(fileURLToPath(import.meta.url));
51
+ }
52
+ if (isDirectExecution()) process.exit(main());
53
+ //#endregion
54
+ export { main, parseArguments, runCli };
@@ -0,0 +1,95 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_shared = require("./shared-tI7NsvoF.cjs");
3
+ let node_path = require("node:path");
4
+ node_path = require_shared.__toESM(node_path, 1);
5
+ let typescript = require("typescript");
6
+ typescript = require_shared.__toESM(typescript, 1);
7
+ //#region src/typecheck.ts
8
+ require_shared.init_shared();
9
+ function createFormatHost(currentDirectory) {
10
+ return {
11
+ getCanonicalFileName: (fileName) => fileName,
12
+ getCurrentDirectory: () => currentDirectory,
13
+ getNewLine: () => typescript.default.sys.newLine
14
+ };
15
+ }
16
+ function parseConfigFile(configPath, currentDirectory) {
17
+ const configParseHost = {
18
+ ...typescript.default.sys,
19
+ onUnRecoverableConfigFileDiagnostic: (diagnostic) => {
20
+ throw new Error(typescript.default.formatDiagnosticsWithColorAndContext([diagnostic], createFormatHost(currentDirectory)));
21
+ }
22
+ };
23
+ const parsedConfig = typescript.default.getParsedCommandLineOfConfigFile(configPath, {}, configParseHost);
24
+ if (!parsedConfig) throw new Error(`Could not parse TypeScript config at ${configPath}`);
25
+ return parsedConfig;
26
+ }
27
+ function runProjectTypecheck(configPath, cartridgeRoots, currentDirectory) {
28
+ const parsedConfig = parseConfigFile(configPath, currentDirectory);
29
+ parsedConfig.options.paths = require_shared.createSfccPaths(configPath, cartridgeRoots);
30
+ const configFilePath = parsedConfig.options.configFilePath;
31
+ const moduleResolutionCache = typescript.default.createModuleResolutionCache(typeof configFilePath === "string" ? node_path.default.dirname(configFilePath) : currentDirectory, (fileName) => fileName, parsedConfig.options);
32
+ const host = typescript.default.createCompilerHost(parsedConfig.options, true);
33
+ const resolveSfccModule = require_shared.createSfccModuleResolver(cartridgeRoots);
34
+ const hostReadFile = host.readFile?.bind(host);
35
+ const originalReadFile = hostReadFile ? (fileName) => hostReadFile(fileName) : (fileName) => typescript.default.sys.readFile(fileName);
36
+ host.readFile = (fileName) => {
37
+ const fileContent = originalReadFile(fileName);
38
+ if (typeof fileContent !== "string" || !fileName.endsWith(".js")) return fileContent;
39
+ return require_shared.transformSuperModuleSource(fileContent, fileName, cartridgeRoots);
40
+ };
41
+ host.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference, options) => {
42
+ return moduleNames.map((moduleName) => {
43
+ const sfccResolved = resolveSfccModule(moduleName, containingFile);
44
+ if (sfccResolved) return {
45
+ resolvedFileName: sfccResolved,
46
+ extension: pathToExtension(sfccResolved),
47
+ isExternalLibraryImport: false
48
+ };
49
+ return typescript.default.resolveModuleName(moduleName, containingFile, options ?? parsedConfig.options, host, moduleResolutionCache, redirectedReference).resolvedModule;
50
+ });
51
+ };
52
+ host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options, _containingSourceFile, _reusedNames) => {
53
+ return moduleLiterals.map((literal) => {
54
+ const moduleName = typeof literal === "string" ? literal : literal.text;
55
+ const sfccResolved = resolveSfccModule(moduleName, containingFile);
56
+ if (sfccResolved) return { resolvedModule: {
57
+ resolvedFileName: sfccResolved,
58
+ extension: pathToExtension(sfccResolved),
59
+ isExternalLibraryImport: false
60
+ } };
61
+ return { resolvedModule: typescript.default.resolveModuleName(moduleName, containingFile, options ?? parsedConfig.options, host, moduleResolutionCache, redirectedReference).resolvedModule };
62
+ });
63
+ };
64
+ const program = typescript.default.createProgram({
65
+ options: parsedConfig.options,
66
+ rootNames: parsedConfig.fileNames,
67
+ projectReferences: parsedConfig.projectReferences,
68
+ host
69
+ });
70
+ return typescript.default.getPreEmitDiagnostics(program);
71
+ }
72
+ function typecheckSolutionProjects({ solutionConfigPath, cartridgesDir }) {
73
+ const resolvedSolutionConfigPath = node_path.default.resolve(solutionConfigPath);
74
+ const resolvedCartridgesDir = cartridgesDir ? node_path.default.resolve(cartridgesDir) : node_path.default.dirname(resolvedSolutionConfigPath);
75
+ const configPaths = require_shared.readSolutionReferences(resolvedSolutionConfigPath);
76
+ const cartridgeRoots = require_shared.inferCartridgeOrder(resolvedCartridgesDir, resolvedSolutionConfigPath);
77
+ const currentDirectory = node_path.default.dirname(resolvedCartridgesDir);
78
+ return configPaths.flatMap((configPath) => runProjectTypecheck(configPath, cartridgeRoots, currentDirectory));
79
+ }
80
+ function formatDiagnostics(diagnostics, currentDirectory) {
81
+ return typescript.default.formatDiagnosticsWithColorAndContext(diagnostics, createFormatHost(currentDirectory));
82
+ }
83
+ function pathToExtension(filePath) {
84
+ if (filePath.endsWith(".d.ts")) return typescript.default.Extension.Dts;
85
+ if (filePath.endsWith(".tsx")) return typescript.default.Extension.Tsx;
86
+ if (filePath.endsWith(".ts")) return typescript.default.Extension.Ts;
87
+ if (filePath.endsWith(".jsx")) return typescript.default.Extension.Jsx;
88
+ return typescript.default.Extension.Js;
89
+ }
90
+ //#endregion
91
+ exports.createFormatHost = createFormatHost;
92
+ exports.formatDiagnostics = formatDiagnostics;
93
+ exports.parseConfigFile = parseConfigFile;
94
+ exports.runProjectTypecheck = runProjectTypecheck;
95
+ exports.typecheckSolutionProjects = typecheckSolutionProjects;
@@ -0,0 +1,17 @@
1
+ import ts from "typescript";
2
+
3
+ //#region src/typecheck.d.ts
4
+ interface TypecheckOptions {
5
+ solutionConfigPath: string;
6
+ cartridgesDir?: string;
7
+ }
8
+ declare function createFormatHost(currentDirectory: string): ts.FormatDiagnosticsHost;
9
+ declare function parseConfigFile(configPath: string, currentDirectory: string): ts.ParsedCommandLine;
10
+ declare function runProjectTypecheck(configPath: string, cartridgeRoots: string[], currentDirectory: string): readonly ts.Diagnostic[];
11
+ declare function typecheckSolutionProjects({
12
+ solutionConfigPath,
13
+ cartridgesDir
14
+ }: TypecheckOptions): ts.Diagnostic[];
15
+ declare function formatDiagnostics(diagnostics: ts.Diagnostic[], currentDirectory: string): string;
16
+ //#endregion
17
+ export { TypecheckOptions, createFormatHost, formatDiagnostics, parseConfigFile, runProjectTypecheck, typecheckSolutionProjects };
@@ -0,0 +1,17 @@
1
+ import ts from "typescript";
2
+
3
+ //#region src/typecheck.d.ts
4
+ interface TypecheckOptions {
5
+ solutionConfigPath: string;
6
+ cartridgesDir?: string;
7
+ }
8
+ declare function createFormatHost(currentDirectory: string): ts.FormatDiagnosticsHost;
9
+ declare function parseConfigFile(configPath: string, currentDirectory: string): ts.ParsedCommandLine;
10
+ declare function runProjectTypecheck(configPath: string, cartridgeRoots: string[], currentDirectory: string): readonly ts.Diagnostic[];
11
+ declare function typecheckSolutionProjects({
12
+ solutionConfigPath,
13
+ cartridgesDir
14
+ }: TypecheckOptions): ts.Diagnostic[];
15
+ declare function formatDiagnostics(diagnostics: ts.Diagnostic[], currentDirectory: string): string;
16
+ //#endregion
17
+ export { TypecheckOptions, createFormatHost, formatDiagnostics, parseConfigFile, runProjectTypecheck, typecheckSolutionProjects };
@@ -0,0 +1,88 @@
1
+ import { c as init_shared, g as transformSuperModuleSource, i as createSfccPaths, r as createSfccModuleResolver, s as inferCartridgeOrder, u as readSolutionReferences } from "./shared-j82Y0_wL.mjs";
2
+ import path from "node:path";
3
+ import ts from "typescript";
4
+ //#region src/typecheck.ts
5
+ init_shared();
6
+ function createFormatHost(currentDirectory) {
7
+ return {
8
+ getCanonicalFileName: (fileName) => fileName,
9
+ getCurrentDirectory: () => currentDirectory,
10
+ getNewLine: () => ts.sys.newLine
11
+ };
12
+ }
13
+ function parseConfigFile(configPath, currentDirectory) {
14
+ const configParseHost = {
15
+ ...ts.sys,
16
+ onUnRecoverableConfigFileDiagnostic: (diagnostic) => {
17
+ throw new Error(ts.formatDiagnosticsWithColorAndContext([diagnostic], createFormatHost(currentDirectory)));
18
+ }
19
+ };
20
+ const parsedConfig = ts.getParsedCommandLineOfConfigFile(configPath, {}, configParseHost);
21
+ if (!parsedConfig) throw new Error(`Could not parse TypeScript config at ${configPath}`);
22
+ return parsedConfig;
23
+ }
24
+ function runProjectTypecheck(configPath, cartridgeRoots, currentDirectory) {
25
+ const parsedConfig = parseConfigFile(configPath, currentDirectory);
26
+ parsedConfig.options.paths = createSfccPaths(configPath, cartridgeRoots);
27
+ const configFilePath = parsedConfig.options.configFilePath;
28
+ const moduleResolutionCache = ts.createModuleResolutionCache(typeof configFilePath === "string" ? path.dirname(configFilePath) : currentDirectory, (fileName) => fileName, parsedConfig.options);
29
+ const host = ts.createCompilerHost(parsedConfig.options, true);
30
+ const resolveSfccModule = createSfccModuleResolver(cartridgeRoots);
31
+ const hostReadFile = host.readFile?.bind(host);
32
+ const originalReadFile = hostReadFile ? (fileName) => hostReadFile(fileName) : (fileName) => ts.sys.readFile(fileName);
33
+ host.readFile = (fileName) => {
34
+ const fileContent = originalReadFile(fileName);
35
+ if (typeof fileContent !== "string" || !fileName.endsWith(".js")) return fileContent;
36
+ return transformSuperModuleSource(fileContent, fileName, cartridgeRoots);
37
+ };
38
+ host.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference, options) => {
39
+ return moduleNames.map((moduleName) => {
40
+ const sfccResolved = resolveSfccModule(moduleName, containingFile);
41
+ if (sfccResolved) return {
42
+ resolvedFileName: sfccResolved,
43
+ extension: pathToExtension(sfccResolved),
44
+ isExternalLibraryImport: false
45
+ };
46
+ return ts.resolveModuleName(moduleName, containingFile, options ?? parsedConfig.options, host, moduleResolutionCache, redirectedReference).resolvedModule;
47
+ });
48
+ };
49
+ host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options, _containingSourceFile, _reusedNames) => {
50
+ return moduleLiterals.map((literal) => {
51
+ const moduleName = typeof literal === "string" ? literal : literal.text;
52
+ const sfccResolved = resolveSfccModule(moduleName, containingFile);
53
+ if (sfccResolved) return { resolvedModule: {
54
+ resolvedFileName: sfccResolved,
55
+ extension: pathToExtension(sfccResolved),
56
+ isExternalLibraryImport: false
57
+ } };
58
+ return { resolvedModule: ts.resolveModuleName(moduleName, containingFile, options ?? parsedConfig.options, host, moduleResolutionCache, redirectedReference).resolvedModule };
59
+ });
60
+ };
61
+ const program = ts.createProgram({
62
+ options: parsedConfig.options,
63
+ rootNames: parsedConfig.fileNames,
64
+ projectReferences: parsedConfig.projectReferences,
65
+ host
66
+ });
67
+ return ts.getPreEmitDiagnostics(program);
68
+ }
69
+ function typecheckSolutionProjects({ solutionConfigPath, cartridgesDir }) {
70
+ const resolvedSolutionConfigPath = path.resolve(solutionConfigPath);
71
+ const resolvedCartridgesDir = cartridgesDir ? path.resolve(cartridgesDir) : path.dirname(resolvedSolutionConfigPath);
72
+ const configPaths = readSolutionReferences(resolvedSolutionConfigPath);
73
+ const cartridgeRoots = inferCartridgeOrder(resolvedCartridgesDir, resolvedSolutionConfigPath);
74
+ const currentDirectory = path.dirname(resolvedCartridgesDir);
75
+ return configPaths.flatMap((configPath) => runProjectTypecheck(configPath, cartridgeRoots, currentDirectory));
76
+ }
77
+ function formatDiagnostics(diagnostics, currentDirectory) {
78
+ return ts.formatDiagnosticsWithColorAndContext(diagnostics, createFormatHost(currentDirectory));
79
+ }
80
+ function pathToExtension(filePath) {
81
+ if (filePath.endsWith(".d.ts")) return ts.Extension.Dts;
82
+ if (filePath.endsWith(".tsx")) return ts.Extension.Tsx;
83
+ if (filePath.endsWith(".ts")) return ts.Extension.Ts;
84
+ if (filePath.endsWith(".jsx")) return ts.Extension.Jsx;
85
+ return ts.Extension.Js;
86
+ }
87
+ //#endregion
88
+ export { createFormatHost, formatDiagnostics, parseConfigFile, runProjectTypecheck, typecheckSolutionProjects };
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@commerce-klaus/typescript-sfcc",
3
+ "version": "0.0.0",
4
+ "description": "TypeScript tooling for Salesforce Commerce Cloud cartridge projects",
5
+ "keywords": [
6
+ "commercecloud",
7
+ "demandware",
8
+ "salesforce",
9
+ "sfcc",
10
+ "tsserver",
11
+ "typescript"
12
+ ],
13
+ "homepage": "https://github.com/commerce-klaus/commerce-klaus/tree/main/packages/sfcc-ts-tooling#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/commerce-klaus/commerce-klaus/issues"
16
+ },
17
+ "license": "MIT",
18
+ "author": "Jens Simon <https://github.com/jenssimon>",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/commerce-klaus/commerce-klaus",
22
+ "directory": "packages/sfcc-ts-tooling"
23
+ },
24
+ "bin": {
25
+ "sfcc-ts-typecheck": "./dist/typecheck-cartridges.cjs"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "type": "module",
31
+ "main": "./dist/tsserver-plugin.cjs",
32
+ "module": "./dist/index.mjs",
33
+ "types": "./dist/index.d.mts",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.mts",
37
+ "import": "./dist/index.mjs",
38
+ "require": "./dist/tsserver-plugin.cjs"
39
+ },
40
+ "./tsserver-plugin": {
41
+ "types": "./dist/tsserver-plugin.d.cts",
42
+ "import": "./dist/tsserver-plugin.mjs",
43
+ "require": "./dist/tsserver-plugin.cjs"
44
+ },
45
+ "./typecheck": {
46
+ "types": "./dist/typecheck.d.mts",
47
+ "import": "./dist/typecheck.mjs",
48
+ "require": "./dist/typecheck.cjs"
49
+ },
50
+ "./package.json": "./package.json"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "scripts": {
56
+ "build": "vp pack",
57
+ "test": "vp test",
58
+ "check": "vp check",
59
+ "prepublishOnly": "vp run build"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "catalog:",
63
+ "typescript": "catalog:",
64
+ "vite-plus": "catalog:"
65
+ },
66
+ "peerDependencies": {
67
+ "typescript": ">=5.5.0"
68
+ },
69
+ "packageManager": "pnpm@11.9.0"
70
+ }