Skip to content

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented May 10, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a pre-commit hook to enforce code quality on staged files.
    • Added configuration files for OXLint and Prettier to standardize linting and formatting.
    • Updated lint-staged to automatically fix code style on commit.
  • Chores

    • Migrated project tooling from ESLint and egg-bin to OXLint, Prettier, and Vitest.
    • Updated CI workflows to use newer Node.js and Codecov versions.
    • Removed ESLint configuration and dependencies.
    • Improved environment variable handling in test configuration.
  • Documentation

    • Enhanced README formatting for clarity and readability.
  • Refactor & Style

    • Improved code formatting, type annotations, and consistency across all modules.
    • Refined method and function signatures for better type safety and readability.
    • Updated test files to use Vitest conventions and improved assertion clarity.
  • Tests

    • Migrated tests to Vitest and updated test hooks and assertions for consistency.

@fengmk2 fengmk2 requested a review from Copilot May 10, 2025 04:53
@coderabbitai
Copy link

coderabbitai bot commented May 10, 2025

Walkthrough

This update migrates the project's linting, formatting, and testing toolchain from ESLint, Egg-Bin, and Mocha to OXLint, Prettier, and Vitest. It removes the ESLint configuration, introduces OXLint and Prettier configs, updates scripts and dependencies, and refactors code and tests for improved style, type safety, and compatibility with the new tools.

Changes

File(s) Change Summary
.eslintrc Removed ESLint configuration file, discontinuing ESLint rules and TypeScript/node prefix enforcement.
.oxlintrc.json Added OXLint configuration with strict rules, multiple plugins, and ignore patterns tailored for Node.js, TypeScript, and Mocha environments.
.prettierrc, .prettierignore Introduced Prettier configuration and ignore file to standardize formatting and exclude changelog and snapshots from formatting.
.husky/pre-commit Added pre-commit hook to run lint-staged for linting and formatting staged files before commits.
.github/workflows/nodejs.yml Updated CI workflow: replaced Node.js v23 with v24, upgraded Codecov action to v5, and adjusted indentation.
.github/workflows/release.yml Reformatted branch specification in workflow trigger for consistency (no logic change).
package.json Migrated scripts to use OXLint, Prettier, and Vitest; replaced lint, test, and coverage tools; added lint-staged and husky; updated devDependencies accordingly.
README.md Improved documentation formatting: standardized code blocks, added markdown tables, and clarified code examples. No API or behavior changes.
src/OSSBaseClient.ts, src/OSSObject.ts, src/type/Object.ts, src/type/Request.ts Refactored for improved formatting, multiline signatures, explicit type imports, and minor type safety enhancements; replaced assert() with assert.ok(); improved XML and error handling robustness; no logic changes.
src/util/checkBucketName.ts, src/util/checkObjectTag.ts, src/util/encodeCallback.ts, Reformatted conditionals and error messages for clarity; improved type safety and explicitness in validation and encoding utilities.
src/util/json2xml.ts Changed function parameter type from any to unknown for stricter type safety; reformatted for readability.
src/util/policyToJSONString.ts Improved error handling in JSON parsing with type-safe error message extraction.
src/util/sign.ts Reformatted function signatures and loops for clarity; no change in signature logic or control flow.
src/error/OSSClientError.ts Reformatted constructor to multiline style for readability; no logic changes.
test/OSSObject.test.ts Refactored tests: used assert.ok, updated to Vitest hooks, replaced urllib import, improved assertion formatting, and enhanced type assertions. No test logic changes.
test/config.ts Used read-env-value for robust environment variable handling with defaults; replaced process.env access.
test/util/isIP.test.ts Imported Vitest's describe and it for BDD-style test definitions; no logic changes.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Git as Git (with Husky)
    participant Lint as OXLint/Prettier
    participant Test as Vitest
    participant CI as GitHub Actions

    Dev->>Git: git commit
    Git->>Lint: Run lint-staged (OXLint, Prettier) on staged files
    Lint-->>Git: Lint passes or fails
    Git->>Dev: Commit proceeds or aborts

    Dev->>CI: Push to repository
    CI->>Lint: Run OXLint on codebase
    CI->>Test: Run Vitest with coverage
    Test->>CI: Test results and coverage
    CI->>Dev: CI status (pass/fail)
Loading

Possibly related PRs

  • test: Node.js 23 #23: Related update to Node.js CI workflow matrix adding Node.js v23, while this PR replaces v23 with v24, both modifying the same workflow file.

Poem

🐇✨ In the warren, tools renewed,
Prettier and OXLint now pursued.
Vitest hops where Mocha lay,
Husky guards each commit’s way.
Scripts refactored, code refined,
A burrow clean and well-aligned.
🐰🎉 Hooray for lint and test anew!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb6d832 and f2a92e5.

