@salesforce/b2c-tooling-sdk 1.3.2 → 1.5.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.
Files changed (109) hide show
  1. package/data/xsd/abtest.xsd +14 -1
  2. package/data/xsd/bmext.xsd +18 -0
  3. package/data/xsd/commercefeaturestate.xsd +101 -0
  4. package/data/xsd/index.json +10 -2
  5. package/data/xsd/library.xsd +33 -0
  6. package/data/xsd/order.xsd +2 -0
  7. package/data/xsd/pagemetatag.xsd +1 -0
  8. package/data/xsd/search2.xsd +39 -0
  9. package/data/xsd/sort.xsd +31 -1
  10. package/data/xsd/storefronts.xsd +104 -0
  11. package/dist/cjs/cli/lifecycle.d.ts +1 -1
  12. package/dist/cjs/cli/lifecycle.js.map +1 -1
  13. package/dist/cjs/index.d.ts +2 -0
  14. package/dist/cjs/index.js +2 -0
  15. package/dist/cjs/index.js.map +1 -1
  16. package/dist/cjs/operations/cap/index.d.ts +56 -0
  17. package/dist/cjs/operations/cap/index.js +57 -0
  18. package/dist/cjs/operations/cap/index.js.map +1 -0
  19. package/dist/cjs/operations/cap/install.d.ts +53 -0
  20. package/dist/cjs/operations/cap/install.js +181 -0
  21. package/dist/cjs/operations/cap/install.js.map +1 -0
  22. package/dist/cjs/operations/cap/list.d.ts +92 -0
  23. package/dist/cjs/operations/cap/list.js +230 -0
  24. package/dist/cjs/operations/cap/list.js.map +1 -0
  25. package/dist/cjs/operations/cap/package.d.ts +39 -0
  26. package/dist/cjs/operations/cap/package.js +77 -0
  27. package/dist/cjs/operations/cap/package.js.map +1 -0
  28. package/dist/cjs/operations/cap/pull.d.ts +21 -0
  29. package/dist/cjs/operations/cap/pull.js +77 -0
  30. package/dist/cjs/operations/cap/pull.js.map +1 -0
  31. package/dist/cjs/operations/cap/uninstall.d.ts +46 -0
  32. package/dist/cjs/operations/cap/uninstall.js +87 -0
  33. package/dist/cjs/operations/cap/uninstall.js.map +1 -0
  34. package/dist/cjs/operations/cap/validate.d.ts +47 -0
  35. package/dist/cjs/operations/cap/validate.js +235 -0
  36. package/dist/cjs/operations/cap/validate.js.map +1 -0
  37. package/dist/cjs/operations/code/deploy.d.ts +17 -1
  38. package/dist/cjs/operations/code/deploy.js +21 -2
  39. package/dist/cjs/operations/code/deploy.js.map +1 -1
  40. package/dist/cjs/operations/code/download.d.ts +66 -0
  41. package/dist/cjs/operations/code/download.js +180 -0
  42. package/dist/cjs/operations/code/download.js.map +1 -0
  43. package/dist/cjs/operations/code/index.d.ts +7 -1
  44. package/dist/cjs/operations/code/index.js +6 -0
  45. package/dist/cjs/operations/code/index.js.map +1 -1
  46. package/dist/cjs/operations/jobs/site-archive.d.ts +1 -0
  47. package/dist/cjs/operations/jobs/site-archive.js +30 -39
  48. package/dist/cjs/operations/jobs/site-archive.js.map +1 -1
  49. package/dist/cjs/operations/util/zip.d.ts +5 -0
  50. package/dist/cjs/operations/util/zip.js +25 -0
  51. package/dist/cjs/operations/util/zip.js.map +1 -0
  52. package/dist/cjs/plugins/loader.js +6 -1
  53. package/dist/cjs/plugins/loader.js.map +1 -1
  54. package/dist/cjs/skills/github.js +143 -49
  55. package/dist/cjs/skills/github.js.map +1 -1
  56. package/dist/cjs/skills/installer.d.ts +1 -0
  57. package/dist/cjs/skills/installer.js.map +1 -1
  58. package/dist/cjs/telemetry/index.d.ts +8 -0
  59. package/dist/cjs/telemetry/index.js.map +1 -1
  60. package/dist/esm/cli/lifecycle.d.ts +1 -1
  61. package/dist/esm/cli/lifecycle.js.map +1 -1
  62. package/dist/esm/index.d.ts +2 -0
  63. package/dist/esm/index.js +2 -0
  64. package/dist/esm/index.js.map +1 -1
  65. package/dist/esm/operations/cap/index.d.ts +56 -0
  66. package/dist/esm/operations/cap/index.js +57 -0
  67. package/dist/esm/operations/cap/index.js.map +1 -0
  68. package/dist/esm/operations/cap/install.d.ts +53 -0
  69. package/dist/esm/operations/cap/install.js +183 -0
  70. package/dist/esm/operations/cap/install.js.map +1 -0
  71. package/dist/esm/operations/cap/list.d.ts +92 -0
  72. package/dist/esm/operations/cap/list.js +231 -0
  73. package/dist/esm/operations/cap/list.js.map +1 -0
  74. package/dist/esm/operations/cap/package.d.ts +39 -0
  75. package/dist/esm/operations/cap/package.js +78 -0
  76. package/dist/esm/operations/cap/package.js.map +1 -0
  77. package/dist/esm/operations/cap/pull.d.ts +21 -0
  78. package/dist/esm/operations/cap/pull.js +78 -0
  79. package/dist/esm/operations/cap/pull.js.map +1 -0
  80. package/dist/esm/operations/cap/uninstall.d.ts +46 -0
  81. package/dist/esm/operations/cap/uninstall.js +98 -0
  82. package/dist/esm/operations/cap/uninstall.js.map +1 -0
  83. package/dist/esm/operations/cap/validate.d.ts +47 -0
  84. package/dist/esm/operations/cap/validate.js +235 -0
  85. package/dist/esm/operations/cap/validate.js.map +1 -0
  86. package/dist/esm/operations/code/deploy.d.ts +17 -1
  87. package/dist/esm/operations/code/deploy.js +21 -2
  88. package/dist/esm/operations/code/deploy.js.map +1 -1
  89. package/dist/esm/operations/code/download.d.ts +66 -0
  90. package/dist/esm/operations/code/download.js +180 -0
  91. package/dist/esm/operations/code/download.js.map +1 -0
  92. package/dist/esm/operations/code/index.d.ts +7 -1
  93. package/dist/esm/operations/code/index.js +6 -0
  94. package/dist/esm/operations/code/index.js.map +1 -1
  95. package/dist/esm/operations/jobs/site-archive.d.ts +1 -0
  96. package/dist/esm/operations/jobs/site-archive.js +30 -39
  97. package/dist/esm/operations/jobs/site-archive.js.map +1 -1
  98. package/dist/esm/operations/util/zip.d.ts +5 -0
  99. package/dist/esm/operations/util/zip.js +26 -0
  100. package/dist/esm/operations/util/zip.js.map +1 -0
  101. package/dist/esm/plugins/loader.js +6 -1
  102. package/dist/esm/plugins/loader.js.map +1 -1
  103. package/dist/esm/skills/github.js +143 -49
  104. package/dist/esm/skills/github.js.map +1 -1
  105. package/dist/esm/skills/installer.d.ts +1 -0
  106. package/dist/esm/skills/installer.js.map +1 -1
  107. package/dist/esm/telemetry/index.d.ts +8 -0
  108. package/dist/esm/telemetry/index.js.map +1 -1
  109. package/package.json +11 -1
