Skip to content

Commit df1d483

Browse files
authored
feat: support name in pin.ls (#260)
According to the [Kubo docs](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-pin-ls) (and practical experience) the pin label (name) is returned top level on the pin item (not in Metadata).
1 parent b1ec205 commit df1d483

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

src/pin/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ export interface PinAddOptions extends HTTPRPCOptions {
2323
* Internal option used to control whether to create a repo write lock during a pinning operation
2424
*/
2525
lock?: boolean
26+
27+
/**
28+
* An optional name for created pin(s)
29+
*/
30+
name?: string
2631
}
2732

2833
export interface PinAddAllOptions extends HTTPRPCOptions {
@@ -68,12 +73,14 @@ export type PinQueryType = 'recursive' | 'direct' | 'indirect' | 'all'
6873
export interface PinLsOptions extends HTTPRPCOptions {
6974
paths?: CID | CID[] | string | string[]
7075
type?: PinQueryType
76+
name?: string
7177
}
7278

7379
export interface PinLsResult {
7480
cid: CID
7581
type: PinType | string
7682
metadata?: Record<string, any>
83+
name?: string
7784
}
7885

7986
export interface PinRmOptions extends HTTPRPCOptions {

src/pin/ls.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { toUrlSearchParams } from '../lib/to-url-search-params.js'
33
import type { PinAPI, PinLsResult } from './index.js'
44
import type { HTTPRPCClient } from '../lib/core.js'
55

6-
function toPin (type: string, cid: string, metadata: Record<string, string>): PinLsResult {
6+
function toPin (type: string, cid: string, metadata: Record<string, string>, name: string): PinLsResult {
77
const pin: PinLsResult = {
88
type,
99
cid: CID.parse(cid)
@@ -12,6 +12,9 @@ function toPin (type: string, cid: string, metadata: Record<string, string>): Pi
1212
if (metadata != null) {
1313
pin.metadata = metadata
1414
}
15+
if (name != null) {
16+
pin.name = name
17+
}
1518

1619
return pin
1720
}
@@ -37,12 +40,12 @@ export function createLs (client: HTTPRPCClient): PinAPI['ls'] {
3740
for await (const pin of res.ndjson()) {
3841
if (pin.Keys != null) { // non-streaming response
3942
for (const cid of Object.keys(pin.Keys)) {
40-
yield toPin(pin.Keys[cid].Type, cid, pin.Keys[cid].Metadata)
43+
yield toPin(pin.Keys[cid].Type, cid, pin.Keys[cid].Metadata, pin.Keys[cid].Name)
4144
}
4245
return
4346
}
4447

45-
yield toPin(pin.Type, pin.Cid, pin.Metadata)
48+
yield toPin(pin.Type, pin.Cid, pin.Metadata, pin.Name)
4649
}
4750
}
4851
}

test/interface-tests/src/pin/ls.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ export function testLs (factory: Factory<KuboNode>, options: MochaConfig): void
2424
await ipfs.pin.add(fixtures.directory.cid, { recursive: true })
2525
// a file (CID pinned recursively)
2626
await ipfs.add(fixtures.files[0].data, { pin: false, cidVersion: 0 })
27-
await ipfs.pin.add(fixtures.files[0].cid, { recursive: true })
27+
await ipfs.pin.add(fixtures.files[0].cid, { recursive: true, name: fixtures.files[0].pinName })
2828
// a single CID (pinned directly)
2929
await ipfs.add(fixtures.files[1].data, { pin: false, cidVersion: 0 })
30-
await ipfs.pin.add(fixtures.files[1].cid, { recursive: false })
30+
await ipfs.pin.add(fixtures.files[1].cid, { recursive: false, name: fixtures.files[1].pinName })
3131
})
3232

3333
after(async function () {
@@ -77,6 +77,7 @@ export function testLs (factory: Factory<KuboNode>, options: MochaConfig): void
7777
const pinset = await all(ipfs.pin.ls())
7878

7979
expect(pinset).to.not.be.empty()
80+
8081
// check the three "roots"
8182
expect(pinset).to.deep.include({
8283
type: 'recursive',
@@ -98,6 +99,11 @@ export function testLs (factory: Factory<KuboNode>, options: MochaConfig): void
9899
type: 'indirect',
99100
cid: fixtures.directory.files[1].cid
100101
})
102+
103+
// Verify each pin has no name property
104+
for (const pin of pinset) {
105+
expect(pin).to.not.have.property('name')
106+
}
101107
})
102108

103109
it('should list all direct pins', async () => {
@@ -174,6 +180,30 @@ export function testLs (factory: Factory<KuboNode>, options: MochaConfig): void
174180
expect(cids).to.include(fixtures.files[1].cid.toString())
175181
})
176182

183+
it('should list multiple partially matched named pins', async () => {
184+
const pinset = await all(ipfs.pin.ls({
185+
name: 'file'
186+
}))
187+
expect(pinset).to.have.lengthOf(2)
188+
const cids = pinset.map(p => p.cid.toString())
189+
expect(cids).to.include(fixtures.files[0].cid.toString())
190+
expect(cids).to.include(fixtures.files[1].cid.toString())
191+
const names = pinset.map(p => p.name)
192+
expect(names).to.include(fixtures.files[0].pinName)
193+
expect(names).to.include(fixtures.files[1].pinName)
194+
})
195+
196+
it('should list specific named pin', async () => {
197+
const pinset = await all(ipfs.pin.ls({
198+
name: fixtures.files[0].pinName
199+
}))
200+
expect(pinset).to.have.lengthOf(1)
201+
const cids = pinset.map(p => p.cid.toString())
202+
expect(cids).to.include(fixtures.files[0].cid.toString())
203+
const names = pinset.map(p => p.name)
204+
expect(names).to.include(fixtures.files[0].pinName)
205+
})
206+
177207
it('should throw error for invalid non-string pin type option', () => {
178208
// @ts-expect-error wrong pin type
179209
return expect(all(ipfs.pin.ls({ type: 6 })))

test/interface-tests/src/pin/utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ export const fixtures = Object.freeze({
3636
}),
3737
files: Object.freeze([Object.freeze({
3838
data: uint8ArrayFromString('Plz add me!\n'),
39-
cid: CID.parse('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP')
39+
cid: CID.parse('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP'),
40+
pinName: 'file-1'
4041
}), Object.freeze({
4142
data: loadFixture('test/interface-tests/fixtures/test-folder/files/hello.txt'),
42-
cid: CID.parse('QmY9cxiHqTFoWamkQVkpmmqzBrY3hCBEL2XNu3NtX74Fuu')
43+
cid: CID.parse('QmY9cxiHqTFoWamkQVkpmmqzBrY3hCBEL2XNu3NtX74Fuu'),
44+
pinName: 'file-2'
4345
})])
4446
})
4547

0 commit comments

Comments
 (0)