📒 Files selected for processing (2)
  • package.json (2 hunks)
  • test/OSSObject.test.ts (81 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/OSSObject.test.ts
  • package.json
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: build (18, ubuntu-latest)
  • GitHub Check: build (22, ubuntu-latest)
  • GitHub Check: build (20, ubuntu-latest)
  • GitHub Check: build (24, ubuntu-latest)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a new code style and quality workflow by integrating prettier, oxlint, and vitest while refactoring several modules for improved readability and maintainability. Key changes include reformatting functions into multi‐line signatures, standardizing assertions (using assert.ok), updating configuration files, and adjusting type declarations and error handling.

Reviewed Changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/util/sign.ts Refactored function signatures and loop iterations for clarity.
src/util/policyToJSONString.ts Improved error message handling for JSON parsing.
src/util/json2xml.ts Updated type annotations and recursive call formatting.
src/util/encodeCallback.ts Adjusted formatting for base64 conversion, improving readability.
src/util/checkObjectTag.ts Simplified condition structure and error messages.
src/util/checkBucketName.ts Reformatted regex condition for bucket name validation.
src/type/* Updated union types’ formatting and multiline declarations.
src/OSSObject.ts Converted assertions to assert.ok, clarified overloads & mappings.
src/OSSBaseClient.ts Improved assertion messaging and updated internal request logic.
package.json & config files Updated dependencies & scripts to use prettier, oxlint, vitest, husky.
.github/workflows/nodejs.yml Updated Node versions and Codecov action version.
README.md Adjusted API usage examples to improved formatting.

@socket-security
Copy link

socket-security bot commented May 10, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedhusky@​9.1.71001005982100
Added@​vitest/​coverage-v8@​3.1.3991007099100
Addedread-env-value@​1.0.1701008383100
Addedvitest@​3.1.3971007799100
Addedoxlint@​0.16.10991008396100
Addedprettier@​3.5.39810010090100

View full report

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (4)
.husky/pre-commit (1)

1-2: ⚠️ Potential issue

Missing Husky hook initialization
Husky requires sourcing its runner script before commands. Without it, the hook may not run.

Apply this diff:

+#!/usr/bin/env sh
+. "$(dirname "$0")/_/husky.sh"
 npx lint-staged
test/OSSObject.test.ts (1)

1486-1486: ⚠️ Potential issue

Fix timeout in traffic limit test.

The test "should signature url with traffic limit" is timing out in 5000ms, which is causing build failures:

Test timed out in 5000ms for 'should signature url with traffic limit'. Consider increasing timeout with 'testTimeout' option.

Increase the test timeout specifically for this test:

-  it('should signature url with traffic limit', async () => {
+  it('should signature url with traffic limit', async () => {
+    // This test involves network operations that may take longer than the default timeout
+    vi.setConfig({ testTimeout: 30000 });

Or use the testTimeout option in the test declaration:

-  it('should signature url with traffic limit', async () => {
+  it('should signature url with traffic limit', { timeout: 30000 }, async () => {
🧰 Tools
🪛 GitHub Check: build (24, ubuntu-latest)

[failure] 1486-1486: test/OSSObject.test.ts > test/OSSObject.test.ts > signatureUrl() and asyncSignatureUrl() > should signature url with traffic limit
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ test/OSSObject.test.ts:1486:5

🪛 GitHub Check: build (20, ubuntu-latest)

[failure] 1486-1486: test/OSSObject.test.ts > test/OSSObject.test.ts > signatureUrl() and asyncSignatureUrl() > should signature url with traffic limit
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ test/OSSObject.test.ts:1486:5

🪛 GitHub Check: build (18, ubuntu-latest)

[failure] 1486-1486: test/OSSObject.test.ts > test/OSSObject.test.ts > signatureUrl() and asyncSignatureUrl() > should signature url with traffic limit
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ test/OSSObject.test.ts:1486:5

🪛 GitHub Check: build (22, ubuntu-latest)

[failure] 1486-1486: test/OSSObject.test.ts > test/OSSObject.test.ts > signatureUrl() and asyncSignatureUrl() > should signature url with traffic limit
Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
❯ test/OSSObject.test.ts:1486:5

🪛 GitHub Actions: Node.js CI

[error] 1486-1486: Test timed out in 5000ms for 'should signature url with traffic limit'. Consider increasing timeout with 'testTimeout' option.

src/util/sign.ts (1)

32-40: ⚠️ Potential issue

Canonicalization sort only compares first character – breaks signature for multi-char keys

compareFunc returns a result based solely on entry[0], so keys like "abc" and "az" are treated as equal.
When OSS validates the signature it expects keys to be sorted by the full string; a wrong order yields SignatureDoesNotMatch.

-const compareFunc = (entry1: string, entry2: string) => {
-  if (entry1[0] > entry2[0]) {
-    return 1;
-  } else if (entry1[0] < entry2[0]) {
-    return -1;
-  }
-  return 0;
-};
+const compareFunc = (a: string, b: string) => (a > b ? 1 : a < b ? -1 : 0);

This keeps the original intent but performs a full lexical comparison.

Also applies to: 47-49

src/OSSObject.ts (1)

384-388: ⚠️ Potential issue

Destroying the write stream immediately causes “ERR_STREAM_UNABLE_TO_PIPE”

CI shows failures (Cannot pipe to a closed or destroyed stream) in tests that pass a file path to get().
urllib resolves the promise when the response ends, not when the writeStream finishes flushing.
Calling writeStream.destroy() at this point closes the FD early and triggers the error.

-      if (needDestroy && writeStream) {
-        writeStream.destroy();
-      }
+      // Wait for the stream to flush before closing it
+      if (needDestroy && writeStream) {
+        await new Promise<void>(resolve => {
+          writeStream.once('close', resolve);
+        });
+      }

This lets the OS flush and close the descriptor safely, removing the pipeline failure.

🧹 Nitpick comments (10)
test/util/isIP.test.ts (1)

3-3: Optional: Adopt Vitest's expect API.
Consider importing and using Vitest's expect for assertions (expect(isIP(...)).toBe(true)) to leverage built-in matchers and improve readability.

src/util/checkBucketName.ts (1)

5-6: Nitpick: Improve error message grammar.
Change the error message from:

'The bucket must be conform to the specifications'

to:

'The bucket must conform to the specifications'
src/util/encodeCallback.ts (1)

20-22: Optional: Extract base64 encoding to helper.
Consider defining a helper such as:

function toBase64(obj: unknown): string {
  return Buffer.from(JSON.stringify(obj)).toString('base64');
}

to reduce duplication and centralize encoding logic.

Also applies to: 32-34

src/util/checkObjectTag.ts (2)

8-10: Grammar refinement in error message
The message reads “maximum of 10 tags for a object” but should use “an object.”

Proposed diff:

-    throw new TypeError('maximum of 10 tags for a object');
+    throw new TypeError('maximum of 10 tags for an object');

12-14: Grammar refinement in error message
Use plural “strings” and lowercase for consistency.

Proposed diff:

-      throw new TypeError('the key and value of the tag must be String');
+      throw new TypeError('the key and value of the tag must be strings');
src/util/json2xml.ts (1)

4-5: Optional refactor: extract options interface
If you expect more flags later, consider:

interface Json2XmlOptions { headers?: boolean }
export function json2xml(
  json: Record<string, unknown>,
  options?: Json2XmlOptions
)
README.md (1)

1-1658: Approve documentation formatting changes
Prettier has reformatted code snippets, lists, and tables without altering any API descriptions or examples.

Grammar nitpick in .deleteMulti description
Fix typo “succes” → “success”, add missing comma/semicolon.

- quiet mode: if all objects delete succes, return emtpy response. otherwise return delete error object results.
+ quiet mode: if all objects delete successfully, return empty response; otherwise, return delete error object results.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~26-~26: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... OSS, Object Storage Service. Equal to well known Amazon S3....

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[grammar] ~146-~146: An article may be missing.
Context: ... aliyun too, you can set true to save lot of money. - [timeout] {String|Number} inst...

(BUNCH_OF)


[grammar] ~166-~166: There seems to be a noun/verb agreement error. Did you mean “accelerates” or “accelerated”?
Context: ...ion: 'oss-cn-hangzhou', }); ``` 2. use accelerate endpoint - Global accelerate endpoint:...

(SINGULAR_NOUN_VERB_AGREEMENT)


[uncategorized] ~405-~405: Possible missing article found.
Context: ...nd an object to the bucket, it's almost same as put, but it can add content to exist...

(AI_HYDRA_LEO_MISSING_THE)


[uncategorized] ~405-~405: Possible missing article found.
Context: ... same as put, but it can add content to existing object rather than override it. All pa...

(AI_HYDRA_LEO_MISSING_AN)


[uncategorized] ~448-~448: Possible missing preposition found.
Context: ...e baseUrl, will use baseUrl instead the default bucket and endpoint. Suggest ...

(AI_HYDRA_LEO_MISSING_OF)


[grammar] ~550-~550: Possible subject-verb agreement error.
Context: ... example: - Head an exists object and get object meta info ```js await this.stor...

(IS_AND_ARE)


[grammar] ~718-~718: In standard English, the word ‘exists’ is a verb. Please verify that the determiner ‘an’ is correct, or that a noun is not missing between ‘an’ and ‘exists’.
Context: ...lso delete success. example: - Delete an exists object ```js await store.delete('ossde...

(A_INFINITIVE)


[grammar] ~745-~745: It seems that a pronoun is missing.
Context: ... [sourceBucket] {String} source Bucket. if doesn't exist,sourceBucket is same bu...

(IF_VB)


[grammar] ~745-~745: Is an article like ‘a’ or ‘an’ missing?
Context: ...Bucket. if doesn't exist,sourceBucket is same bucket. - [options] {Object} optio...

(BE_NN)


[uncategorized] ~745-~745: Possible missing article found.
Context: ...ket. if doesn't exist,sourceBucket is same bucket. - [options] {Object} optional p...

(AI_HYDRA_LEO_MISSING_THE)


[grammar] ~809-~809: In standard English, the word ‘exists’ is a verb. Please verify that the determiner ‘an’ is correct, or that a noun is not missing between ‘an’ and ‘exists’.
Context: ...## .putMeta(name, meta[, options]) Set an exists object meta. parameters: - name {Stri...

(A_INFINITIVE)


[uncategorized] ~857-~857: The preposition ‘at’ seems more likely in this position.
Context: ...Object>} object names, max 1000 objects in once. - key {String} object name - ...

(AI_HYDRA_LEO_REPLACE_IN_AT)


[uncategorized] ~863-~863: Possible missing comma found.
Context: ...lete succes, return emtpy response. otherwise return delete error object results. ...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~928-~928: The modal verb ‘will’ requires the verb’s base form.
Context: ...meta info list Each ObjectMeta will contains blow properties: - name {String} obje...

(MD_BASEFORM)


[uncategorized] ~947-~947: Possible missing preposition found.
Context: ...t total use time (ms) example: - List top 10 objects ```js const result = await ...

(AI_HYDRA_LEO_MISSING_OF)


[grammar] ~993-~993: The modal verb ‘will’ requires the verb’s base form.
Context: ...meta info list Each ObjectMeta will contains blow properties: - name {String} obje...

(MD_BASEFORM)


[uncategorized] ~1013-~1013: Possible missing preposition found.
Context: ...er} request total use time (ms) - List top 10 objects ```js const result = await ...

(AI_HYDRA_LEO_MISSING_OF)


[grammar] ~1072-~1072: The modal verb ‘will’ requires the verb’s base form.
Context: ...meta info list Each ObjectMeta will contains blow properties: - name {String} obje...

(MD_BASEFORM)


[grammar] ~1128-~1128: There is an agreement error between ‘put’ and ‘object’. Insert ‘a(n)’ or change the noun to plural.
Context: ...for download or upload object. When you put object with signatureUrl ,you need to pass `Co...

(PRP_VB_NN)


[uncategorized] ~1151-~1151: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...ject} set the custom value for callback,eg. {var1: value1,var2:value2} Success wil...

(E_G)


[typographical] ~1208-~1208: Consider adding a comma after ‘Basically’ for more clarity.
Context: ...## .asyncSignatureUrl(name[, options]) Basically the same as signatureUrl, if refreshSTS...

(RB_LY_COMMA)


[uncategorized] ~1232-~1232: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...ject} set the custom value for callback,eg. {var1: value1,var2:value2} Success wil...

(E_G)


[misspelling] ~1312-~1312: Use “a” instead of ‘an’ if the following word doesn’t start with a vowel sound, e.g. ‘a sentence’, ‘a university’.
Context: ...ssdemo.txt', 'public-read'); - Set an history object's ACL js const versi...

(EN_A_VS_AN)


[misspelling] ~1350-~1350: Use “a” instead of ‘an’ if the following word doesn’t start with a vowel sound, e.g. ‘a sentence’, ‘a university’.
Context: ...'); console.log(result.acl); - Get an history object's ACL js const versi...

(EN_A_VS_AN)


[misspelling] ~1404-~1404: Use “a” instead of ‘an’ if the following word doesn’t start with a vowel sound, e.g. ‘a sentence’, ‘a university’.
Context: ...sole.log(result.status); - Restore an history object js const versionId =...

(EN_A_VS_AN)


[uncategorized] ~1534-~1534: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...ng} the object name - tag {Object} tag, eg. {var1: value1,var2:value2} - [options...

(E_G)


[uncategorized] ~1552-~1552: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...ng} the object name - tag {Object} tag, eg. {var1: value1,var2:value2} - [options...

(E_G)


[grammar] ~1592-~1592: The modal verb ‘will’ requires the verb’s base form.
Context: ...s Each error return by OSS server will contains these properties: - name {String} erro...

(MD_BASEFORM)

🪛 markdownlint-cli2 (0.17.2)

184-184: Bare URL used
null

(MD034, no-bare-urls)

test/OSSObject.test.ts (1)

702-714: Use consistent Buffer utility methods.

The implementation uses both Buffer.byteLength and string concatenation to determine content length.

For better readability, consider:

-  'content-length': Buffer.byteLength(
-    'Hello, 你好 OSS',
-    'utf8'
-  ).toString(),
+  'content-length': String(Buffer.byteLength('Hello, 你好 OSS', 'utf8')),
src/OSSObject.ts (1)

1096-1098: successStatuses too narrow for PUT/POST uploads

OSS may legitimately return 201 (Created) for some PUT/POST operations (e.g. object upload with x-oss-forbid-overwrite). Limiting to [200] forces an unnecessary retry path.

-    params.successStatuses = [200];
+    params.successStatuses = [200, 201];
src/OSSBaseClient.ts (1)

190-194: Avoid double allocation when computing MD5

Buffer.from(params.content) allocates a new buffer although params.content is already a Buffer.

-        headers['content-md5'] = createHash('md5')
-          .update(Buffer.from(params.content))
+        headers['content-md5'] = createHash('md5')
+          .update(params.content)
           .digest('base64');

Reduces one copy per request and a few CPU cycles.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f7c506 and bb6d832.

📒 Files selected for processing (23)
  • .eslintrc (0 hunks)
  • .github/workflows/nodejs.yml (1 hunks)
  • .github/workflows/release.yml (1 hunks)
  • .husky/pre-commit (1 hunks)
  • .oxlintrc.json (1 hunks)
  • .prettierignore (1 hunks)
  • .prettierrc (1 hunks)
  • README.md (42 hunks)
  • package.json (2 hunks)
  • src/OSSBaseClient.ts (11 hunks)
  • src/OSSObject.ts (47 hunks)
  • src/error/OSSClientError.ts (1 hunks)
  • src/type/Object.ts (2 hunks)
  • src/type/Request.ts (1 hunks)
  • src/util/checkBucketName.ts (1 hunks)
  • src/util/checkObjectTag.ts (1 hunks)
  • src/util/encodeCallback.ts (2 hunks)
  • src/util/json2xml.ts (2 hunks)
  • src/util/policyToJSONString.ts (1 hunks)
  • src/util/sign.ts (5 hunks)
  • test/OSSObject.test.ts (81 hunks)
  • test/config.ts (1 hunks)
  • test/util/isIP.test.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • .eslintrc
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/util/sign.ts (3)
src/type/Request.ts (2)
  • RequestParameters (5-8)
  • Request (18-21)
src/OSSObject.ts (2)
  • method (1140-1155)
  • options (1118-1135)
src/OSSBaseClient.ts (4)
  • request (234-263)
  • signature (71-74)
  • authorization (91-109)
  • options (267-292)
src/OSSBaseClient.ts (3)
src/type/Request.ts (3)
  • RequestParameters (5-8)
  • OSSRequestParams (23-44)
  • OSSResult (46-49)
src/util/sign.ts (2)
  • buildCanonicalString (65-94)
  • authorization (104-111)
src/error/OSSClientError.ts (1)
  • OSSClientError (5-28)
🪛 LanguageTool
README.md

[uncategorized] ~863-~863: Possible missing comma found.
Context: ...lete succes, return emtpy response. otherwise return delete error object results. ...

(AI_HYDRA_LEO_MISSING_COMMA)

🪛 Biome (1.9.4)
.oxlintrc.json

[error] 26-26: Expected a property but instead found '// eslint'.

Expected a property here.

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 35-35: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 35-35: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 35-35: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 35-35: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 36-36: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 36-36: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 36-36: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 36-36: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 37-37: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 37-37: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 37-37: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 37-37: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 38-38: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 38-38: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 38-38: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 38-38: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 39-39: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 39-39: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 39-39: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 39-39: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 40-40: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 40-40: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 40-40: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 40-40: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 41-41: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 41-41: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 41-41: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 41-41: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 42-42: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 42-42: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 42-42: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 42-42: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 43-43: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 43-43: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 43-43: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 43-43: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 44-44: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 44-44: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 44-44: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 44-44: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 45-45: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 45-45: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 45-45: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 45-45: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 46-46: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 46-46: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 46-46: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 46-46: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 47-47: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 47-47: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 47-47: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 47-47: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 48-48: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 48-48: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 48-48: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 48-48: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 49-49: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 49-49: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 49-49: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 49-49: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 50-50: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 50-50: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 50-50: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 50-50: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 51-51: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 51-51: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 51-51: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 51-51: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 52-52: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 52-52: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 52-52: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 52-52: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 53-53: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 53-53: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 53-53: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 53-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 56-56: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 56-56: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 56-56: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 56-56: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 58-58: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 58-58: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 58-58: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 58-58: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 59-59: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 59-59: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 59-59: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 59-59: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 60-60: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 60-60: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 60-60: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 60-60: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 61-61: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 61-61: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 61-61: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 61-61: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 62-62: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 62-62: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 62-62: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 62-62: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 63-63: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 63-63: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 63-63: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 63-63: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 64-64: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 64-64: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 64-64: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 64-64: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 65-65: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 65-65: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 65-65: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 65-65: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 66-66: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 66-66: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 66-66: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 66-66: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 67-67: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 67-67: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 67-67: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 67-67: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 68-68: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 68-68: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 68-68: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 68-70: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 71-71: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 71-71: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 71-71: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 71-71: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 72-72: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 72-72: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 72-72: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 72-72: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 73-73: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 73-73: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 73-73: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 73-73: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 74-74: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 74-74: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 74-74: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 74-74: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 75-75: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 75-75: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 75-75: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 75-75: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 76-76: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 76-76: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 76-76: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 76-76: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 77-77: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 77-77: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 77-77: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 77-77: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 78-78: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 78-78: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 78-78: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 78-78: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 79-79: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 79-79: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 79-79: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 79-79: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 80-80: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 80-80: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 80-80: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 80-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 83-83: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 83-83: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 83-83: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 83-83: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 85-85: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 85-85: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 85-85: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 85-85: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 86-86: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 86-86: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 86-86: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 86-86: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 88-88: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 88-88: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 88-88: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 88-88: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 89-89: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 89-89: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 89-89: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 89-91: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 92-92: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 92-92: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 92-92: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 92-92: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 93-93: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 93-93: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 93-93: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 93-93: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 94-94: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 94-94: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 94-94: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 94-94: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 95-95: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 96-96: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 97-97: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 97-97: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 97-97: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 97-97: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 98-98: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 98-98: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 98-98: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 98-98: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 99-99: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 99-99: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 99-99: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 99-100: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 101-101: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 101-101: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 101-101: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 101-101: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 102-102: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 102-102: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 102-102: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 102-102: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 103-103: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 103-103: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 103-103: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 103-103: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 104-104: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 104-104: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 104-104: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 104-104: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 105-105: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 105-105: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 105-105: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 105-105: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 106-106: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 106-106: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 106-106: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 106-106: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 107-107: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 107-107: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 107-107: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 107-107: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 108-108: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 108-108: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 108-108: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 108-108: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 110-110: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 110-110: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 110-110: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 110-110: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 112-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 112-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 112-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 112-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 113-113: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 113-113: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 113-113: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 113-113: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 114-114: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 114-114: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 114-114: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 114-114: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 115-115: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 115-115: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 115-115: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 115-117: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 118-118: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 118-118: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 118-118: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 118-118: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 119-119: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 119-119: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 119-119: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 119-119: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 120-120: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 120-120: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 120-120: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 120-120: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 121-121: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 121-121: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 121-121: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 121-123: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 124-124: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 124-124: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 124-124: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 124-124: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 125-125: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 125-125: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 125-125: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 125-125: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 126-126: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 126-126: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 126-126: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 126-126: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 127-127: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 127-127: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 127-127: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 127-127: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 128-128: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 128-128: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 128-128: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 128-128: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 129-129: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 129-129: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 129-129: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 129-129: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 130-130: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 130-130: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 130-130: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 130-130: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 131-131: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 131-131: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 131-131: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 131-131: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 132-132: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 132-132: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 132-132: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 132-132: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 133-133: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 133-133: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 133-133: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 133-133: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 134-134: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 134-134: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 134-134: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 134-134: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 135-135: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 135-135: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 135-135: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 135-135: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 136-136: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 136-136: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 136-136: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 136-138: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 139-139: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 139-139: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 139-139: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 139-139: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 140-140: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 140-140: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 140-140: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 141-141: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 142-142: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 142-142: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 142-142: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 142-143: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

🪛 GitHub Check: build (24, ubuntu-latest)
src/OSSBaseClient.ts

[failure] 238-238: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should store object to writeStream
Error: Cannot pipe to a closed or destroyed stream
❯ HttpClient.#requestInternal node_modules/urllib/src/HttpClient.ts:643:17
❯ HttpClient.request node_modules/urllib/src/HttpClient.ts:246:12
❯ OSSObject.request src/OSSBaseClient.ts:238:20
❯ OSSObject.get src/OSSObject.ts:383:16
❯ test/OSSObject.test.ts:1589:22

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'ERR_STREAM_UNABLE_TO_PIPE', opaque: undefined, status: 200, headers: { server: 'AliyunOSS', date: 'Sat, 10 May 2025 04:55:25 GMT', 'content-type': 'video/mp2t', 'content-length': '90839', connection: 'keep-alive', 'x-oss-request-id': '681EDC3D0482F43637297E41', 'accept-ranges': 'bytes', etag: '"64ADE9929664E066DBC0D45974A6E2A6"', 'last-modified': 'Sat, 10 May 2025 04:55:23 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '8275475219421965874', 'x-oss-storage-class': 'IA', 'x-oss-meta-pid': '123', 'x-oss-meta-slus': 'test.html', 'x-oss-meta-uid': '1', 'content-md5': 'ZK3pkpZk4GbbwNRZdKbipg==', 'x-oss-server-time': '14' }, res: { status: 200, statusCode: 200, statusText: 'OK', statusMessage: 'OK', headers: { server: 'AliyunOSS', date: 'Sat, 10 May 2025 04:55:25 GMT', 'content-type': 'video/mp2t', 'content-length': '90839', connection: 'keep-alive', 'x-oss-request-id': '681EDC3D0482F43637297E41', 'accept-ranges': 'bytes', etag: '"64ADE9929664E066DBC0D45974A6E2A6"', 'last-modified': 'Sat, 10 May 2025 04:55:23 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '8275475219421965874', 'x-oss-storage-class': 'IA', 'x-oss-meta-pid': '123', 'x-oss-meta-slus': 'test.html', 'x-oss-meta-uid': '1', 'content-md5': 'ZK3pkpZk4GbbwNRZdKbipg==', 'x-oss-server-time': '14' }, size: 90839, aborted: false, rt: 1072.76, keepAliveSocket: true, requestUrls: [ 'https://..aliyuncs.com/linux-v24.0.0-1746852855756/oss-client/oss/get-meta.js' ], timing: { queuing: 0.095, dnslookup: +0, connected: 836.136, requestHeadersSent: 836.214, requestSent: 836.284, waiting: 1072.471, contentDownload: +0 }, socket: { id: 5, localAddress: '10.1.0.5', localPort: 52860, remoteAddress: '47.101.28.51', remotePort: 443, remoteFamily: 'IPv4', bytesWritten: 365, bytesRead: 4096, handledRequests: 1, handledResponses: 1, connectedTime: '2025-05-10T04:55:25.136Z' }, retries: +0, socketErrorRetries: +0 }, socket: { id: 5, localAddress: '10.1.0.5', localPort: 52860, remoteAddress: '47.101.28.51', remotePort: 443, remoteFamily: 'IPv4', bytesWritten: 365, bytesRead: 4096, handledRequests: 1, handledResponses: 1, connectedTime: '2025-05-10T04:55:25.136Z' } }


[failure] 238-238: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should escape uri path ok
Error: Cannot pipe to a closed or destroyed stream
❯ HttpClient.#requestInternal node_modules/urllib/src/HttpClient.ts:643:17
❯ HttpClient.request node_modules/urllib/src/HttpClient.ts:246:12
❯ OSSObject.request src/OSSBaseClient.ts:238:20
❯ OSSObject.get src/OSSObject.ts:383:16
❯ test/OSSObject.test.ts:1563:22

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'ERR_STREAM_UNABLE_TO_PIPE', opaque: undefined, status: 200, headers: { server: 'AliyunOSS', date: 'Sat, 10 May 2025 04:55:24 GMT', 'content-type': 'video/mp2t', 'content-length': '90839', connection: 'keep-alive', 'x-oss-request-id': '681EDC3C2E2F78353286872E', 'accept-ranges': 'bytes', etag: '"64ADE9929664E066DBC0D45974A6E2A6"', 'last-modified': 'Sat, 10 May 2025 04:55:23 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '8275475219421965874', 'x-oss-storage-class': 'IA', 'x-oss-meta-pid': '123', 'x-oss-meta-slus': 'test.html', 'x-oss-meta-uid': '1', 'content-md5': 'ZK3pkpZk4GbbwNRZdKbipg==', 'x-oss-server-time': '12' }, res: { status: 200, statusCode: 200, statusText: 'OK', statusMessage: 'OK', headers: { server: 'AliyunOSS', date: 'Sat, 10 May 2025 04:55:24 GMT', 'content-type': 'video/mp2t', 'content-length': '90839', connection: 'keep-alive', 'x-oss-request-id': '681EDC3C2E2F78353286872E', 'accept-ranges': 'bytes', etag: '"64ADE9929664E066DBC0D45974A6E2A6"', 'last-modified': 'Sat, 10 May 2025 04:55:23 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '8275475219421965874', 'x-oss-storage-class': 'IA', 'x-oss-meta-pid': '123', 'x-oss-meta-slus': 'test.html', 'x-oss-meta-uid': '1', 'content-md5': 'ZK3pkpZk4GbbwNRZdKbipg==', 'x-oss-server-time': '12' }, size: 90839, aborted: false, rt: 231.396, keepAliveSocket: true, requestUrls: [ 'https://..aliyuncs.com/linux-v24.0.0-1746852855756/oss-client/oss/%253get%2Bmeta.js' ], timing: { queuing: 0.088, dnslookup: +0, connected: +0, requestHeadersSent: 0.127, requestSent: 0.182, waiting: 230.966, contentDownload: +0 }, socket: { id: 1, localAddress: '10.1.0.5', localPort: 34320, remoteAddress: '47.101.28.51', remotePort: 443, remoteFamily: 'IPv4', bytesWritten: 9637827, bytesRead: 1923049, handledRequests: 117, handledResponses: 117, connectedTime: '2025-05-10T04:54:17.257Z', lastRequestEndTime: '2025-05-10T04:55:23.799Z' }, retries: +0, socketErrorRetries: +0 }, socket: { id: 1, localAddress: '10.1.0.5', localPort: 34320, remoteAddress: '47.101.28.51', remotePort: 443, remoteFamily: 'IPv4', bytesWritten: 9637827, bytesRead: 1923049, handledRequests: 117, handledResponses: 117, connectedTime: '2025-05-10T04:54:17.257Z', lastRequestEndTime: '2025-05-10T04:55:23.799Z' } }


[failure] 238-238: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should store object to local file
Error: Cannot pipe to a closed or destroyed stream
❯ HttpClient.#requestInternal node_modules/urllib/src/HttpClient.ts:643:17
❯ HttpClient.request node_modules/urllib/src/HttpClient.ts:246:12
❯ OSSObject.request src/OSSBaseClient.ts:238:20
❯ OSSObject.get src/OSSObject.ts:383:16
❯ test/OSSObject.test.ts:1546:22

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'ERR_STREAM_UNABLE_TO_PIPE', opaque: undefined, status: 200, headers: { server: 'AliyunOSS', date: 'Sat, 10 May 2025 04:55:23 GMT', 'content-type': 'video/mp2t', 'content-length': '90839', connection: 'keep-alive', 'x-oss-request-id': '681EDC3B0EF7D03538BA4A7A', 'accept-ranges': 'bytes', etag: '"64ADE9929664E066DBC0D45974A6E2A6"', 'last-modified': 'Sat, 10 May 2025 04:55:23 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '8275475219421965874', 'x-oss-storage-class': 'IA', 'x-oss-meta-pid': '123', 'x-oss-meta-slus': 'test.html', 'x-oss-meta-uid': '1', 'content-md5': 'ZK3pkpZk4GbbwNRZdKbipg==', 'x-oss-server-time': '12' }, res: { status: 200, statusCode: 200, statusText: 'OK', statusMessage: 'OK', headers: { server: 'AliyunOSS', date: 'Sat, 10 May 2025 04:55:23 GMT', 'content-type': 'video/mp2t', 'content-length': '90839', connection: 'keep-alive', 'x-oss-request-id': '681EDC3B0EF7D03538BA4A7A', 'accept-ranges': 'bytes', etag: '"64ADE9929664E066DBC0D45974A6E2A6"', 'last-modified': 'Sat, 10 May 2025 04:55:23 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '8275475219421965874', 'x-oss-storage-class': 'IA', 'x-oss-meta-pid': '123', 'x-oss-meta-slus': 'test.html', 'x-oss-meta-uid': '1', 'content-md5': 'ZK3pkpZk4GbbwNRZdKbipg==', 'x-oss-server-time': '12' }, size: 90839, aborted: false, rt: 257.566, keepAliveSocket: true, requestUrls: [ 'https://..aliyuncs.com/linux-v24.0.0-1746852855756/oss-client/oss/get-meta.js' ], timing: { queuing: 0.064, dnslookup: +0, connected: +0, requestHeadersSent: 0.097, requestSent: 0.159, waiting: 257.21, contentDownload: +0 }, socket: { id: 3, localAddress: '10.1.0.5', localPort: 41758, remoteAddress: '47.101.28.51', remotePort: 443, remoteFamily: 'IPv4', bytesWritten: 12862, bytesRead: 1360201, handledRequests: 29, handledResponses: 29, connectedTime: '2025-05-10T04:54:57.661Z', lastRequestEndTime: '2025-05-10T04:55:23.018Z' }, retries: +0, socketErrorRetries: +0 }, socket: { id: 3, localAddress: '10.1.0.5', localPort: 41758, remoteAddress: '47.101.28.51', remotePort: 443, remoteFamily: 'IPv4', bytesWritten: 12862, bytesRead: 1360201, handledRequests: 29, handledResponses: 29, connectedTime: '2025-05-10T04:54:57.661Z', lastRequestEndTime: '2025-05-10T04:55:23.018Z' } }

test/OSSObject.test.ts

[failure] 1603-1603: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should store not exists object to file
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • 'ERR_STREAM_UNABLE_TO_PIPE'

  • 'NoSuchKey'

Expected: "NoSuchKey"
Received: "ERR_STREAM_UNABLE_TO_PIPE"

❯ Object. test/OSSObject.test.ts:1603:18
❯ test/OSSObject.test.ts:1598:7

🪛 GitHub Check: build (20, ubuntu-latest)
test/OSSObject.test.ts

[failure] 1603-1603: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should store not exists object to file
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • 'ENOENT'

  • 'NoSuchKey'

Expected: "NoSuchKey"
Received: "ENOENT"

❯ Object. test/OSSObject.test.ts:1603:18
❯ test/OSSObject.test.ts:1598:7

🪛 GitHub Check: build (18, ubuntu-latest)
test/OSSObject.test.ts

[failure] 1603-1603: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should store not exists object to file
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • 'ENOENT'

  • 'NoSuchKey'

Expected: "NoSuchKey"
Received: "ENOENT"

❯ Object. test/OSSObject.test.ts:1603:18
❯ test/OSSObject.test.ts:1598:7

🪛 GitHub Check: build (22, ubuntu-latest)
test/OSSObject.test.ts

[failure] 1603-1603: test/OSSObject.test.ts > test/OSSObject.test.ts > get() > should store not exists object to file
AssertionError: Expected values to be strictly equal:

  • actual - expected

  • 'ENOENT'

  • 'NoSuchKey'

Expected: "NoSuchKey"
Received: "ENOENT"

❯ Object. test/OSSObject.test.ts:1603:18
❯ test/OSSObject.test.ts:1598:7

🪛 GitHub Actions: Node.js CI
test/OSSObject.test.ts

[error] 1486-1486: Test timed out in 5000ms for 'should signature url with traffic limit'. Consider increasing timeout with 'testTimeout' option.


[error] 1546-1546: Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should store object to local file'.


[error] 1563-1563: Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should escape uri path ok'.


[error] 1589-1589: Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should store object to writeStream'.


[error] 1603-1603: AssertionError: Expected error code 'NoSuchKey' but received 'ERR_STREAM_UNABLE_TO_PIPE' in 'should store not exists object to file'.

🔇 Additional comments (30)
test/util/isIP.test.ts (1)

3-3: Tests updated for Vitest.
Importing describe and it from Vitest aligns the tests with the new testing framework.

.github/workflows/nodejs.yml (2)

21-21: Update tested Node.js versions.
Testing against Node.js v18, v20, v22, and the newly released v24 ensures CI compatibility with supported and current versions.


45-46: Bump Codecov action to v5.
Upgrading codecov/codecov-action from v3 to v5 aligns with the latest version of the action and its features.

.github/workflows/release.yml (1)

5-5: Standardize branch syntax.
The formatting change to branches: [master] improves consistency without affecting workflow behavior.

src/util/checkBucketName.ts (1)

2-4: Reformat ternary assignment.
Splitting the bucketRegex assignment into a multiline conditional enhances readability while preserving existing logic.

src/util/encodeCallback.ts (1)

20-22: Reformat base64 encoding calls.
Splitting the .toString('base64') invocation across lines improves formatting in accordance with Prettier’s style rules.

Also applies to: 32-34

src/type/Object.ts (2)

2-7: Clean import formatting looks good!

The multi-line import style improves readability when importing multiple types.


170-171: Interface extension formatting looks good!

The multi-line interface extension syntax is more readable and consistent with the formatting style being applied throughout the codebase.

src/type/Request.ts (2)

5-8: Union type formatting looks good!

The multi-line format for the RequestParameters union type improves readability.


10-16: HTTP method union type formatting looks good!

The multi-line format for the RequestMethod union type makes each HTTP method clearly visible, improving readability.

src/error/OSSClientError.ts (1)

12-21: Constructor formatting looks good!

The multi-line formatting for both the constructor parameters and the super call improves readability, especially with the template string construction in the error message.

src/util/policyToJSONString.ts (1)

6-8: Great improvement to error handling!

The updated error handling is more type-safe by checking if the caught error is an instance of Error before accessing the message property. Using String(err) as a fallback ensures that the error message is always a string, making the code more robust against different error types.

src/util/checkObjectTag.ts (2)

11-22: Preserved validation logic with improved readability
The multi-line condition clearly checks that keys always match the allowed pattern and values only if non-empty. No change in runtime behavior.


23-27: Explicit length check improves clarity
Switching from key.length < 1 to key.length === 0 makes the lower-bound check more explicit without altering logic.

src/util/json2xml.ts (2)

3-6: Enhanced type safety in function signature
Updating json to Record<string, unknown> and formatting the parameters across multiple lines boosts readability and type correctness.


21-23: Safe cast for recursive calls
You guard against null/undefined before casting to Record<string, unknown>, maintaining runtime safety while satisfying TypeScript.

.prettierignore (1)

1-3: Prettier ignore patterns look good
Excluding CHANGELOG.md and __snapshots__ prevents formatting of non-code files and snapshots.

.prettierrc (1)

1-6: New Prettier configuration looks good.

The Prettier configuration includes sensible defaults that align with modern JavaScript/TypeScript practices:

  • Single quotes for string literals
  • ES5-compatible trailing commas
  • 2-space indentation
  • Omitting parentheses around single arrow function parameters

This configuration complements the migration from ESLint to Prettier for code formatting as mentioned in the PR objectives.

test/config.ts (3)

1-1: Good addition of typed environment variable handling.

Using the read-env-value package provides better type safety and explicit default values compared to directly accessing process.env.


4-4: Nice simplification using Date.now().

Replacing new Date().getTime() with the equivalent but more concise Date.now() improves code readability.


6-14: Good addition of explicit type handling and default values.

The use of the env function with explicit types and default values for OSS configuration enhances robustness by:

  1. Ensuring type safety through explicit type declarations
  2. Providing fallback values for when environment variables are not set
  3. Making the configuration more maintainable and self-documenting

This approach is more resilient than directly accessing process.env.

test/OSSObject.test.ts (5)

3-8: Good practice: Organized imports for better readability.

The reworked import statements clearly separate core Node.js modules from third-party dependencies, making the dependencies more obvious at a glance.


15-28: Migration to Vitest testing framework.

Correctly updated imports to use Vitest testing functions instead of Mocha. This change is consistent with the toolchain migration mentioned in the PR objectives.


38-39: Good practice: Using assert.ok for boolean checks.

Replacing direct assert calls with assert.ok for boolean checks is more explicit about the intention of the assertion, improving code readability.

Also applies to: 78-84, 91-93, 137-140, 179-180, 316-317, 327-328, 341-342, 356-357, 368-369


50-71: Updated lifecycle hooks from Mocha to Vitest.

Correctly migrated from Mocha's before/after to Vitest's beforeAll/afterAll hooks, which is necessary for compatibility with the new testing framework.

Also applies to: 230-251


501-513: Improved assertion callback formatting.

The refactored assert.rejects blocks are more readable with properly indented callback functions, making the error-handling tests easier to follow.

Also applies to: 615-633, 659-670, 680-688, 851-866, 872-880, 1010-1018, 1051-1062, 1199-1210, 1252-1266, 1598-1608, 1672-1682, 1730-1749, 1792-1805, 2152-2161, 2287-2303

package.json (3)

9-16: Well-structured NPM scripts for the new toolchain.

The scripts have been appropriately updated to use the new tools:

  • lint now uses oxlint instead of ESLint
  • Added pretest to run linting with auto-fix before tests
  • Modified test and cov commands to use Vitest instead of egg-bin
  • Added prepare script for Husky Git hooks integration

These changes align perfectly with the PR objective of migrating to Prettier, OXLint, and Vitest.


18-23: Good configuration for lint-staged.

The lint-staged configuration ensures that:

  1. All files are formatted with Prettier
  2. TypeScript, JavaScript, JSON, Markdown, and YAML files are also checked and fixed with OXLint

This setup enforces code quality standards at commit time, which is a best practice for maintaining consistent code style across the project.


57-67: Appropriate dependency updates for the new toolchain.

The updated dependencies reflect the migration from ESLint and egg-bin to OXLint, Prettier, and Vitest:

  • Added @vitest/coverage-v8 for test coverage reporting
  • Added husky for Git hooks management
  • Added oxlint for linting
  • Added prettier for code formatting
  • Added read-env-value for type-safe environment variable handling
  • Updated TypeScript to a newer version
  • Added vitest as the testing framework

These changes are consistent with the PR objectives and ensure the project uses modern tooling.

.oxlintrc.json (1)

26-34:

Details

❓ Verification inconclusive

File is not valid JSON – comments trigger JSON parser errors

The file extension is .json, but inline // comments violate the JSON spec and are flagged by Biome. Unless oxlint explicitly supports “JSONC”, this will prevent the linter from loading.

Options:

  1. Rename to .oxlintrc.jsonc / .oxlintrc.json5 (if supported by oxlint).
  2. Keep the name but switch to pure JSON – move comments to project docs instead.

Failing to load this config will silently disable the very rules we expect.


Invalid JSON in .oxlintrc.json (comments will break parsing)

The .oxlintrc.json file currently includes // comments (e.g. lines 26–34), which are not valid in standard JSON. If OXLint (via Biome) doesn’t support JSONC/JSON5, the config will fail to load and may silently disable your lint rules.

Suggestions:

  • Rename the file to .oxlintrc.jsonc or .oxlintrc.json5 if your version of OXLint/Biome supports JSONC/JSON5 syntax.
  • Otherwise, remove all inline comments and move them into project documentation so the file remains pure JSON.

Please verify whether your OXLint/Biome version supports JSONC before renaming or stripping comments.

🧰 Tools
🪛 Biome (1.9.4)

[error] 26-26: Expected a property but instead found '// eslint'.

Expected a property here.

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 27-27: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 28-28: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 29-29: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 31-31: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 32-32: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 33-33: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 34-34: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

Comment on lines 1545 to 1546
);
const { size } = await stat(__filename);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix test failures in file operations.

The pipeline is showing failures in tests involving file streams and error handling:

Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should store object to local file'.
Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should escape uri path ok'.
Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should store object to writeStream'.
AssertionError: Expected error code 'NoSuchKey' but received 'ERR_STREAM_UNABLE_TO_PIPE' in 'should store not exists object to file'.

These errors suggest issues with stream handling that need to be addressed when migrating to the new testing framework.

Consider updating the implementation to properly handle stream errors and cleanup, ensuring streams are properly closed when errors occur:

-  await assert.rejects(
-    async () => {
-      await ossObject.get(`${name}not-exists`, savePath);
-    },
-    (err: OSSClientError) => {
-      assert.equal(err.code, 'NoSuchKey');
-      assert.equal(err.status, 404);
-      assert.ok(!existsSync(savePath));
-      return true;
-    }
-  );
+  await assert.rejects(
+    async () => {
+      try {
+        await ossObject.get(`${name}not-exists`, savePath);
+      } catch (err) {
+        // Ensure any created streams are properly closed
+        throw err;
+      }
+    },
+    (err: OSSClientError | Error) => {
+      // Handle both OSSClientError and stream errors
+      if ('code' in err) {
+        assert.equal(err.code, 'NoSuchKey');
+        assert.equal((err as OSSClientError).status, 404);
+      }
+      assert.ok(!existsSync(savePath));
+      return true;
+    }
+  );

Also applies to: 1559-1562, 1588-1594, 1597-1609

🧰 Tools
🪛 GitHub Actions: Node.js CI

[error] 1546-1546: Error 'Cannot pipe to a closed or destroyed stream' occurred in 'should store object to local file'.

Comment on lines +75 to 78
(headers['content-md5'] as string) ?? '',
headers['content-type'] as string,
expiresTimestamp || (headers['x-oss-date'] as string),
];
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

content-type may be undefined – pushes literal 'undefined' into the string-to-sign

If the caller omits a Content-Type header the expression

headers['content-type'] as string

inserts the string “undefined”, changing the canonical string and producing an invalid signature.
Use an empty string fallback, mirroring content-md5 handling:

-  (headers['content-type'] as string,
+  (headers['content-type'] as string) ?? '',

@codecov
Copy link

codecov bot commented May 10, 2025

Codecov Report

Attention: Patch coverage is 93.18735% with 28 lines in your changes missing coverage. Please review.

Project coverage is 91.40%. Comparing base (ad9346f) to head (f2a92e5).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
src/OSSBaseClient.ts 82.52% 18 Missing ⚠️
src/OSSObject.ts 97.29% 6 Missing ⚠️
src/util/encodeCallback.ts 50.00% 3 Missing ⚠️
src/util/checkBucketName.ts 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #27      +/-   ##
==========================================
- Coverage   94.39%   91.40%   -2.99%     
==========================================
  Files          17       15       -2     
  Lines        1891     1443     -448     
  Branches      282      291       +9     
==========================================
- Hits         1785     1319     -466     
- Misses        106      124      +18     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@fengmk2 fengmk2 merged commit d411a9f into master May 10, 2025
7 of 9 checks passed
@fengmk2 fengmk2 deleted the vitest branch May 10, 2025 05:14
fengmk2 pushed a commit that referenced this pull request May 10, 2025
[skip ci]

## [2.5.0](v2.4.0...v2.5.0) (2025-05-10)

### Features

* use prettier, oxlint and vitest ([#27](#27)) ([d411a9f](d411a9f))
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.

2 participants