Skip to content

Commit d0160c5

Browse files
committed
fix: exclude credential file from zip for external-callout
1 parent 4d4fcdb commit d0160c5

2 files changed

Lines changed: 9 additions & 3 deletions

File tree

src/utils/zipBuilder.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2929
const messages = Messages.loadMessages('@salesforce/plugin-data-code-extension', 'datacodeBinaryExecutor');
3030

3131
export const ZIP_FILE_NAME = 'deployment.zip';
32+
export const EXTERNAL_CALLOUT_CREDENTIAL = 'external_callout_config.json';
33+
const EXCLUDED_FILENAMES = new Set(['.DS_Store', EXTERNAL_CALLOUT_CREDENTIAL]);
3234
export const DEPENDENCIES_ARCHIVE_NAME = 'native_dependencies';
3335
export const DEPENDENCIES_ARCHIVE_FULL_NAME = `${DEPENDENCIES_ARCHIVE_NAME}.tar.gz`;
3436
export const DEPENDENCIES_ARCHIVE_PATH = path.join('payload', 'archives', DEPENDENCIES_ARCHIVE_FULL_NAME);
@@ -248,6 +250,7 @@ export async function prepareDependencyArchive(
248250

249251
async function collectFiles(directory: string): Promise<string[]> {
250252
// Match Python `os.walk(path)` (default `followlinks=False`) + `zipfile.write`:
253+
// - Files in EXCLUDED_FILENAMES (.DS_Store, external_callout_config.json) are skipped.
251254
// - Real subdirectories are recursed.
252255
// - Directory symlinks are NOT recursed (Python `is_dir(follow_symlinks=False)` is False).
253256
// - Regular files and file symlinks are both included; their contents are read
@@ -258,7 +261,7 @@ async function collectFiles(directory: string): Promise<string[]> {
258261
const nested = await Promise.all(
259262
entries.map(async (entry) => {
260263
const full = path.join(current, entry.name);
261-
if (entry.name === '.DS_Store') {
264+
if (EXCLUDED_FILENAMES.has(entry.name)) {
262265
return [];
263266
}
264267
if (entry.isDirectory()) {
@@ -290,7 +293,8 @@ async function collectFiles(directory: string): Promise<string[]> {
290293

291294
/**
292295
* Creates `deployment.zip` (DEFLATE-compressed) at the current working
293-
* directory containing every file under `directory` except `.DS_Store`.
296+
* directory containing every file under `directory` except those in
297+
* EXCLUDED_FILENAMES (`.DS_Store` and the local `external_callout_config.json`).
294298
* Archive entry names are relative to `directory`, matching the Python
295299
* `os.path.relpath(abs_path, directory)` behavior.
296300
*/

test/utils/zipBuilder.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,14 @@ describe('zipBuilder.createZip', () => {
133133
rmSync(tempDir, { recursive: true, force: true });
134134
});
135135

136-
it('creates deployment.zip with all non-DS_Store files at relative paths', async () => {
136+
it('creates deployment.zip excluding .DS_Store and external_callout_config.json', async () => {
137137
const payload = path.join(tempDir, 'payload');
138138
mkdirSync(path.join(payload, 'sub'), { recursive: true });
139139
writeFileSync(path.join(payload, 'a.py'), 'print(1)');
140140
writeFileSync(path.join(payload, 'sub', 'b.py'), 'print(2)');
141141
writeFileSync(path.join(payload, '.DS_Store'), 'junk');
142+
// Local-only credentials must never be packaged into the deployment archive.
143+
writeFileSync(path.join(payload, 'external_callout_config.json'), '{"secret":"key"}');
142144

143145
const result = await createZip('payload');
144146

0 commit comments

Comments
 (0)