Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
d4f641f
Added package copy command
roll Aug 12, 2025
c005b89
Added visidata guide
roll Aug 12, 2025
cdcf082
Renamed package load to show
roll Aug 12, 2025
774870e
Added package archive command
roll Aug 12, 2025
10412f5
Bootstrapped stricli
roll Aug 13, 2025
9b36bb4
Added new cli stack
roll Aug 13, 2025
1cd3e3c
Migrated to commander
roll Aug 13, 2025
110c20f
Bootstrapped -p/--package option
roll Aug 13, 2025
688291b
Fixed task
roll Aug 13, 2025
55b67cd
Implemented session helpers
roll Aug 14, 2025
1887e9c
Implemented selectResource helper
roll Aug 14, 2025
2f8e6f0
Added dialect helpers
roll Aug 14, 2025
803b5f1
Fixed help messages
roll Aug 14, 2025
ecfd332
Updated dialect infer
roll Aug 14, 2025
5c99fdb
Rebased on joint render
roll Aug 14, 2025
5ff6586
Improved session into/outro
roll Aug 14, 2025
856a85f
Bootstrapped validate commands
roll Aug 14, 2025
f19463b
Exlude compile from tsconfig
roll Aug 14, 2025
0672d19
Added dialect show command
roll Aug 14, 2025
f5cd179
Implemented validate dialect
roll Aug 14, 2025
1b6a5cd
Added more grids
roll Aug 14, 2025
3a6884e
Implemented resource commands
roll Aug 14, 2025
723f41a
Implemented schema commands
roll Aug 14, 2025
65229eb
Renamed describe to stats
roll Aug 14, 2025
64448f0
Split table errors/validate
roll Aug 14, 2025
aa8811b
Added dialect errors command
roll Aug 14, 2025
c8d3944
Added other error commands
roll Aug 14, 2025
82c6a89
Rebased other table commands on session
roll Aug 14, 2025
6a59135
Update package commands
roll Aug 14, 2025
8a8e4ab
Implemented file copy command
roll Aug 15, 2025
8625015
Implemened describeFile
roll Aug 15, 2025
bf45ce5
Implemented file stats command
roll Aug 15, 2025
e4c9393
Removed extend/ui packages
roll Aug 15, 2025
5ce4e6d
Renamed to inferResourceFormat
roll Aug 15, 2025
383d155
Implemented inferResourceName
roll Aug 15, 2025
da1fd7d
Implemented proper infer resource
roll Aug 15, 2025
5c469f8
Implemented inferPackage
roll Aug 15, 2025
a456b84
Implemented infer package
roll Aug 15, 2025
22ec124
Boostrapped validateResource
roll Aug 15, 2025
6a5a9da
Moved metadata erorrs to its own folder
roll Aug 15, 2025
2b47793
Added file errors
roll Aug 15, 2025
2b197fb
Implemente validateFile
roll Aug 15, 2025
4f5cda2
Implemented validateResource
roll Aug 15, 2025
777016c
Implemented resource validate command
roll Aug 15, 2025
e981603
Fixed validateFile
roll Aug 15, 2025
6617b25
Implemented validatePackage
roll Aug 15, 2025
d555fe9
Implemented package validate command
roll Aug 15, 2025
ebcc970
Fixed spinner cancel behavior
roll Aug 18, 2025
192fe88
Added completion todo
roll Aug 18, 2025
af6b78a
Implemented publish command
roll Aug 18, 2025
4112d19
Show errors by type in validate
roll Aug 19, 2025
a85f6c9
Implemented file validate command
roll Aug 19, 2025
73faa70
Implemented file errors command
roll Aug 19, 2025
03262c1
Updated validatePackage
roll Aug 19, 2025
d3aa87e
Bootstrapped validatePackage update
roll Aug 19, 2025
49f3a25
Added resource to package validation
roll Aug 19, 2025
ab32599
Normalized validation json output
roll Aug 19, 2025
599205f
Added plugins support for validatePackage
roll Aug 19, 2025
902bf7b
Rebased on resource/type grouping
roll Aug 19, 2025
195b2ba
Fixed cli compilation
roll Aug 19, 2025
33c279a
Added changeset
roll Aug 19, 2025
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
18 changes: 18 additions & 0 deletions .changeset/eleven-pillows-eat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@dpkit/parquet": minor
"@dpkit/folder": minor
"@dpkit/github": minor
"@dpkit/zenodo": minor
"@dpkit/arrow": minor
"dpkit": minor
"@dpkit/table": minor
"@dpkit/ckan": minor
"@dpkit/core": minor
"@dpkit/file": minor
"@dpkit/json": minor
"@dpkit/cli": minor
"@dpkit/csv": minor
"@dpkit/zip": minor
---

