Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 13, 2025

  • Explore repository structure and understand the codebase
  • Run initial tests to establish baseline
  • Modify the _headers method to support upload-specific headers
  • Update uploadExisting method to include the new headers
  • Extract filename from the stream/path when applicable
  • Add tests to verify headers are correctly set
  • Run tests and verify all pass
  • Validate the changes work correctly
  • Simplify filename detection logic based on reviewer feedback
  • Restore original readStream assignment pattern

Summary of Changes

Added support for Google upload protocol headers in the uploadExisting method:

  1. New _uploadHeaders method: Creates upload-specific headers that include:

    • X-Goog-Upload-Protocol: raw
    • X-Goog-Upload-File-Name: <filename>
  2. Simplified filename detection:

    • For .crx file uploads: Uses extension.crx
    • For all other uploads (directories, .zip files, streams): Uses extension.zip
  3. Preserved original code structure:

    • Kept the getStreamFromPath helper function
    • Maintained the clean ternary operator pattern for readStream assignment
  4. Added comprehensive tests to verify:

    • The protocol header is set correctly
    • The filename header is set correctly for all input types (file, directory, stream)

All existing tests continue to pass, ensuring backward compatibility.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] Add necessary headers for Google upload protocol Add X-Goog-Upload headers to Chrome Web Store upload requests Oct 13, 2025
Copilot AI requested a review from fregante October 13, 2025 09:04
Copilot finished work on behalf of fregante October 13, 2025 09:04
@fregante fregante changed the title Add X-Goog-Upload headers to Chrome Web Store upload requests Fix support fo CRX uploads Oct 13, 2025
@fregante fregante marked this pull request as ready for review October 13, 2025 12:11
@fregante
Copy link
Owner

@J3ekir

Copy link
Contributor Author

Copilot AI commented Oct 13, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.googleapis.com
    • Triggering command: node (vitest 2) (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Fix support fo CRX uploads Add X-Goog-Upload headers to Chrome Web Store upload requests Oct 13, 2025
Copilot AI requested a review from fregante October 13, 2025 12:24
Copilot finished work on behalf of fregante October 13, 2025 12:24
Copy link
Owner

@fregante fregante left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot

source/index.ts Outdated
const stats = await fs.promises.stat(streamOrPath);
readStream = stats.isFile()
? fs.createReadStream(streamOrPath)
: await zipStreamFromDirectory(streamOrPath);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to change this block. Restore the readStream line as it was

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored the original readStream assignment pattern with the ternary operator and getStreamFromPath helper function. Commit: 94a3f53

Copy link
Contributor Author

Copilot AI commented Oct 13, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.googleapis.com

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from fregante October 13, 2025 12:57
Copilot finished work on behalf of fregante October 13, 2025 12:57
@fregante fregante changed the title Add X-Goog-Upload headers to Chrome Web Store upload requests Fix support for CRX uploads Oct 13, 2025
Copy link

@J3ekir J3ekir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expected X-Goog-Upload-File-Name to match the actual file name but the code seems to work even when it doesn’t. Confirmed working on my end.

@fregante
Copy link
Owner

Yeah I figured it doesn't matter what we pass, they only check the extension anyway.

Thanks for checking! The only problem with this solution is that it won't work if you pass a CRX stream but only if you pass a path.

@fregante fregante merged commit d320c86 into main Oct 14, 2025
6 checks passed
@fregante fregante deleted the copilot/add-upload-headers-to-request branch October 14, 2025 03:06
@fregante
Copy link
Owner

I'll release this package as a patch update and then the CLI will receive a major prerelease that you can try. Maybe in a couple of hours

@J3ekir
Copy link

J3ekir commented Oct 15, 2025

The only problem with this solution is that it won't work if you pass a CRX stream but only if you pass a path.

Isn't it because fileName? Since it's a stream it's gonna get extension.zip as X-Goog-Upload-File-Name won't it?
When I change that by replacing it with const fileName = 'extension.crx'; I see no issue on my PC.

My test code
import 'dotenv/config';
import fs from 'fs';
import chromeWebstoreUpload from 'chrome-webstore-upload';

const fileName = './test.crx';
const store = new chromeWebstoreUpload({
	extensionId: process.env.EXTENSION_ID,
	clientId: process.env.CLIENT_ID,
	clientSecret: process.env.CLIENT_SECRET,
	refreshToken: process.env.REFRESH_TOKEN,
});

(async () => {
	const response = await store.uploadExisting(fs.createReadStream(fileName));
	// const response = await store.uploadExisting(fileName);

	console.log('response', response);
})();

I believe there are 12 possible cases.

Cases
CRX ZIP Folder
Opted In Stream 1 2 3
File 4 5 6
Not Opted In Stream 7 8 9
File 10 11 12

Right now #​4 works. For #​1, the fileName should be something with CRX extension. When it's like that it works too. IDK how streams work, why it's used, also how to detect it but looks like CRX files have a consistent magic number.

#​2 and #​5 are invalid. If you're opted in you can't use other than CRX. They return PKG_MUST_UPDATE_AS_CRX.

I believe #​3 is invalid because you can't stream folders.

#​6 doesn't work for me. I have folders in my extension and yazl isn't happy about it in here. Maybe I do something wrong. It's the same "My test code", only difference is it's a path with the same name, not with the file extension.

Since I've opted in, I can't/didn't test the rest. Right now I can't spend time to make another test extension. But I suggest you to do it and use proper CRX files for testing.

I would try to help implementing it but I don't know Node.JS/NPM stuf and I don't want to spend time learning it because I won't be using it anywhere else in the near future.

I also suggest you to test the effects of adding or not adding X-Goog-Upload-Protocol and X-Goog-Upload-File-Name headers for the cases #​7-#​12.

@fregante

@fregante
Copy link
Owner

fregante commented Oct 20, 2025

Yes? That's the point: if you pass a stream, the package doesn't know its name because streams don't have names.

Folders aren't "streamed", they're zipped first.

There are 3 cases:

  • you pass a stream, there's no file name
  • you pass a file path, there's a filename
  • you pass a folder path, the filename is .zip

There's nothing to do or fix here.

As was clear from the beginning, I'm not going to implement crx creation, so 6 will never work. If you want crx uploads, you must pass a crx file path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants