@sitecore-content-sdk/content 1.5.0-canary.5

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 (258) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +7 -0
  3. package/client.d.ts +1 -0
  4. package/codegen.d.ts +1 -0
  5. package/config-cli.d.ts +1 -0
  6. package/config.d.ts +1 -0
  7. package/dist/cjs/client/edge-proxy.js +24 -0
  8. package/dist/cjs/client/index.js +14 -0
  9. package/dist/cjs/client/models.js +2 -0
  10. package/dist/cjs/client/sitecore-client.js +420 -0
  11. package/dist/cjs/client/utils.js +53 -0
  12. package/dist/cjs/config/define-config.js +195 -0
  13. package/dist/cjs/config/index.js +7 -0
  14. package/dist/cjs/config/models.js +12 -0
  15. package/dist/cjs/config-cli/define-cli-config.js +23 -0
  16. package/dist/cjs/config-cli/index.js +7 -0
  17. package/dist/cjs/config-cli/models.js +8 -0
  18. package/dist/cjs/constants.js +12 -0
  19. package/dist/cjs/debug.js +21 -0
  20. package/dist/cjs/editing/codegen/index.js +14 -0
  21. package/dist/cjs/editing/codegen/preview.js +277 -0
  22. package/dist/cjs/editing/component-layout-service.js +62 -0
  23. package/dist/cjs/editing/design-library.js +184 -0
  24. package/dist/cjs/editing/editing-service.js +81 -0
  25. package/dist/cjs/editing/index.js +33 -0
  26. package/dist/cjs/editing/models.js +44 -0
  27. package/dist/cjs/editing/utils.js +105 -0
  28. package/dist/cjs/form/form.js +81 -0
  29. package/dist/cjs/form/index.js +7 -0
  30. package/dist/cjs/i18n/dictionary-service.js +144 -0
  31. package/dist/cjs/i18n/index.js +7 -0
  32. package/dist/cjs/i18n/utils.js +16 -0
  33. package/dist/cjs/index.js +47 -0
  34. package/dist/cjs/layout/content-styles.js +73 -0
  35. package/dist/cjs/layout/index.js +24 -0
  36. package/dist/cjs/layout/layout-service.js +68 -0
  37. package/dist/cjs/layout/models.js +39 -0
  38. package/dist/cjs/layout/themes.js +77 -0
  39. package/dist/cjs/layout/utils.js +117 -0
  40. package/dist/cjs/media/index.js +38 -0
  41. package/dist/cjs/media/media-api.js +100 -0
  42. package/dist/cjs/models.js +2 -0
  43. package/dist/cjs/personalize/index.js +15 -0
  44. package/dist/cjs/personalize/layout-personalizer.js +98 -0
  45. package/dist/cjs/personalize/personalize-service.js +109 -0
  46. package/dist/cjs/personalize/utils.js +143 -0
  47. package/dist/cjs/site/error-pages-service.js +82 -0
  48. package/dist/cjs/site/index.js +26 -0
  49. package/dist/cjs/site/models.js +2 -0
  50. package/dist/cjs/site/redirects-service.js +109 -0
  51. package/dist/cjs/site/robots-service.js +74 -0
  52. package/dist/cjs/site/site-resolver.js +73 -0
  53. package/dist/cjs/site/siteinfo-service.js +94 -0
  54. package/dist/cjs/site/sitemap-xml-service.js +92 -0
  55. package/dist/cjs/site/sitepath-service.js +201 -0
  56. package/dist/cjs/site/utils.js +55 -0
  57. package/dist/cjs/sitecore-service-base.js +33 -0
  58. package/dist/cjs/tools/codegen/component-generation.js +49 -0
  59. package/dist/cjs/tools/codegen/extract-files.js +105 -0
  60. package/dist/cjs/tools/codegen/import-map.js +411 -0
  61. package/dist/cjs/tools/codegen/utils.js +418 -0
  62. package/dist/cjs/tools/generate-map.js +2 -0
  63. package/dist/cjs/tools/generateSites.js +59 -0
  64. package/dist/cjs/tools/index.js +30 -0
  65. package/dist/cjs/tools/scaffold.js +62 -0
  66. package/dist/cjs/tools/templating/components.js +96 -0
  67. package/dist/cjs/tools/templating/index.js +6 -0
  68. package/dist/esm/client/edge-proxy.js +19 -0
  69. package/dist/esm/client/index.js +4 -0
  70. package/dist/esm/client/models.js +1 -0
  71. package/dist/esm/client/sitecore-client.js +416 -0
  72. package/dist/esm/client/utils.js +49 -0
  73. package/dist/esm/config/define-config.js +189 -0
  74. package/dist/esm/config/index.js +2 -0
  75. package/dist/esm/config/models.js +9 -0
  76. package/dist/esm/config-cli/define-cli-config.js +19 -0
  77. package/dist/esm/config-cli/index.js +2 -0
  78. package/dist/esm/config-cli/models.js +5 -0
  79. package/dist/esm/constants.js +9 -0
  80. package/dist/esm/debug.js +19 -0
  81. package/dist/esm/editing/codegen/index.js +1 -0
  82. package/dist/esm/editing/codegen/preview.js +263 -0
  83. package/dist/esm/editing/component-layout-service.js +55 -0
  84. package/dist/esm/editing/design-library.js +172 -0
  85. package/dist/esm/editing/editing-service.js +74 -0
  86. package/dist/esm/editing/index.js +6 -0
  87. package/dist/esm/editing/models.js +41 -0
  88. package/dist/esm/editing/utils.js +98 -0
  89. package/dist/esm/form/form.js +72 -0
  90. package/dist/esm/form/index.js +1 -0
  91. package/dist/esm/i18n/dictionary-service.js +137 -0
  92. package/dist/esm/i18n/index.js +2 -0
  93. package/dist/esm/i18n/utils.js +13 -0
  94. package/dist/esm/index.js +5 -0
  95. package/dist/esm/layout/content-styles.js +65 -0
  96. package/dist/esm/layout/index.js +6 -0
  97. package/dist/esm/layout/layout-service.js +61 -0
  98. package/dist/esm/layout/models.js +36 -0
  99. package/dist/esm/layout/themes.js +72 -0
  100. package/dist/esm/layout/utils.js +109 -0
  101. package/dist/esm/media/index.js +2 -0
  102. package/dist/esm/media/media-api.js +90 -0
  103. package/dist/esm/models.js +1 -0
  104. package/dist/esm/personalize/index.js +3 -0
  105. package/dist/esm/personalize/layout-personalizer.js +93 -0
  106. package/dist/esm/personalize/personalize-service.js +102 -0
  107. package/dist/esm/personalize/utils.js +135 -0
  108. package/dist/esm/site/error-pages-service.js +75 -0
  109. package/dist/esm/site/index.js +8 -0
  110. package/dist/esm/site/models.js +1 -0
  111. package/dist/esm/site/redirects-service.js +102 -0
  112. package/dist/esm/site/robots-service.js +67 -0
  113. package/dist/esm/site/site-resolver.js +69 -0
  114. package/dist/esm/site/siteinfo-service.js +87 -0
  115. package/dist/esm/site/sitemap-xml-service.js +85 -0
  116. package/dist/esm/site/sitepath-service.js +193 -0
  117. package/dist/esm/site/utils.js +49 -0
  118. package/dist/esm/sitecore-service-base.js +29 -0
  119. package/dist/esm/tools/codegen/component-generation.js +44 -0
  120. package/dist/esm/tools/codegen/extract-files.js +99 -0
  121. package/dist/esm/tools/codegen/import-map.js +368 -0
  122. package/dist/esm/tools/codegen/utils.js +373 -0
  123. package/dist/esm/tools/generate-map.js +1 -0
  124. package/dist/esm/tools/generateSites.js +52 -0
  125. package/dist/esm/tools/index.js +6 -0
  126. package/dist/esm/tools/scaffold.js +54 -0
  127. package/dist/esm/tools/templating/components.js +59 -0
  128. package/dist/esm/tools/templating/index.js +1 -0
  129. package/editing.d.ts +1 -0
  130. package/i18n.d.ts +1 -0
  131. package/layout.d.ts +1 -0
  132. package/media.d.ts +1 -0
  133. package/package.json +157 -0
  134. package/personalize.d.ts +1 -0
  135. package/site.d.ts +1 -0
  136. package/tools.d.ts +1 -0
  137. package/types/client/edge-proxy.d.ts +17 -0
  138. package/types/client/edge-proxy.d.ts.map +1 -0
  139. package/types/client/index.d.ts +7 -0
  140. package/types/client/index.d.ts.map +1 -0
  141. package/types/client/models.d.ts +21 -0
  142. package/types/client/models.d.ts.map +1 -0
  143. package/types/client/sitecore-client.d.ts +338 -0
  144. package/types/client/sitecore-client.d.ts.map +1 -0
  145. package/types/client/utils.d.ts +15 -0
  146. package/types/client/utils.d.ts.map +1 -0
  147. package/types/config/define-config.d.ts +20 -0
  148. package/types/config/define-config.d.ts.map +1 -0
  149. package/types/config/index.d.ts +3 -0
  150. package/types/config/index.d.ts.map +1 -0
  151. package/types/config/models.d.ts +287 -0
  152. package/types/config/models.d.ts.map +1 -0
  153. package/types/config-cli/define-cli-config.d.ts +9 -0
  154. package/types/config-cli/define-cli-config.d.ts.map +1 -0
  155. package/types/config-cli/index.d.ts +3 -0
  156. package/types/config-cli/index.d.ts.map +1 -0
  157. package/types/config-cli/models.d.ts +6 -0
  158. package/types/config-cli/models.d.ts.map +1 -0
  159. package/types/constants.d.ts +10 -0
  160. package/types/constants.d.ts.map +1 -0
  161. package/types/debug.d.ts +19 -0
  162. package/types/debug.d.ts.map +1 -0
  163. package/types/editing/codegen/index.d.ts +2 -0
  164. package/types/editing/codegen/index.d.ts.map +1 -0
  165. package/types/editing/codegen/preview.d.ts +256 -0
  166. package/types/editing/codegen/preview.d.ts.map +1 -0
  167. package/types/editing/component-layout-service.d.ts +84 -0
  168. package/types/editing/component-layout-service.d.ts.map +1 -0
  169. package/types/editing/design-library.d.ts +111 -0
  170. package/types/editing/design-library.d.ts.map +1 -0
  171. package/types/editing/editing-service.d.ts +71 -0
  172. package/types/editing/editing-service.d.ts.map +1 -0
  173. package/types/editing/index.d.ts +7 -0
  174. package/types/editing/index.d.ts.map +1 -0
  175. package/types/editing/models.d.ts +103 -0
  176. package/types/editing/models.d.ts.map +1 -0
  177. package/types/editing/utils.d.ts +82 -0
  178. package/types/editing/utils.d.ts.map +1 -0
  179. package/types/form/form.d.ts +25 -0
  180. package/types/form/form.d.ts.map +1 -0
  181. package/types/form/index.d.ts +2 -0
  182. package/types/form/index.d.ts.map +1 -0
  183. package/types/i18n/dictionary-service.d.ts +133 -0
  184. package/types/i18n/dictionary-service.d.ts.map +1 -0
  185. package/types/i18n/index.d.ts +3 -0
  186. package/types/i18n/index.d.ts.map +1 -0
  187. package/types/i18n/utils.d.ts +9 -0
  188. package/types/i18n/utils.d.ts.map +1 -0
  189. package/types/index.d.ts +7 -0
  190. package/types/index.d.ts.map +1 -0
  191. package/types/layout/content-styles.d.ts +20 -0
  192. package/types/layout/content-styles.d.ts.map +1 -0
  193. package/types/layout/index.d.ts +6 -0
  194. package/types/layout/index.d.ts.map +1 -0
  195. package/types/layout/layout-service.d.ts +45 -0
  196. package/types/layout/layout-service.d.ts.map +1 -0
  197. package/types/layout/models.d.ts +174 -0
  198. package/types/layout/models.d.ts.map +1 -0
  199. package/types/layout/themes.d.ts +13 -0
  200. package/types/layout/themes.d.ts.map +1 -0
  201. package/types/layout/utils.d.ts +56 -0
  202. package/types/layout/utils.d.ts.map +1 -0
  203. package/types/media/index.d.ts +3 -0
  204. package/types/media/index.d.ts.map +1 -0
  205. package/types/media/media-api.d.ts +60 -0
  206. package/types/media/media-api.d.ts.map +1 -0
  207. package/types/models.d.ts +32 -0
  208. package/types/models.d.ts.map +1 -0
  209. package/types/personalize/index.d.ts +4 -0
  210. package/types/personalize/index.d.ts.map +1 -0
  211. package/types/personalize/layout-personalizer.d.ts +29 -0
  212. package/types/personalize/layout-personalizer.d.ts.map +1 -0
  213. package/types/personalize/personalize-service.d.ts +89 -0
  214. package/types/personalize/personalize-service.d.ts.map +1 -0
  215. package/types/personalize/utils.d.ts +78 -0
  216. package/types/personalize/utils.d.ts.map +1 -0
  217. package/types/site/error-pages-service.d.ts +64 -0
  218. package/types/site/error-pages-service.d.ts.map +1 -0
  219. package/types/site/index.d.ts +10 -0
  220. package/types/site/index.d.ts.map +1 -0
  221. package/types/site/models.d.ts +23 -0
  222. package/types/site/models.d.ts.map +1 -0
  223. package/types/site/redirects-service.d.ts +91 -0
  224. package/types/site/redirects-service.d.ts.map +1 -0
  225. package/types/site/robots-service.d.ts +57 -0
  226. package/types/site/robots-service.d.ts.map +1 -0
  227. package/types/site/site-resolver.d.ts +28 -0
  228. package/types/site/site-resolver.d.ts.map +1 -0
  229. package/types/site/siteinfo-service.d.ts +64 -0
  230. package/types/site/siteinfo-service.d.ts.map +1 -0
  231. package/types/site/sitemap-xml-service.d.ts +63 -0
  232. package/types/site/sitemap-xml-service.d.ts.map +1 -0
  233. package/types/site/sitepath-service.d.ts +137 -0
  234. package/types/site/sitepath-service.d.ts.map +1 -0
  235. package/types/site/utils.d.ts +41 -0
  236. package/types/site/utils.d.ts.map +1 -0
  237. package/types/sitecore-service-base.d.ts +31 -0
  238. package/types/sitecore-service-base.d.ts.map +1 -0
  239. package/types/tools/codegen/component-generation.d.ts +50 -0
  240. package/types/tools/codegen/component-generation.d.ts.map +1 -0
  241. package/types/tools/codegen/extract-files.d.ts +24 -0
  242. package/types/tools/codegen/extract-files.d.ts.map +1 -0
  243. package/types/tools/codegen/import-map.d.ts +103 -0
  244. package/types/tools/codegen/import-map.d.ts.map +1 -0
  245. package/types/tools/codegen/utils.d.ts +76 -0
  246. package/types/tools/codegen/utils.d.ts.map +1 -0
  247. package/types/tools/generate-map.d.ts +36 -0
  248. package/types/tools/generate-map.d.ts.map +1 -0
  249. package/types/tools/generateSites.d.ts +25 -0
  250. package/types/tools/generateSites.d.ts.map +1 -0
  251. package/types/tools/index.d.ts +8 -0
  252. package/types/tools/index.d.ts.map +1 -0
  253. package/types/tools/scaffold.d.ts +27 -0
  254. package/types/tools/scaffold.d.ts.map +1 -0
  255. package/types/tools/templating/components.d.ts +104 -0
  256. package/types/tools/templating/components.d.ts.map +1 -0
  257. package/types/tools/templating/index.d.ts +2 -0
  258. package/types/tools/templating/index.d.ts.map +1 -0