Improved CLI implementation
4 changes: 2 additions & 2 deletions arrow/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Resource } from "@dpkit/core"
import { inferFormat } from "@dpkit/core"
import { inferResourceFormat } from "@dpkit/core"
import type { TablePlugin } from "@dpkit/table"
import type { SaveTableOptions, Table } from "@dpkit/table"
import { loadArrowTable, saveArrowTable } from "./table/index.ts"
Expand All @@ -21,6 +21,6 @@ export class ArrowPlugin implements TablePlugin {
}

function getIsArrow(resource: Partial<Resource>) {
const format = inferFormat(resource)
const format = inferResourceFormat(resource)
return format === "arrow" || format === "feather"
}
10 changes: 5 additions & 5 deletions ckan/package/save.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ export async function savePackageToCkan(
basepath,
withRemote: true,
withoutFolders: true,
saveFile: async props => {
const filename = getFilename(props.normalizedPath)
saveFile: async options => {
const filename = getFilename(options.normalizedPath)
const ckanResource = denormalizeCkanResource(resource)

const payload = {
...ckanResource,
package_id: datasetName,
name: props.denormalizedPath,
name: options.denormalizedPath,
format: getFormat(filename)?.toUpperCase(),
}

const upload = {
name: props.denormalizedPath,
data: await blob(await loadFileStream(props.normalizedPath)),
name: options.denormalizedPath,
data: await blob(await loadFileStream(options.normalizedPath)),
}

const result = await makeCkanApiRequest<CkanResource>({
Expand Down
6 changes: 0 additions & 6 deletions cli/.oclifrc.js

This file was deleted.

3 changes: 3 additions & 0 deletions cli/commander.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "commander" {
export * from "@commander-js/extra-typings"
}
62 changes: 62 additions & 0 deletions cli/commands/dialect/errors.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Command } from "commander"
import { loadDescriptor, validateDialect } from "dpkit"
import type { Descriptor } from "dpkit"
import React from "react"
import { ReportGrid } from "../../components/ReportGrid.tsx"
import { helpConfiguration } from "../../helpers/help.ts"
import { selectResource } from "../../helpers/resource.ts"
import { Session } from "../../helpers/session.ts"
import * as params from "../../params/index.ts"

export const errorsDialectCommand = new Command("errors")
.configureHelp(helpConfiguration)
.description("Show errors for a table dialect from a local or remote path")

.addArgument(params.positionalTablePath)
.addOption(params.fromPackage)
.addOption(params.fromResource)
.addOption(params.json)

.action(async (path, options) => {
const session = Session.create({
title: "Dialect errors",
json: options.json,
})

let descriptor: Descriptor | undefined

if (!path) {
const resource = await selectResource(session, options)

if (!resource.dialect) {
Session.terminate("Dialect is not available")
}

if (typeof resource.dialect !== "string") {
descriptor = resource.dialect as Descriptor
} else {
path = resource.dialect
}
}

if (!descriptor) {
const result = await session.task(
"Loading dialect",
// @ts-ignore
loadDescriptor(path),
)

descriptor = result.descriptor
}

const report = await session.task(
"Finding errors",
validateDialect(descriptor),
)

if (report.valid) {
session.success("Dialect is valid")
}

session.render(report, <ReportGrid report={report} />)
})
15 changes: 15 additions & 0 deletions cli/commands/dialect/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Command } from "commander"
import { helpConfiguration } from "../../helpers/help.ts"
import { errorsDialectCommand } from "./errors.tsx"
import { inferDialectCommand } from "./infer.tsx"
import { showDialectCommand } from "./show.tsx"
import { validateDialectCommand } from "./validate.tsx"

export const dialectCommand = new Command("dialect")
.configureHelp(helpConfiguration)
.description("Table Dialect related commands")

.addCommand(errorsDialectCommand)
.addCommand(inferDialectCommand)
.addCommand(showDialectCommand)
.addCommand(validateDialectCommand)
29 changes: 0 additions & 29 deletions cli/commands/dialect/infer.ts

This file was deleted.

34 changes: 34 additions & 0 deletions cli/commands/dialect/infer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Command } from "commander"
import { inferDialect } from "dpkit"
import React from "react"
import { DialectGrid } from "../../components/DialectGrid.tsx"
import { helpConfiguration } from "../../helpers/help.ts"
import { isEmptyObject } from "../../helpers/object.ts"
import { selectResource } from "../../helpers/resource.ts"
import { Session } from "../../helpers/session.ts"
import * as params from "../../params/index.ts"

export const inferDialectCommand = new Command("infer")
.configureHelp(helpConfiguration)
.description("Infer a table dialect from a table")

.addArgument(params.positionalTablePath)
.addOption(params.fromPackage)
.addOption(params.fromResource)
.addOption(params.json)

.action(async (path, options) => {
const session = Session.create({
title: "Infer dialect",
json: options.json,
})

const resource = path ? { path } : await selectResource(session, options)

const dialect = await session.task("Loading sample", inferDialect(resource))
if (isEmptyObject(dialect)) {
Session.terminate("Could not infer dialect")
}

await session.render(dialect, <DialectGrid dialect={dialect} />)
})
52 changes: 52 additions & 0 deletions cli/commands/dialect/show.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Command } from "commander"
import { loadDialect } from "dpkit"
import type { Dialect } from "dpkit"
import React from "react"
import { DialectGrid } from "../../components/DialectGrid.tsx"
import { helpConfiguration } from "../../helpers/help.ts"
import { isEmptyObject } from "../../helpers/object.ts"
import { selectResource } from "../../helpers/resource.ts"
import { Session } from "../../helpers/session.ts"
import * as params from "../../params/index.ts"

export const showDialectCommand = new Command("show")
.configureHelp(helpConfiguration)
.description("Show a table dialect from a local or remote path")

.addArgument(params.positionalTablePath)
.addOption(params.fromPackage)
.addOption(params.fromResource)
.addOption(params.json)

.action(async (path, options) => {
const session = Session.create({
title: "Show dialect",
json: options.json,
})

let dialect: Dialect | undefined

if (!path) {
const resource = await selectResource(session, options)
if (!resource.dialect) {
Session.terminate("Dialect is not available")
}

if (typeof resource.dialect !== "string") {
dialect = resource.dialect
} else {
path = resource.dialect
}
}

if (!dialect) {
// @ts-ignore
dialect = await session.task("Loading dialect", loadDialect(path))
}

if (isEmptyObject(dialect)) {
Session.terminate("Dialect is not available")
}

await session.render(dialect, <DialectGrid dialect={dialect} />)
})
63 changes: 63 additions & 0 deletions cli/commands/dialect/validate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Command } from "commander"
import { loadDescriptor, validateDialect } from "dpkit"
import type { Descriptor } from "dpkit"
import React from "react"
import { ReportGrid } from "../../components/ReportGrid.tsx"
import { helpConfiguration } from "../../helpers/help.ts"
import { selectResource } from "../../helpers/resource.ts"
import { Session } from "../../helpers/session.ts"
import * as params from "../../params/index.ts"

