Skip to content

Commit

Permalink
feat: Export low-level API & CLI commands
Browse files Browse the repository at this point in the history
  • Loading branch information
franky47 committed Dec 16, 2022
1 parent b3f1fa2 commit 20f90ca
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 13 deletions.
35 changes: 31 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,39 @@ $ sceau verify --strict

## Programmatic usage

Sceau can be imported as a library (ESM-only):
Sceau can be imported as a library (ESM only).

```ts
import { initializeSodium, keygen, sign, verify } from 'sceau'
You can access the commands using the same arguments as the CLI:

// todo: Add programmatic usage docs
```ts
import {
generateKeyPair,
signCommand,
verifyCommand,
SCEAU_FILE_NAME,
} from 'sceau'

// Random keypair
const { publicKey, privateKey } = await generateKeyPair()

// Seeded keypair
const { publicKey, privateKey } = await generateKeyPair('baadf00d...')

await signCommand({
file: SCEAU_FILE_NAME,
quiet: true,
privateKey: '...', // will default to SCEAU_PRIVATE_KEY env if unspecified
packageDir: 'packages/my-package',
build: 'https://url-to-build-process.example.com',
source: 'https://url-to-sources.example.com',
})

await verifyCommand({
file: SCEAU_FILE_NAME,
strict: true,
packageDir: 'packages/my-package',
publicKey: '...', // will default to SCEAU_PUBLIC_KEY env if unspecified
})
```

## Examples
Expand Down
15 changes: 10 additions & 5 deletions src/cli/args.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import chalk from 'chalk'
import minimist from 'minimist'
import { z } from 'zod'
import { SCEAU_FILE_NAME } from '../constants'
import { hexStringSchema } from '../lib'

const keygenCommandSchema = z.object({
Expand All @@ -9,12 +10,13 @@ const keygenCommandSchema = z.object({
compact: z.boolean().optional().default(false),
})

export type KeygenCommandArgs = z.infer<typeof keygenCommandSchema>
export type KeygenCommandArgs = Omit<
z.infer<typeof keygenCommandSchema>,
'command'
>

// --

export const SCEAU_FILE_NAME = 'sceau.json'

const signCommandSchema = z.object({
command: z.literal('sign'),
build: z.string().url().optional(),
Expand All @@ -25,7 +27,7 @@ const signCommandSchema = z.object({
quiet: z.boolean().optional().default(false),
})

export type SignCommandArgs = z.infer<typeof signCommandSchema>
export type SignCommandArgs = Omit<z.infer<typeof signCommandSchema>, 'command'>

// --

Expand All @@ -37,7 +39,10 @@ const verifyCommandSchema = z.object({
strict: z.boolean().optional().default(false),
})

export type VerifyCommandArgs = z.infer<typeof verifyCommandSchema>
export type VerifyCommandArgs = Omit<
z.infer<typeof verifyCommandSchema>,
'command'
>

// --

Expand Down
8 changes: 6 additions & 2 deletions src/cli/commands/keygen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import { initializeSodium } from '../../crypto/sodium'
import { keygen } from '../../lib'
import type { KeygenCommandArgs } from '../args'

export async function keygenCommand(args: KeygenCommandArgs) {
export async function generateKeyPair(seed: KeygenCommandArgs['seed']) {
const sodium = await initializeSodium()
const keypair = keygen(sodium, args.seed)
return keygen(sodium, seed)
}

export async function keygenCommand(args: KeygenCommandArgs) {
const keypair = await generateKeyPair(args.seed)
if (args.compact) {
console.info(keypair.privateKey)
} else {
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export async function signCommand(args: SignCommandArgs) {
const packageDir = args.packageDir ?? process.cwd()
const sodium = await initializeSodium()
const sceau = await sign(sodium, {
timestamp: new Date(),
packageDir,
privateKey,
buildURL,
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const SCEAU_FILE_NAME = 'sceau.json'
10 changes: 9 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
export type { SignCommandArgs, VerifyCommandArgs } from './cli/args'
// CLI command interfaces
export { generateKeyPair } from './cli/commands/keygen'
export { signCommand } from './cli/commands/sign'
export { verifyCommand } from './cli/commands/verify'
// Low-level API
export { SCEAU_FILE_NAME } from './constants'
export { initializeSodium } from './crypto/sodium'
export { keygen, sign, verify } from './lib'
export { keygen, sceauSchema, sign, verify } from './lib'
export type { Sceau } from './lib'
16 changes: 15 additions & 1 deletion src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,22 @@ const signInputSchema = sceauSchema
buildURL: true,
})
.extend({
timestamp: z.date(),

/**
* Absolute path to the package to sign
*/
packageDir: z.string(),

/**
* Ed25519 private key to use for signature (64 bytes hex encoded)
*/
privateKey: hexStringSchema(64),
/** A list of files to omit from the manifest
*
* Note that this should always include the sceau file itself,
* otherwise signature will be impossible (running in circles).
*/
ignoreFiles: z.array(z.string()).default([]),
})

Expand All @@ -186,7 +200,7 @@ export async function sign(sodium: Sodium, input: SignInput) {
secretKey
)
const $schema = V1_SCHEMA_URL
const timestamp = new Date().toISOString()
const timestamp = input.timestamp.toISOString()
const signature = multipartSignature(
sodium,
secretKey,
Expand Down

0 comments on commit 20f90ca

Please sign in to comment.