Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/pin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export interface PinAddOptions extends HTTPRPCOptions {
* Internal option used to control whether to create a repo write lock during a pinning operation
*/
lock?: boolean

/**
* An optional name for created pin(s)
*/
name?: string
}

export interface PinAddAllOptions extends HTTPRPCOptions {
Expand Down Expand Up @@ -68,12 +73,14 @@ export type PinQueryType = 'recursive' | 'direct' | 'indirect' | 'all'
export interface PinLsOptions extends HTTPRPCOptions {
paths?: CID | CID[] | string | string[]
type?: PinQueryType
name?: string
}

export interface PinLsResult {
cid: CID
type: PinType | string
metadata?: Record<string, any>
name?: string
Copy link
Member

Choose a reason for hiding this comment

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

If Kubo doesn’t return this field, does it need to be in the interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Kubo does return it if you call pin.ls with the name param. Otherwise not. So yes it needs to be there as optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the reason it's not returned by default is that one CID can have multiple names it's pinned under.

Copy link
Member

Choose a reason for hiding this comment

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

Aha, gotcha - so it just needs a test that shows this then all is good.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, so now we test for both cases:

  • should list all types of pins tests that name isn't returned in the regular case
  • should list multiple partially matched named pins and should list specific named pin tests that name is returned

Copy link
Member

Choose a reason for hiding this comment

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

That's perfect, thanks for making those changes.

}

export interface PinRmOptions extends HTTPRPCOptions {
Expand Down
9 changes: 6 additions & 3 deletions src/pin/ls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type { PinAPI, PinLsResult } from './index.js'
import type { HTTPRPCClient } from '../lib/core.js'

function toPin (type: string, cid: string, metadata: Record<string, string>): PinLsResult {
function toPin (type: string, cid: string, metadata: Record<string, string>, name: string): PinLsResult {
const pin: PinLsResult = {
type,
cid: CID.parse(cid)
Expand All @@ -12,6 +12,9 @@
if (metadata != null) {
pin.metadata = metadata
}
if (name != null) {
pin.name = name
}

return pin
}
Expand All @@ -37,12 +40,12 @@
for await (const pin of res.ndjson()) {
if (pin.Keys != null) { // non-streaming response
for (const cid of Object.keys(pin.Keys)) {
yield toPin(pin.Keys[cid].Type, cid, pin.Keys[cid].Metadata)
yield toPin(pin.Keys[cid].Type, cid, pin.Keys[cid].Metadata, pin.Keys[cid].Name)

Check warning on line 43 in src/pin/ls.ts

View check run for this annotation

Codecov / codecov/patch

src/pin/ls.ts#L43

Added line #L43 was not covered by tests
}
return
}

yield toPin(pin.Type, pin.Cid, pin.Metadata)
yield toPin(pin.Type, pin.Cid, pin.Metadata, pin.Name)
}
}
}
28 changes: 26 additions & 2 deletions test/interface-tests/src/pin/ls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export function testLs (factory: Factory<KuboNode>, options: MochaConfig): void
await ipfs.pin.add(fixtures.directory.cid, { recursive: true })
// a file (CID pinned recursively)
await ipfs.add(fixtures.files[0].data, { pin: false, cidVersion: 0 })
await ipfs.pin.add(fixtures.files[0].cid, { recursive: true })
await ipfs.pin.add(fixtures.files[0].cid, { recursive: true, name: fixtures.files[0].pinName })
// a single CID (pinned directly)
await ipfs.add(fixtures.files[1].data, { pin: false, cidVersion: 0 })
await ipfs.pin.add(fixtures.files[1].cid, { recursive: false })
await ipfs.pin.add(fixtures.files[1].cid, { recursive: false, name: fixtures.files[1].pinName })
})

after(async function () {
Expand Down Expand Up @@ -174,6 +174,30 @@ export function testLs (factory: Factory<KuboNode>, options: MochaConfig): void
expect(cids).to.include(fixtures.files[1].cid.toString())
})

it('should list multiple partially matched named pins', async () => {
const pinset = await all(ipfs.pin.ls({
name: 'file'
}))
expect(pinset).to.have.lengthOf(2)
const cids = pinset.map(p => p.cid.toString())
expect(cids).to.include(fixtures.files[0].cid.toString())
expect(cids).to.include(fixtures.files[1].cid.toString())
const names = pinset.map(p => p.name)
expect(names).to.include(fixtures.files[0].pinName)
expect(names).to.include(fixtures.files[1].pinName)
})

it('should list specific named pin', async () => {
const pinset = await all(ipfs.pin.ls({
name: fixtures.files[0].pinName
}))
expect(pinset).to.have.lengthOf(1)
const cids = pinset.map(p => p.cid.toString())
expect(cids).to.include(fixtures.files[0].cid.toString())
const names = pinset.map(p => p.name)
expect(names).to.include(fixtures.files[0].pinName)
})

it('should throw error for invalid non-string pin type option', () => {
// @ts-expect-error wrong pin type
return expect(all(ipfs.pin.ls({ type: 6 })))
Expand Down
6 changes: 4 additions & 2 deletions test/interface-tests/src/pin/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ export const fixtures = Object.freeze({
}),
files: Object.freeze([Object.freeze({
data: uint8ArrayFromString('Plz add me!\n'),
cid: CID.parse('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
cid: CID.parse('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP'),
pinName: 'file-1'
}), Object.freeze({
data: loadFixture('test/interface-tests/fixtures/test-folder/files/hello.txt'),
cid: CID.parse('QmY9cxiHqTFoWamkQVkpmmqzBrY3hCBEL2XNu3NtX74Fuu')
cid: CID.parse('QmY9cxiHqTFoWamkQVkpmmqzBrY3hCBEL2XNu3NtX74Fuu'),
pinName: 'file-2'
})])
})

Expand Down
Loading