export const validateDialectCommand = new Command("validate")
.configureHelp(helpConfiguration)
.description("Validate a table dialect from a local or remote path")

.addArgument(params.positionalTablePath)
.addOption(params.fromPackage)
.addOption(params.fromResource)
.addOption(params.json)

.action(async (path, options) => {
const session = Session.create({
title: "Validate dialect",
json: options.json,
})

let descriptor: Descriptor | undefined

if (!path) {
const resource = await selectResource(session, options)

if (!resource.dialect) {
Session.terminate("Dialect is not available")
}

if (typeof resource.dialect !== "string") {
descriptor = resource.dialect as Descriptor
} else {
path = resource.dialect
}
}

if (!descriptor) {
const result = await session.task(
"Loading dialect",
// @ts-ignore
loadDescriptor(path),
)

descriptor = result.descriptor
}

const report = await session.task(
"Validating dialect",
// @ts-ignore
validateDialect(descriptor),
)

if (report.valid) {
session.success("Dialect is valid")
}

session.render(report, <ReportGrid report={report} groupBy="type" />)
})
41 changes: 41 additions & 0 deletions cli/commands/file/copy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Command } from "commander"
import { copyFile } from "dpkit"
import { helpConfiguration } from "../../helpers/help.ts"
import { selectResource } from "../../helpers/resource.ts"
import { Session } from "../../helpers/session.ts"
import * as params from "../../params/index.ts"

export const copyFileCommand = new Command("copy")
.configureHelp(helpConfiguration)
.description("Copy a local or remote file to a local path")

.addArgument(params.positionalFilePath)
.addOption(params.toPath.makeOptionMandatory())
.addOption(params.fromPackage)
.addOption(params.fromResource)

.action(async (path, options) => {
const session = Session.create({
title: "Copy file",
})

if (!path) {
const resource = await selectResource(session, options)

if (typeof resource.path !== "string") {
Session.terminate("Only single file resources are supported")
}

path = resource.path
}

await session.task(
"Copying file",
copyFile({
sourcePath: path,
targetPath: options.toPath,
}),
)

session.success(`File from "${path}" copied to "${options.toPath}"`)
})
Loading