@@ -0,0 +1,53 @@
1
+ import { B2CInstance } from '../../instance/index.js';
2
+ import { type JobExecution, type WaitForJobOptions } from '../jobs/run.js';
3
+ import { type CommerceAppManifest } from './validate.js';
4
+ /**
5
+ * Options for CAP installation.
6
+ */
7
+ export interface CommerceAppInstallOptions {
8
+ /** Target site ID to install the app on. */
9
+ siteId: string;
10
+ /** Keep the uploaded zip on the instance after install (default: false). */
11
+ keepArchive?: boolean;
12
+ /** Wait options for job completion. */
13
+ waitOptions?: WaitForJobOptions;
14
+ }
15
+ /**
16
+ * Result of a CAP installation.
17
+ */
18
+ export interface CommerceAppInstallResult {
19
+ /** Job execution details. */
20
+ execution: JobExecution;
21
+ /** App name (id from commerce-app.json). */
22
+ appName: string;
23
+ /** App version. */
24
+ appVersion: string;
25
+ /** Uploaded archive filename. */
26
+ archiveFilename: string;
27
+ /** Whether the archive was kept on the instance. */
28
+ archiveKept: boolean;
29
+ }
30
+ /**
31
+ * Installs a Commerce App Package (CAP) on a B2C Commerce instance.
32
+ *
33
+ * Accepts a local directory or zip file. Reads the commerce-app.json manifest
34
+ * to determine app name, version, and domain. Uploads the zip to WebDAV and
35
+ * executes the sfcc-install-commerce-app system job.
36
+ *
37
+ * @param instance - B2C instance to install to
38
+ * @param target - Path to a CAP directory or .zip file
39
+ * @param options - Install options including required siteId
40
+ * @returns Install result with job execution details
41
+ * @throws JobExecutionError if the install job fails
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const result = await commerceAppInstall(instance, './commerce-avalara-tax-app-v0.2.5', {
46
+ * siteId: 'RefArch',
47
+ * });
48
+ * ```
49
+ */
50
+ export declare function commerceAppInstall(instance: B2CInstance, target: string, options: CommerceAppInstallOptions): Promise<CommerceAppInstallResult>;
51
+ export declare function readManifest(capDir: string): CommerceAppManifest;
52
+ /** Prefix site ID with "Sites-" if not already present. */
53
+ export declare function normalizeSiteId(siteId: string): string;
@@ -0,0 +1,183 @@
1
+ /*
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * SPDX-License-Identifier: Apache-2
4
+ * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5
+ */
6
+ /**
7
+ * Commerce App Package (CAP) installation.
8
+ *
9
+ * Uploads a CAP to WebDAV and runs the sfcc-install-commerce-app system job.
10
+ */
11
+ import * as fs from 'node:fs';
12
+ import * as path from 'node:path';
13
+ import JSZip from 'jszip';
14
+ import { B2CInstance } from '../../instance/index.js';
15
+ import { getLogger } from '../../logging/logger.js';
16
+ import { waitForJob, JobExecutionError, getJobLog } from '../jobs/run.js';
17
+ import { addDirectoryToZip } from '../util/zip.js';
18
+ import {} from './validate.js';
19
+ const INSTALL_JOB_ID = 'sfcc-install-commerce-app';
20
+ /**
21
+ * Installs a Commerce App Package (CAP) on a B2C Commerce instance.
22
+ *
23
+ * Accepts a local directory or zip file. Reads the commerce-app.json manifest
24
+ * to determine app name, version, and domain. Uploads the zip to WebDAV and
25
+ * executes the sfcc-install-commerce-app system job.
26
+ *
27
+ * @param instance - B2C instance to install to
28
+ * @param target - Path to a CAP directory or .zip file
29
+ * @param options - Install options including required siteId
30
+ * @returns Install result with job execution details
31
+ * @throws JobExecutionError if the install job fails
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const result = await commerceAppInstall(instance, './commerce-avalara-tax-app-v0.2.5', {
36
+ * siteId: 'RefArch',
37
+ * });
38
+ * ```
39
+ */
40
+ export async function commerceAppInstall(instance, target, options) {
41
+ const logger = getLogger();
42
+ const { siteId: rawSiteId, keepArchive = false, waitOptions } = options;
43
+ const siteId = normalizeSiteId(rawSiteId);
44
+ if (!fs.existsSync(target)) {
45
+ throw new Error(`Target not found: ${target}`);
46
+ }
47
+ const stat = fs.statSync(target);
48
+ let archiveContent;
49
+ let archiveFilename;
50
+ let manifest;
51
+ if (stat.isDirectory()) {
52
+ manifest = readManifest(target);
53
+ archiveFilename = `${manifest.id}-v${manifest.version}.zip`;
54
+ logger.debug({ path: target }, `Packaging CAP directory: ${target}`);
55
+ archiveContent = await createArchiveFromDirectory(target, `${manifest.id}-v${manifest.version}`);
56
+ }
57
+ else if (stat.isFile() && target.endsWith('.zip')) {
58
+ manifest = await readManifestFromZip(target);
59
+ archiveFilename = path.basename(target);
60
+ archiveContent = await fs.promises.readFile(target);
61
+ }
62
+ else {
63
+ throw new Error(`Target must be a directory or .zip file: ${target}`);
64
+ }
65
+ const uploadDir = 'Impex/commerce-apps';
66
+ const webdavUploadPath = `${uploadDir}/${archiveFilename}`;
67
+ const appPath = `webdav/Sites/${webdavUploadPath}`;
68
+ logger.debug({ path: webdavUploadPath }, `Uploading CAP to ${webdavUploadPath}`);
69
+ await instance.webdav.mkcol(uploadDir);
70
+ await instance.webdav.put(webdavUploadPath, archiveContent, 'application/zip');
71
+ logger.debug({ path: webdavUploadPath }, `CAP uploaded: ${webdavUploadPath}`);
72
+ // Execute the install job
73
+ logger.debug({ jobId: INSTALL_JOB_ID, appName: manifest.id, siteId }, `Executing ${INSTALL_JOB_ID} job`);
74
+ let execution;
75
+ // Try direct body format first (standard OCAPI format)
76
+ const { data, error } = await instance.ocapi.POST('/jobs/{job_id}/executions', {
77
+ params: { path: { job_id: INSTALL_JOB_ID } },
78
+ body: {
79
+ app_name: manifest.id,
80
+ app_source: 'WebDAV',
81
+ app_domain: manifest.domain,
82
+ site_id: siteId,
83
+ app_path: appPath,
84
+ },
85
+ });
86
+ if (error?.fault?.type === 'UnknownPropertyException' &&
87
+ error.fault.arguments?.document === 'job_execution_request') {
88
+ // Retry with parameters format (internal/support users)
89
+ logger.warn('Retrying with parameters format for internal users');
90
+ const { data: retryData, error: retryError } = await instance.ocapi.POST('/jobs/{job_id}/executions', {
91
+ params: { path: { job_id: INSTALL_JOB_ID } },
92
+ body: {
93
+ parameters: [
94
+ { name: 'AppName', value: manifest.id },
95
+ { name: 'AppSource', value: 'WebDAV' },
96
+ { name: 'AppDomain', value: manifest.domain },
97
+ { name: 'SiteId', value: siteId },
98
+ { name: 'AppPath', value: appPath },
99
+ ],
100
+ },
101
+ });
102
+ if (retryError || !retryData) {
103
+ throw new Error(retryError?.fault?.message ?? 'Failed to start install job');
104
+ }
105
+ execution = retryData;
106
+ }
107
+ else if (error || !data) {
108
+ throw new Error(error?.fault?.message ?? 'Failed to start install job');
109
+ }
110
+ else {
111
+ execution = data;
112
+ }
113
+ logger.debug({ jobId: INSTALL_JOB_ID, executionId: execution.id }, `Install job started: ${execution.id}`);
114
+ // Wait for job completion
115
+ let finalExecution;
116
+ try {
117
+ finalExecution = await waitForJob(instance, INSTALL_JOB_ID, execution.id, waitOptions);
118
+ }
119
+ catch (err) {
120
+ if (err instanceof JobExecutionError) {
121
+ try {
122
+ const log = await getJobLog(instance, err.execution);
123
+ logger.error({ jobId: INSTALL_JOB_ID, log }, `Job log:\n${log}`);
124
+ }
125
+ catch {
126
+ logger.error({ jobId: INSTALL_JOB_ID }, 'Could not retrieve job log');
127
+ }
128
+ }
129
+ throw err;
130
+ }
131
+ // Clean up archive unless keeping
132
+ if (!keepArchive) {
133
+ await instance.webdav.delete(webdavUploadPath);
134
+ logger.debug({ path: webdavUploadPath }, `Archive deleted: ${webdavUploadPath}`);
135
+ }
136
+ return {
137
+ execution: finalExecution,
138
+ appName: manifest.id,
139
+ appVersion: manifest.version,
140
+ archiveFilename,
141
+ archiveKept: keepArchive,
142
+ };
143
+ }
144
+ export function readManifest(capDir) {
145
+ const manifestPath = path.join(capDir, 'commerce-app.json');
146
+ if (!fs.existsSync(manifestPath)) {
147
+ throw new Error(`commerce-app.json not found in: ${capDir}`);
148
+ }
149
+ try {
150
+ return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
151
+ }
152
+ catch {
153
+ throw new Error(`Failed to parse commerce-app.json in: ${capDir}`);
154
+ }
155
+ }
156
+ async function readManifestFromZip(zipPath) {
157
+ const data = await fs.promises.readFile(zipPath);
158
+ const zip = await JSZip.loadAsync(data);
159
+ // Find commerce-app.json at root or one level deep
160
+ for (const [filePath, entry] of Object.entries(zip.files)) {
161
+ if (!entry.dir && (filePath === 'commerce-app.json' || filePath.match(/^[^/]+\/commerce-app\.json$/))) {
162
+ try {
163
+ const content = await entry.async('string');
164
+ return JSON.parse(content);
165
+ }
166
+ catch {
167
+ throw new Error('Failed to parse commerce-app.json from zip');
168
+ }
169
+ }
170
+ }
171
+ throw new Error('commerce-app.json not found in zip');
172
+ }
173
+ /** Prefix site ID with "Sites-" if not already present. */
174
+ export function normalizeSiteId(siteId) {
175
+ return siteId.startsWith('Sites-') ? siteId : `Sites-${siteId}`;
176
+ }
177
+ async function createArchiveFromDirectory(dirPath, archiveDirName) {
178
+ const zip = new JSZip();
179
+ const rootFolder = zip.folder(archiveDirName);
180
+ await addDirectoryToZip(rootFolder, dirPath);
181
+ return zip.generateAsync({ type: 'nodebuffer', compression: 'DEFLATE', compressionOptions: { level: 9 } });
182
+ }
183
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../../src/operations/cap/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { B2CInstance } from '../../instance/index.js';
2
+ import type { JobExecution, WaitForJobOptions } from '../jobs/run.js';
3
+ import type { CommerceAppManifest } from './validate.js';
4
+ /**
5
+ * A commerce feature state parsed from the commerce-feature-states.xml export.
6
+ */
7
+ export interface CommerceFeatureState {
8
+ siteId: string;
9
+ featureName: string;
10
+ featureType: string;
11
+ featureSource: string;
12
+ featureDomain: string;
13
+ installStatus: string;
14
+ configStatus: string;
15
+ featureVersionId: string;
16
+ installedAt: string;
17
+ configTasks?: unknown[];
18
+ installationMetadata?: unknown;
19
+ }
20
+ /**
21
+ * A locally discovered Commerce App Package.
22
+ */
23
+ export interface LocalCommerceApp {
24
+ /** Absolute path to the directory containing commerce-app.json. */
25
+ path: string;
26
+ /** Parsed manifest from commerce-app.json. */
27
+ manifest: CommerceAppManifest;
28
+ }
29
+ /**
30
+ * Options for listing installed apps on an instance.
31
+ */
32
+ export interface ListInstalledAppsOptions {
33
+ /** Specific site IDs to query. If omitted, discovers all sites via OCAPI. */
34
+ sites?: string[];
35
+ /** Wait options for the export job. */
36
+ waitOptions?: WaitForJobOptions;
37
+ }
38
+ /**
39
+ * Result of listing installed apps on an instance.
40
+ */
41
+ export interface ListInstalledAppsResult {
42
+ /** Parsed commerce feature states from all queried sites. */
43
+ features: CommerceFeatureState[];
44
+ /** Job execution details. */
45
+ execution: JobExecution;
46
+ }
47
+ /**
48
+ * Discovers local Commerce App Packages by searching for commerce-app.json files.
49
+ *
50
+ * Walks the directory tree starting from `searchPath`, finds directories
51
+ * containing a `commerce-app.json` file, and reads each manifest.
52
+ *
53
+ * @param searchPath - Root directory to search
54
+ * @returns Array of discovered local apps with their paths and manifests
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const apps = await discoverLocalApps('./my-workspace');
59
+ * for (const app of apps) {
60
+ * console.log(`${app.manifest.id}@${app.manifest.version} at ${app.path}`);
61
+ * }
62
+ * ```
63
+ */
64
+ export declare function discoverLocalApps(searchPath: string): Promise<LocalCommerceApp[]>;
65
+ /**
66
+ * Lists installed Commerce Apps on a B2C instance by exporting commerce feature states.
67
+ *
68
+ * Attempts to export the `commerce_feature_states` data unit for each site.
69
+ * If the export fails (e.g. because the data unit is not yet supported on the server),
70
+ * falls back to a bundled stub fixture.
71
+ *
72
+ * @param instance - B2C instance to query
73
+ * @param options - Options including optional site filter and wait options
74
+ * @returns List of commerce feature states across all queried sites
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const result = await listInstalledApps(instance);
79
+ * for (const state of result.features) {
80
+ * console.log(`${state.featureName} (${state.installStatus}) on ${state.siteId}`);
81
+ * }
82
+ * ```
83
+ */
84
+ export declare function listInstalledApps(instance: B2CInstance, options?: ListInstalledAppsOptions): Promise<ListInstalledAppsResult>;
85
+ /**
86
+ * Parses a commerce-feature-states.xml string into CommerceFeatureState objects.
87
+ *
88
+ * @param xml - XML string to parse
89
+ * @param siteId - Site ID to associate with parsed states (used as fallback if not in XML attributes)
90
+ * @returns Array of parsed commerce feature states
91
+ */
92
+ export declare function parseCommerceFeatureStatesXml(xml: string, siteId: string): Promise<CommerceFeatureState[]>;
@@ -0,0 +1,231 @@
1
+ /*
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * SPDX-License-Identifier: Apache-2
4
+ * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5
+ */
6
+ /**
7
+ * Commerce App listing operations.
8
+ *
9
+ * Provides functions for discovering local Commerce App Packages and listing
10
+ * installed apps on a B2C Commerce instance via site archive export.
11
+ */
12
+ import * as fs from 'node:fs';
13
+ import * as path from 'node:path';
14
+ import JSZip from 'jszip';
15
+ import * as xml2js from 'xml2js';
16
+ import { B2CInstance } from '../../instance/index.js';
17
+ import { getLogger } from '../../logging/logger.js';
18
+ import { siteArchiveExportToBuffer } from '../jobs/site-archive.js';
19
+ import { readManifest } from './install.js';
20
+ /**
21
+ * Discovers local Commerce App Packages by searching for commerce-app.json files.
22
+ *
23
+ * Walks the directory tree starting from `searchPath`, finds directories
24
+ * containing a `commerce-app.json` file, and reads each manifest.
25
+ *
26
+ * @param searchPath - Root directory to search
27
+ * @returns Array of discovered local apps with their paths and manifests
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const apps = await discoverLocalApps('./my-workspace');
32
+ * for (const app of apps) {
33
+ * console.log(`${app.manifest.id}@${app.manifest.version} at ${app.path}`);
34
+ * }
35
+ * ```
36
+ */
37
+ export async function discoverLocalApps(searchPath) {
38
+ const logger = getLogger();
39
+ const apps = [];
40
+ const resolvedPath = path.resolve(searchPath);
41
+ if (!fs.existsSync(resolvedPath)) {
42
+ return apps;
43
+ }
44
+ logger.debug({ searchPath: resolvedPath }, `Discovering local CAPs in: ${resolvedPath}`);
45
+ findCommerceApps(resolvedPath, apps, logger);
46
+ logger.debug({ count: apps.length }, `Found ${apps.length} local CAP(s)`);
47
+ return apps;
48
+ }
49
+ /**
50
+ * Recursively finds directories containing commerce-app.json.
51
+ * Stops descending into a directory once a commerce-app.json is found there.
52
+ */
53
+ function findCommerceApps(dir, apps, logger) {
54
+ let entries;
55
+ try {
56
+ entries = fs.readdirSync(dir, { withFileTypes: true });
57
+ }
58
+ catch {
59
+ return;
60
+ }
61
+ const manifestPath = path.join(dir, 'commerce-app.json');
62
+ if (fs.existsSync(manifestPath)) {
63
+ try {
64
+ const manifest = readManifest(dir);
65
+ apps.push({ path: dir, manifest });
66
+ }
67
+ catch (err) {
68
+ logger.warn({ path: manifestPath, error: err }, `Skipping invalid commerce-app.json: ${manifestPath}`);
69
+ }
70
+ // Don't recurse into CAP directories
71
+ return;
72
+ }
73
+ for (const entry of entries) {
74
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
75
+ findCommerceApps(path.join(dir, entry.name), apps, logger);
76
+ }
77
+ }
78
+ }
79
+ /**
80
+ * Lists installed Commerce Apps on a B2C instance by exporting commerce feature states.
81
+ *
82
+ * Attempts to export the `commerce_feature_states` data unit for each site.
83
+ * If the export fails (e.g. because the data unit is not yet supported on the server),
84
+ * falls back to a bundled stub fixture.
85
+ *
86
+ * @param instance - B2C instance to query
87
+ * @param options - Options including optional site filter and wait options
88
+ * @returns List of commerce feature states across all queried sites
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const result = await listInstalledApps(instance);
93
+ * for (const state of result.features) {
94
+ * console.log(`${state.featureName} (${state.installStatus}) on ${state.siteId}`);
95
+ * }
96
+ * ```
97
+ */
98
+ export async function listInstalledApps(instance, options = {}) {
99
+ const logger = getLogger();
100
+ const { waitOptions } = options;
101
+ // Determine which sites to query
102
+ let siteIds;
103
+ if (options.sites && options.sites.length > 0) {
104
+ siteIds = options.sites;
105
+ }
106
+ else {
107
+ logger.debug('No sites specified, discovering all sites via OCAPI');
108
+ const { data, error } = await instance.ocapi.GET('/sites', {
109
+ params: { query: { select: '(**)' } },
110
+ });
111
+ if (error || !data) {
112
+ throw new Error(error?.fault?.message ?? 'Failed to list sites');
113
+ }
114
+ siteIds = (data.data ?? []).map((s) => s.id).filter((id) => !!id);
115
+ logger.debug({ siteIds }, `Discovered ${siteIds.length} site(s)`);
116
+ }
117
+ if (siteIds.length === 0) {
118
+ return { features: [], execution: undefined };
119
+ }
120
+ // Build export configuration for all sites with commerce_feature_states
121
+ const sitesConfig = {};
122
+ for (const siteId of siteIds) {
123
+ sitesConfig[siteId] = { commerce_feature_states: true };
124
+ }
125
+ logger.debug({ siteIds }, 'Exporting commerce_feature_states');
126
+ const exportResult = await siteArchiveExportToBuffer(instance, { sites: sitesConfig }, { waitOptions });
127
+ const states = await parseExportArchive(exportResult.data);
128
+ return { features: states, execution: exportResult.execution };
129
+ }
130
+ /**
131
+ * Parses a site archive export zip for commerce-feature-states.xml files.
132
+ */
133
+ async function parseExportArchive(data) {
134
+ const logger = getLogger();
135
+ const zip = await JSZip.loadAsync(data);
136
+ const states = [];
137
+ const filePaths = Object.keys(zip.files).filter((p) => !zip.files[p].dir);
138
+ logger.debug({ filePaths }, `Export archive contains ${filePaths.length} file(s)`);
139
+ for (const [filePath, entry] of Object.entries(zip.files)) {
140
+ if (entry.dir)
141
+ continue;
142
+ const match = filePath.match(/sites\/([^/]+)\/commerce-feature-states\.xml$/);
143
+ if (match) {
144
+ const siteId = match[1];
145
+ const xml = await entry.async('string');
146
+ const parsed = await parseCommerceFeatureStatesXml(xml, siteId);
147
+ states.push(...parsed);
148
+ }
149
+ }
150
+ return states;
151
+ }
152
+ /**
153
+ * Parses a commerce-feature-states.xml string into CommerceFeatureState objects.
154
+ *
155
+ * @param xml - XML string to parse
156
+ * @param siteId - Site ID to associate with parsed states (used as fallback if not in XML attributes)
157
+ * @returns Array of parsed commerce feature states
158
+ */
159
+ export async function parseCommerceFeatureStatesXml(xml, siteId) {
160
+ const parsed = await xml2js.parseStringPromise(xml, {
161
+ explicitArray: false,
162
+ tagNameProcessors: [(name) => name.replace(/^[^:]+:/, '')],
163
+ });
164
+ if (!parsed)
165
+ return [];
166
+ const root = parsed['commerce-feature-states'];
167
+ if (!root)
168
+ return [];
169
+ let entries = root['commerce-feature-state'];
170
+ if (!entries)
171
+ return [];
172
+ // Normalize to array (xml2js uses single object when there's only one element)
173
+ if (!Array.isArray(entries)) {
174
+ entries = [entries];
175
+ }
176
+ return entries.map((entry) => {
177
+ const attrs = (entry['$'] ?? {});
178
+ // Parse config-tasks as JSON if present
179
+ let configTasks;
180
+ if (typeof entry['config-tasks'] === 'string') {
181
+ try {
182
+ configTasks = JSON.parse(entry['config-tasks']);
183
+ }
184
+ catch {
185
+ // Leave as undefined if not valid JSON
186
+ }
187
+ }
188
+ // Parse installation-metadata as JSON if present
189
+ let installationMetadata;
190
+ if (typeof entry['installation-metadata'] === 'string') {
191
+ try {
192
+ const parsed = JSON.parse(entry['installation-metadata']);
193
+ if (typeof parsed.impexUninstallData === 'string') {
194
+ try {
195
+ parsed.impexUninstallData = JSON.parse(parsed.impexUninstallData);
196
+ }
197
+ catch {
198
+ // leave as string
199
+ }
200
+ }
201
+ installationMetadata = parsed;
202
+ }
203
+ catch {
204
+ // Leave as undefined if not valid JSON
205
+ }
206
+ }
207
+ return {
208
+ siteId: attrs['site-id'] || siteId,
209
+ featureName: attrs['feature-name'] || '',
210
+ featureType: getTextValue(entry['feature-type']),
211
+ featureSource: getTextValue(entry['feature-source']),
212
+ featureDomain: getTextValue(entry['feature-domain']),
213
+ installStatus: getTextValue(entry['install-status']),
214
+ configStatus: getTextValue(entry['config-status']),
215
+ featureVersionId: getTextValue(entry['feature-version-id']),
216
+ installedAt: getTextValue(entry['installed-at']),
217
+ configTasks,
218
+ installationMetadata,
219
+ };
220
+ });
221
+ }
222
+ /** Extract text value from xml2js parsed element (may be string or object with _). */
223
+ function getTextValue(value) {
224
+ if (typeof value === 'string')
225
+ return value;
226
+ if (value && typeof value === 'object' && '_' in value) {
227
+ return String(value['_']);
228
+ }
229
+ return '';
230
+ }
231
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/operations/cap/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type CommerceAppManifest } from './validate.js';
2
+ /**
3
+ * Options for CAP packaging.
4
+ */
5
+ export interface CommerceAppPackageOptions {
6
+ /**
7
+ * Output path for the zip file.
8
+ * - If a directory: zip is written to `{outputPath}/{id}-v{version}.zip`
9
+ * - If a .zip path: written to that exact location
10
+ * - Default: current working directory
11
+ */
12
+ outputPath?: string;
13
+ }
14
+ /**
15
+ * Result of CAP packaging.
16
+ */
17
+ export interface CommerceAppPackageResult {
18
+ /** Absolute path to the produced zip file. */
19
+ outputPath: string;
20
+ /** Parsed manifest. */
21
+ manifest: CommerceAppManifest;
22
+ }
23
+ /**
24
+ * Packages a CAP directory into a distributable .zip file.
25
+ *
26
+ * The zip root directory is named `{id}-v{version}/` as required by the CAP spec.
27
+ * Reads commerce-app.json to determine the app name and version.
28
+ *
29
+ * @param sourceDir - Path to the CAP directory
30
+ * @param options - Packaging options
31
+ * @returns Result with the output zip path and manifest
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const result = await commerceAppPackage('./commerce-avalara-tax-app-v0.2.5');
36
+ * console.log(`Packaged to: ${result.outputPath}`);
37
+ * ```
38
+ */
39
+ export declare function commerceAppPackage(sourceDir: string, options?: CommerceAppPackageOptions): Promise<CommerceAppPackageResult>;