Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds capability for the feed command, to specify index #501

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@ethersphere/bee-js": "^6.7.3",
"@ethersphere/bee-js": "^6.9.1",
"@fairdatasociety/bmt-js": "^2.1.0",
"bignumber.js": "^9.1.0",
"chalk": "^2.4.2",
Expand Down
18 changes: 14 additions & 4 deletions src/command/feed/feed-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ export class FeedCommand extends RootCommand {
@Option({ key: 'password', alias: 'P', description: 'Password for the wallet' })
public password!: string

@Option({ key: 'index', description: 'Feed index to write to or read from', required: false })
public index!: number | undefined

protected async updateFeedAndPrint(chunkReference: string): Promise<string> {
const wallet = await this.getWallet()
const topic = this.topic || this.bee.makeFeedTopic(this.topicString)
const { reference, manifest } = await this.writeFeed(wallet, topic, chunkReference)
const { reference, manifest } = await this.writeFeed(wallet, topic, chunkReference, this.index)

this.console.verbose(createKeyValue('Chunk Reference', chunkReference))
this.console.verbose(createKeyValue('Chunk Reference URL', `${this.bee.url}/bzz/${chunkReference}/`))
Expand Down Expand Up @@ -79,16 +82,23 @@ export class FeedCommand extends RootCommand {
return identities[this.identity] || identities[await pickIdentity(this.commandConfig, this.console)]
}

private async writeFeed(wallet: Wallet, topic: string, chunkReference: string): Promise<FeedInfo> {
private async writeFeed(wallet: Wallet, topic: string, chunkReference: string, index?: number): Promise<FeedInfo> {
const spinner = createSpinner('Writing feed...')

if (this.verbosity !== VerbosityLevel.Quiet && !this.curl) {
spinner.start()
}

try {
const writer = this.bee.makeFeedWriter('sequence', topic, wallet.getPrivateKey())
const reference = await writer.upload(this.stamp, chunkReference as Reference)
let reference: Reference
if (index === undefined) {
// Index was not specified
reference = await writer.upload(this.stamp, chunkReference as Reference)
} else {
// Index was specified
reference = await writer.upload(this.stamp, chunkReference as Reference, { index: Number(index) })
}
const { reference: manifest } = await this.bee.createFeedManifest(
this.stamp,
'sequence',
Expand Down
15 changes: 14 additions & 1 deletion src/command/feed/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { getFieldOrNull } from '../../utils'
import { createSpinner } from '../../utils/spinner'
import { createKeyValue } from '../../utils/text'
import { FeedCommand } from './feed-command'
import { FetchFeedUpdateResponse } from '@ethersphere/bee-js/dist/types/modules/feed'

export class Print extends FeedCommand implements LeafCommand {
public readonly name = 'print'
Expand All @@ -28,12 +29,24 @@ export class Print extends FeedCommand implements LeafCommand {
await super.init()

const topic = this.topic || this.bee.makeFeedTopic(this.topicString)
const index: number | undefined = this.index
const spinner = createSpinner(`Looking up feed topic ${topic}`)
spinner.start()
try {
const addressString = this.address || (await this.getAddressString())
const reader = this.bee.makeFeedReader('sequence', topic, addressString)
const { reference, feedIndex, feedIndexNext } = await reader.download()

let result: FetchFeedUpdateResponse | null = null;
if (index === undefined) {
// Index was not specified
result = await reader.download()
} else {
// Index was specified
// typeof index is string, and we don't understand why. This is why we are doing this conversion.
result = await reader.download({ index: Number(index) })
}
if (!result) throw Error('Error downloading feed update')
const { reference, feedIndex, feedIndexNext } = result;

if (!this.stamp) {
spinner.stop()
Expand Down
2 changes: 1 addition & 1 deletion src/command/feed/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FeedCommand } from './feed-command'
export class Update extends FeedCommand implements LeafCommand {
public readonly name = 'update'

public readonly description = 'Update feed'
public readonly description = 'Update feed (with reference)'

@Option({ key: 'reference', alias: 'r', description: 'The new reference', required: true })
public reference!: string
Expand Down
2 changes: 1 addition & 1 deletion src/command/feed/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FeedCommand } from './feed-command'
export class Upload extends FeedCommand implements LeafCommand {
public readonly name = 'upload'

public readonly description = 'Upload to a feed'
public readonly description = 'Upload to a feed (file or folder)'

public feedManifest?: string

Expand Down
139 changes: 139 additions & 0 deletions test/command/feed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,145 @@ describeCommand(
expect(getLastMessage()).toContain('Number of Updates')
expect(getLastMessage()).toContain('2')
})


it('upload should write to correct index', async () => {
const identityName = 'test'
const topicName = 'test'
const password = 'test'
// create identity
await invokeTestCli(['identity', 'create', identityName, '--password', 'test'])
// upload data to index 22
await invokeTestCli([
'feed',
'upload',
`${__dirname}/../testpage/images/swarm.png`,
'--identity',
identityName,
'--topic-string',
topicName,
'--password',
password,
'--quiet',
'--index',
'22',
...getStampOption(),
])
// print with identity and password
await invokeTestCli([
'feed',
'print',
'--identity',
identityName,
'--topic-string',
topicName,
'--password',
password,
'--quiet',
'--index',
'22',
...getStampOption(),
])
expect(getLastMessage()).toMatch(/[a-z0-9]{64}/)

// Zero index should work as well
await invokeTestCli([
'feed',
'upload',
`${__dirname}/../testpage/images/swarm.png`,
'--identity',
identityName,
'--topic-string',
topicName,
'--password',
password,
'--quiet',
'--index',
'0',
...getStampOption(),
])
await invokeTestCli([
'feed',
'print',
'--identity',
identityName,
'--topic-string',
topicName,
'--password',
password,
'--quiet',
'--index',
'0',
...getStampOption(),
])
expect(getLastMessage()).toMatch(/[a-z0-9]{64}/)

// It should work without specifying the index as well
await invokeTestCli([
'feed',
'print',
'--identity',
identityName,
'--topic-string',
topicName,
'--password',
password,
'--quiet',
...getStampOption(),
])
expect(getLastMessage()).toMatch(/[a-z0-9]{64}/)
})

it('update should write to correct index', async () => {
const identityName = 'test'
const topicName = 'test'
const password = 'test'
// create identity
await invokeTestCli(['identity', 'create', 'test', '--password', 'test'])
// upload data and get reference
await invokeTestCli([
'upload',
`${__dirname}/../testpage/images/swarm.png`,
'--quiet',
...getStampOption(),
])
const reference = getLastMessage();
// update the feed with newly got reference
await invokeTestCli([
'feed',
'update',
'--reference',
reference,
'--identity',
identityName,
'--topic-string',
topicName,
'--password',
password,
'--quiet',
'--index',
'22',
...getStampOption(),
])

// print with identity and password
await invokeTestCli([
'feed',
'print',
'--identity',
'test',
'--topic-string',
'test',
'--password',
'test',
'--quiet',
'--index',
'22',
...getStampOption(),
])
expect(getLastMessage()).toMatch(/[a-z0-9]{64}/)
})

},
{ configFileName: 'feed' },
)