@@ -0,0 +1,373 @@
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ import chalk from 'chalk';
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ import * as ts from 'typescript';
6
+ import { debug } from '@sitecore-content-sdk/core';
7
+ import { isBuiltin } from 'module';
8
+ /**
9
+ * Parse the generated component-map file and return all referenced modules
10
+ * per map entry (handles both single identifiers and spread objects).
11
+ * @param {string} appRoot path to the JSS app root
12
+ * @param {string} componentMapPath path to the component map file
13
+ * @returns map of component names and their respective import strings
14
+ */
15
+ export let resolveComponentImportFiles = _resolveComponentImportFiles;
16
+ /**
17
+ * Reads the named exports from a TypeScript file.
18
+ * @param {ExtractedFile} filePath absolute path to a .ts/.tsx file
19
+ * @returns {string[]} list of named exports found in the file
20
+ */
21
+ export let readNamedExports = _readNamedExports;
22
+ /**
23
+ * Sends the extracted code to the specified target URL.
24
+ * @param {object} params - The parameters object.
25
+ * @param {ExtractedFile} params.file - The file to be sent.
26
+ * @param {string} params.token - The access token for authentication.
27
+ * @param {string} params.targetUrl - The target URL to send the file to.
28
+ * @param {Record<string, unknown>} [params.extraLabels] - Additional labels to include in the payload.
29
+ * @returns {Promise<string | null>} - The path of the sent file or null if sending failed.
30
+ */
31
+ export let sendCode = _sendCode;
32
+ export const utilsUnitMocks = {
33
+ set xmCloudDeploy(mockImpl) {
34
+ utils.xmCloudDeploy = mockImpl;
35
+ },
36
+ get xmCloudDeploy() {
37
+ return _xmCloudDeploy;
38
+ },
39
+ set resolveComponentImportFiles(mockImpl) {
40
+ resolveComponentImportFiles = mockImpl;
41
+ },
42
+ get resolveComponentImportFiles() {
43
+ return _resolveComponentImportFiles;
44
+ },
45
+ set readNamedExports(mockImpl) {
46
+ readNamedExports = mockImpl;
47
+ },
48
+ get readNamedExports() {
49
+ return _readNamedExports;
50
+ },
51
+ set sendCode(mockImpl) {
52
+ sendCode = mockImpl;
53
+ },
54
+ get sendCode() {
55
+ return _sendCode;
56
+ },
57
+ };
58
+ /**
59
+ * Type of file to be sent to the mesh endpoint
60
+ */
61
+ export var ExtractedFileType;
62
+ (function (ExtractedFileType) {
63
+ ExtractedFileType["Component"] = "component";
64
+ ExtractedFileType["Variant"] = "variant";
65
+ ExtractedFileType["Json"] = "json";
66
+ ExtractedFileType["PackageJson"] = "package.json";
67
+ })(ExtractedFileType || (ExtractedFileType = {}));
68
+ export const utils = {
69
+ xmCloudDeploy: (...args) => _xmCloudDeploy(...args),
70
+ };
71
+ export const _xmCloudDeploy = () => !!process.env.SITECORE && !!process.env.SITECORE_BUILD;
72
+ // workaround, Vercel does not have variables that are only accessible at build time
73
+ const vercelDeploy = () => !!process.env.VERCEL && !process.env.VERCEL_REGION;
74
+ const netlifyDeploy = () => !!process.env.NETLIFY && !!process.env.BUILD_ID;
75
+ /**
76
+ * Validates if the current operation is done in Vercel, Netlify or XMCloud
77
+ * deploy context
78
+ * @returns {boolean} - true if in deploy context, false otherwise
79
+ */
80
+ export function validateDeployContext() {
81
+ return _xmCloudDeploy() || vercelDeploy() || netlifyDeploy();
82
+ }
83
+ /*
84
+ * Load and parse the tsconfig.json file from the specified app path.
85
+ */
86
+ function loadCompilerOptions(appPathAbs) {
87
+ const configPath = ts.findConfigFile(appPathAbs, ts.sys.fileExists, 'tsconfig.json');
88
+ if (!configPath) {
89
+ // Sane defaults if no tsconfig exists
90
+ return {
91
+ jsx: ts.JsxEmit.Preserve,
92
+ allowJs: true,
93
+ module: ts.ModuleKind.ESNext,
94
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
95
+ target: ts.ScriptTarget.ES2020,
96
+ baseUrl: appPathAbs,
97
+ noEmit: true,
98
+ };
99
+ }
100
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
101
+ if (configFile.error) {
102
+ throw new Error(`Error reading tsconfig at ${configPath}: ${configFile.error.messageText}`);
103
+ }
104
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
105
+ // Merge with a few safe fallbacks/overrides
106
+ return Object.assign({ jsx: ts.JsxEmit.Preserve, allowJs: true, module: ts.ModuleKind.ESNext, moduleResolution: ts.ModuleResolutionKind.NodeNext, target: ts.ScriptTarget.ES2020, baseUrl: appPathAbs, noEmit: true }, parsed.options);
107
+ }
108
+ /*
109
+ * Resolve a module specifier using tsconfig options (fast, no Program needed).
110
+ */
111
+ function resolveWithTs(spec, fromFile, options) {
112
+ var _a, _b;
113
+ const host = {
114
+ fileExists: ts.sys.fileExists,
115
+ readFile: ts.sys.readFile,
116
+ directoryExists: ts.sys.directoryExists,
117
+ getCurrentDirectory: ts.sys.getCurrentDirectory,
118
+ getDirectories: ts.sys.getDirectories,
119
+ realpath: ts.sys.realpath,
120
+ };
121
+ const result = ts.resolveModuleName(spec, fromFile, options, host);
122
+ return (_b = (_a = result.resolvedModule) === null || _a === void 0 ? void 0 : _a.resolvedFileName) !== null && _b !== void 0 ? _b : null;
123
+ }
124
+ function _resolveComponentImportFiles(appRoot, componentMapPath = './.sitecore/component-map.ts') {
125
+ const appPath = path.isAbsolute(appRoot) ? appRoot : path.resolve(process.cwd(), appRoot);
126
+ const mapPath = path.isAbsolute(componentMapPath)
127
+ ? componentMapPath
128
+ : path.resolve(appPath, componentMapPath);
129
+ if (!fs.existsSync(mapPath)) {
130
+ throw new ReferenceError(`Failed to find file ${mapPath}`);
131
+ }
132
+ // 1) Load tsconfig (simple + safe). Use appPath as baseUrl fallback.
133
+ const compilerOptions = loadCompilerOptions(appPath);
134
+ // Read & parse the map file to an AST (SourceFile)
135
+ const mapText = fs.readFileSync(mapPath, 'utf8');
136
+ const source = ts.createSourceFile(mapPath, mapText, ts.ScriptTarget.Latest, true);
137
+ const getFileType = (absPath) => {
138
+ const base = path.basename(absPath); // "PromoBlock.extra.tsx"
139
+ const name = base.replace(/\.[^.]+$/, ''); // "PromoBlock.extra"
140
+ return name.includes('.') ? ExtractedFileType.Variant : ExtractedFileType.Component;
141
+ };
142
+ // 1) Collect import (import %importString% from %importModule%) strings
143
+ const componentMapImports = new Map();
144
+ source.forEachChild((node) => {
145
+ if (ts.isImportDeclaration(node) && node.importClause) {
146
+ const importString = node.importClause.getText();
147
+ const importModule = node.moduleSpecifier.text;
148
+ componentMapImports.set(importString, importModule);
149
+ }
150
+ });
151
+ // 2) Find the map literal: new Map([...]) and collect entries
152
+ // Also capture subsequent mutations: <mapIdent>.set('Key', Value)
153
+ const results = [];
154
+ const mapIdentifiers = new Set(); // all identifiers bound to the Map we care about
155
+ // Given an import and an expression (identifier or object literal with spreads),
156
+ // resolve the module(s) to absolute file paths and append normalized entries to `results`.
157
+ const resolveAndRecordEntry = (importStringsEntry, mapEntry) => {
158
+ // small guard to record a resolved path if valid
159
+ const recordIfValid = (spec) => {
160
+ // ignore Node built-ins and node: protocol up front
161
+ if (isBuiltin(spec) || isNodeProtocol(spec))
162
+ return;
163
+ const fileAbs = resolveWithTs(spec, mapPath, compilerOptions);
164
+ if (!fileAbs)
165
+ return;
166
+ // ignore node_modules and *.d.ts after resolution
167
+ if (inNodeModules(fileAbs) || isDeclarationFile(fileAbs))
168
+ return;
169
+ results.push({
170
+ componentKey: importStringsEntry,
171
+ filePath: toPosixPath(fileAbs),
172
+ fileType: getFileType(fileAbs),
173
+ });
174
+ };
175
+ // Helper to find the matching import statement for a given component/module name
176
+ const getImportPathForModule = (componentModuleName) => {
177
+ let result = componentMapImports.get(componentModuleName);
178
+ if (!result) {
179
+ for (const key of componentMapImports.keys()) {
180
+ const matcher = new RegExp(`\\b(${componentModuleName})\\b`);
181
+ if (key.match(matcher) !== null) {
182
+ return componentMapImports.get(key);
183
+ }
184
+ }
185
+ return null;
186
+ }
187
+ return result;
188
+ };
189
+ // Case A: ['Key', Identifier]
190
+ if (ts.isIdentifier(mapEntry)) {
191
+ const componentEntryName = mapEntry.text;
192
+ const importPathString = getImportPathForModule(componentEntryName);
193
+ if (!importPathString)
194
+ return;
195
+ recordIfValid(importPathString);
196
+ return;
197
+ }
198
+ // Case B: ['Key', { ...A, ...B, ...C }]
199
+ if (ts.isObjectLiteralExpression(mapEntry)) {
200
+ mapEntry.properties.forEach((prop) => {
201
+ if (ts.isSpreadAssignment(prop) && ts.isIdentifier(prop.expression)) {
202
+ const componentEntryName = prop.expression.text;
203
+ const importPathString = getImportPathForModule(componentEntryName);
204
+ if (!importPathString)
205
+ return;
206
+ recordIfValid(importPathString);
207
+ }
208
+ });
209
+ }
210
+ };
211
+ // Walk the `new Map([...])` array literal and feed each ['Key', Value] into
212
+ // `resolveAndRecordEntry` (only when the key is a string literal).
213
+ const collectArrayEntries = (arrayArg) => {
214
+ arrayArg.elements.forEach((el) => {
215
+ if (ts.isArrayLiteralExpression(el)) {
216
+ const [keyNode, valNode] = el.elements;
217
+ if (keyNode && valNode && ts.isStringLiteral(keyNode)) {
218
+ resolveAndRecordEntry(keyNode.text, valNode);
219
+ }
220
+ }
221
+ });
222
+ };
223
+ // If this `new Map([...])` is bound to a variable (via decl or assignment),
224
+ // record the identifier name so we can catch later `<id>.set(...)` mutations.
225
+ const captureMapIdentifier = (node) => {
226
+ // const m = new Map([...])
227
+ const parent = node.parent;
228
+ // Variable declaration with initializer new Map(...)
229
+ if (parent && ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
230
+ mapIdentifiers.add(parent.name.text);
231
+ return;
232
+ }
233
+ // Assignment: m = new Map([...])
234
+ if (parent &&
235
+ ts.isBinaryExpression(parent) &&
236
+ parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
237
+ ts.isIdentifier(parent.left)) {
238
+ mapIdentifiers.add(parent.left.text);
239
+ return;
240
+ }
241
+ // Exported variable declaration: export const componentMap = new Map([...])
242
+ if (parent && ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
243
+ mapIdentifiers.add(parent.name.text);
244
+ return;
245
+ }
246
+ };
247
+ const traverseAst = (node) => {
248
+ var _a;
249
+ // A) Initial literal: new Map([...])
250
+ if (ts.isNewExpression(node) &&
251
+ node.expression.getText(source) === 'Map' &&
252
+ node.arguments &&
253
+ node.arguments.length > 0) {
254
+ const firstArg = node.arguments[0];
255
+ if (ts.isArrayLiteralExpression(firstArg)) {
256
+ collectArrayEntries(firstArg);
257
+ }
258
+ captureMapIdentifier(node);
259
+ }
260
+ // B) Mutations: <mapIdent>.set('Key', Value)
261
+ if (ts.isCallExpression(node) &&
262
+ ts.isPropertyAccessExpression(node.expression) &&
263
+ node.expression.name.text === 'set') {
264
+ const target = node.expression.expression;
265
+ if (ts.isIdentifier(target) && mapIdentifiers.has(target.text)) {
266
+ const [keyArg, valArg] = (_a = node.arguments) !== null && _a !== void 0 ? _a : [];
267
+ if (keyArg && ts.isStringLiteral(keyArg) && valArg) {
268
+ resolveAndRecordEntry(keyArg.text, valArg);
269
+ }
270
+ }
271
+ }
272
+ ts.forEachChild(node, traverseAst);
273
+ };
274
+ ts.forEachChild(source, traverseAst);
275
+ return results.filter((r) => !isDeclarationFile(r.filePath));
276
+ }
277
+ function _readNamedExports(filePath) {
278
+ const code = fs.readFileSync(filePath, 'utf8');
279
+ const sf = ts.createSourceFile(filePath, code, ts.ScriptTarget.Latest, true);
280
+ const names = new Set();
281
+ const visit = (node) => {
282
+ var _a, _b;
283
+ // export const X = ...
284
+ if (ts.isVariableStatement(node) &&
285
+ ((_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.some((m) => m.kind === ts.SyntaxKind.ExportKeyword))) {
286
+ node.declarationList.declarations.forEach((d) => {
287
+ if (ts.isIdentifier(d.name))
288
+ names.add(d.name.text);
289
+ });
290
+ }
291
+ // export function X() {}
292
+ if (ts.isFunctionDeclaration(node) &&
293
+ ((_b = node.modifiers) === null || _b === void 0 ? void 0 : _b.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) &&
294
+ node.name) {
295
+ names.add(node.name.text);
296
+ }
297
+ // export { A, B as C }
298
+ if (ts.isExportDeclaration(node) && node.exportClause && ts.isNamedExports(node.exportClause)) {
299
+ node.exportClause.elements.forEach((e) => names.add(e.name.text));
300
+ }
301
+ // export default ...
302
+ if (ts.isExportAssignment(node)) {
303
+ names.add('Default');
304
+ }
305
+ ts.forEachChild(node, visit);
306
+ };
307
+ ts.forEachChild(sf, visit);
308
+ return Array.from(names);
309
+ }
310
+ async function _sendCode({ file, token, targetUrl, }) {
311
+ const apiEndpoint = `${targetUrl}/mesh/push/api/v1/contentsdk/code/extracted`;
312
+ if (!fs.existsSync(file.path)) {
313
+ console.error(chalk.red(`File not found: ${file.path}`));
314
+ return null;
315
+ }
316
+ const code = fs.readFileSync(file.path);
317
+ // Merge base labels with any extra labels (variants, componentName, etc.)
318
+ const labels = Object.assign({ type: file.type }, (file.labels || {}));
319
+ try {
320
+ const response = await fetch(apiEndpoint, {
321
+ method: 'POST',
322
+ headers: {
323
+ Authorization: `Bearer ${token}`,
324
+ 'Content-Type': 'application/json',
325
+ },
326
+ body: JSON.stringify({
327
+ EnvironmentId: 'ContentSDK',
328
+ name: file.name,
329
+ content: code.toString(),
330
+ labels,
331
+ }),
332
+ });
333
+ if (!response.ok) {
334
+ console.error(chalk.red(`Failed to send extracted code from ${file.path}: ${response.statusText}`));
335
+ debug.http('Error details: %o', {
336
+ status: response.status,
337
+ text: await response.text(),
338
+ url: response.url,
339
+ headers: response.headers,
340
+ });
341
+ return null;
342
+ }
343
+ }
344
+ catch (error) {
345
+ console.error(chalk.red(`Fetch request to send extracted code from ${file.path} failed: ${JSON.stringify(error)}`));
346
+ return null;
347
+ }
348
+ return file.path;
349
+ }
350
+ const NODE_PROTOCOL = 'node:';
351
+ function isNodeProtocol(specifier) {
352
+ return specifier.startsWith(NODE_PROTOCOL);
353
+ }
354
+ function isDeclarationFile(p) {
355
+ return p.endsWith('.d.ts');
356
+ }
357
+ function inNodeModules(p) {
358
+ return p.replace(/\\/g, '/').includes('/node_modules/');
359
+ }
360
+ // Normalize path separators to POSIX-style "/" for cross-platform consistency.
361
+ export function toPosixPath(p) {
362
+ if (/^\\\\\?\\/.test(p))
363
+ return p;
364
+ return p.replace(/\\/g, '/');
365
+ }
366
+ export const stripExtension = (p) => p.replace(/\.(tsx?|jsx?|mjs|cjs)$/, '');
367
+ // Convert an absolute file path into an relative module specifier (POSIX)
368
+ export const getRelativeImportPath = (absFile, appPath) => {
369
+ let rel = toPosixPath(path.relative(appPath, absFile));
370
+ return stripExtension(rel);
371
+ };
372
+ // Determine if a specifier is bare/aliased (i.e., not relative "./" or "../" and not absolute "/").
373
+ export const isNodeModuleImport = (name) => !name.startsWith('./') && !name.startsWith('../') && !name.startsWith('/');
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ import path from 'path';
2
+ import chalk from 'chalk';
3
+ import fs from 'fs';
4
+ import { ensurePathExists } from '@sitecore-content-sdk/core/tools';
5
+ import { SiteInfoService } from '../site';
6
+ import { createGraphQLClientFactory } from '../client';
7
+ import debug from '../debug';
8
+ const DEFAULT_SITES_DIST_PATH = '.sitecore/sites.json';
9
+ /**
10
+ * Generates site information and writes it to a specified destination path.
11
+ * @param {GenerateSitesConfig} config - The configuration for generating site info.
12
+ * @returns {Promise<Function>} - A promise that resolves to an asynchronous function that fetches site information and writes it to a file.
13
+ * @public
14
+ */
15
+ export const generateSites = ({ scConfig: deprecatedScConfig, destinationPath, } = {}) => {
16
+ return async ({ scConfig } = {}) => {
17
+ const config = deprecatedScConfig !== null && deprecatedScConfig !== void 0 ? deprecatedScConfig : scConfig;
18
+ if (!config) {
19
+ throw new Error('Sitecore configuration is required to be provided');
20
+ }
21
+ let sites = [];
22
+ const sitesFilePath = path.resolve(destinationPath !== null && destinationPath !== void 0 ? destinationPath : DEFAULT_SITES_DIST_PATH);
23
+ debug.multisite(config.multisite.enabled
24
+ ? 'Multisite Enabled: Generating site information'
25
+ : 'Multisite Disabled');
26
+ if (config.multisite.enabled) {
27
+ try {
28
+ const siteInfoService = new SiteInfoService({
29
+ clientFactory: createGraphQLClientFactory({
30
+ api: config.api,
31
+ retries: config.retries.count,
32
+ retryStrategy: config.retries.retryStrategy,
33
+ }),
34
+ });
35
+ sites = await siteInfoService.fetchSiteInfo();
36
+ }
37
+ catch (error) {
38
+ console.error(chalk.red('Error fetching site information'));
39
+ throw error;
40
+ }
41
+ }
42
+ // Add default site to the list
43
+ const defaultSite = {
44
+ name: config.defaultSite,
45
+ hostName: '*',
46
+ language: config.defaultLanguage,
47
+ };
48
+ sites.unshift(defaultSite);
49
+ ensurePathExists(sitesFilePath);
50
+ fs.writeFileSync(sitesFilePath, JSON.stringify(sites, null, 2), { encoding: 'utf8' });
51
+ };
52
+ };
@@ -0,0 +1,6 @@
1
+ export { generateSites } from './generateSites';
2
+ export { scaffoldComponent } from './scaffold';
3
+ export { extractFiles } from './codegen/extract-files';
4
+ export { writeImportMap, defaultMapTemplate as defaultImportMapTemplate, } from './codegen/import-map';
5
+ export { getComponentSpec, getComponentSpecUrl } from './codegen/component-generation';
6
+ export * from './templating';
@@ -0,0 +1,54 @@
1
+ import fs from 'fs';
2
+ import chalk from 'chalk';
3
+ import path from 'path';
4
+ /**
5
+ * Force to use `crlf` line endings, we are using `crlf` across the project.
6
+ * Replace: `lf` (\n), `cr` (\r)
7
+ * @param {string} content
8
+ */
9
+ export function editLineEndings(content) {
10
+ return content.replace(/\r|\n/gm, '\r\n');
11
+ }
12
+ /**
13
+ * Creates a file relative to the specified path if the file doesn't exist.
14
+ * Creates directories as needed.
15
+ * Does not overwrite existing files.
16
+ * @param {string} filePath - the file path
17
+ * @param {string} fileContent - the file content
18
+ * @returns {string} the file path if the file was created, otherwise null
19
+ */
20
+ export function scaffoldFile(filePath, fileContent) {
21
+ const outputDir = path.dirname(filePath);
22
+ if (fs.existsSync(filePath)) {
23
+ console.log(chalk.red(`Skipping creating ${filePath}; already exists.`));
24
+ return null;
25
+ }
26
+ fs.mkdirSync(outputDir, { recursive: true });
27
+ fs.writeFileSync(filePath, editLineEndings(fileContent), 'utf8');
28
+ console.log(chalk.green(`File ${filePath} has been scaffolded.`));
29
+ return filePath;
30
+ }
31
+ /**
32
+ * Scaffolds a new component based on the provided template.
33
+ * @param {string} outputFolderPath - The file path where the component will be created.
34
+ * @param {string} componentName - The name of the component to be created.
35
+ * @param {string} templateName - The name of the template to use for scaffolding. If not provided, defaults to 'byoc' if `byoc` is true, otherwise 'default'.
36
+ * @param {ScaffoldTemplate[]} templates - An array of template objects, each containing a name, a template function, and a getNextSteps function.
37
+ * @throws Will throw an error if the specified template is not found.
38
+ * @internal
39
+ */
40
+ export function scaffoldComponent(outputFolderPath, componentName, templateName, templates) {
41
+ const template = templates.find((t) => t.name === templateName);
42
+ if (!template) {
43
+ throw new Error(`Template ${templateName} not found.`);
44
+ }
45
+ const outputFilePath = path.join(outputFolderPath, `${componentName}.${template.fileExtension}`);
46
+ const componentOutputPath = scaffoldFile(outputFilePath, template.generateTemplate(componentName));
47
+ if (componentOutputPath) {
48
+ const nextSteps = [];
49
+ nextSteps.push(chalk.green(`
50
+ Scaffolding of ${componentName} complete.
51
+ Next steps:`), ...(template.getNextSteps ? template.getNextSteps(componentOutputPath) : []));
52
+ console.log(nextSteps.join('\n'));
53
+ }
54
+ }
@@ -0,0 +1,59 @@
1
+ import * as glob from 'glob';
2
+ /**
3
+ * @public
4
+ */
5
+ export let getComponentList = _getComponentList;
6
+ export const componentUnitMocks = {
7
+ set getComponentList(mockImplementation) {
8
+ getComponentList = mockImplementation;
9
+ },
10
+ get getComponentList() {
11
+ return _getComponentList;
12
+ },
13
+ };
14
+ const componentNamePattern = /^[\/]*(.+[\/\\])*(.+)\.[jt]sx?$/;
15
+ const componentPathPattern = /^([\/]*.+[\/\\].+)\..+$/;
16
+ /**
17
+ * Get list of components from @var path
18
+ * Returns a list of components in the following format:
19
+ * {
20
+ * path: 'path/to/component',
21
+ * componentName: 'ComponentName',
22
+ * moduleName: 'ComponentName'
23
+ * }
24
+ * @param {string[]} paths paths to search
25
+ * @param {string[]} [exclude] paths and glob patterns to exclude from final result
26
+ * @param {boolean} [includeVariants] whether to include variant components
27
+ */
28
+ function _getComponentList(paths, exclude, includeVariants) {
29
+ const components = paths.reduce((result, path) => {
30
+ const globPath = glob.hasMagic(path, { magicalBraces: true }) || path.match(componentNamePattern)
31
+ ? path
32
+ : path.replace(/\/$/, '').concat('/**/*.{js,jsx,ts,tsx}');
33
+ return result.concat(...glob
34
+ .sync(globPath, { ignore: exclude, nodir: true })
35
+ .filter((path) => path.match(componentNamePattern))
36
+ .map((filePath) => {
37
+ const name = filePath.match(componentNamePattern)[2];
38
+ return {
39
+ filePath,
40
+ importPath: filePath.match(componentPathPattern)[1].replace(/\\/g, '/'), // use forward slashes for consistency
41
+ componentName: name,
42
+ moduleName: name.replace(/[^\w]+/g, ''),
43
+ };
44
+ }));
45
+ }, []);
46
+ return includeVariants
47
+ ? components
48
+ : components.filter((component) => !component.componentName.includes('.'));
49
+ }
50
+ /**
51
+ * Filters components by their detected type.
52
+ * @param {ComponentFileWithType[]} components - Array of components with types
53
+ * @param {ComponentType[]} allowedTypes - Array of allowed component types to filter by
54
+ * @returns {ComponentFileWithType[]} Filtered array containing only components matching allowed types
55
+ * @internal
56
+ */
57
+ export function filterComponentsByType(components, allowedTypes) {
58
+ return components.filter((component) => allowedTypes.includes(component.componentType));
59
+ }
@@ -0,0 +1 @@
1
+ export { getComponentList, filterComponentsByType, } from './components';
package/editing.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './types/editing/index';
package/i18n.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './types/i18n/index';
package/layout.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './types/layout/index';
package/media.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './types/media/index';