Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"devDependencies": {
"mocha": "^10.1.0",
"prettier": "2.8.8",
"typescript": "^5.0.4"
"typescript": "^5.0.4",
"entail": "^2.1.2"
},
"prettier": {
"trailingComma": "es5",
Expand Down
4 changes: 3 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"test:web": "playwright-test test/*.spec.js --cov && nyc report",
"test:node": "c8 --check-coverage --branches 100 --functions 100 --lines 100 mocha test/*.spec.js",
"test": "c8 --check-coverage --branches 100 --functions 100 --lines 100 mocha --bail test/*.spec.js",
"test:policy": "c8 --check-coverage --branches 100 --functions 100 --lines 100 entail test/policy/*.spec.js",
"coverage": "c8 --reporter=html mocha test/*.spec.js && npm_config_yes=true npx st -d coverage -p 8080",
"check": "tsc --build",
"build": "tsc --build"
Expand All @@ -44,7 +45,8 @@
"mocha": "^10.1.0",
"nyc": "^15.1.0",
"playwright-test": "^8.2.0",
"typescript": "^5.0.4"
"typescript": "^5.0.4",
"entail": "^2.1.2"
},
"type": "module",
"main": "src/lib.js",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * as DID from '@ipld/dag-ucan/did'
export * as Signature from '@ipld/dag-ucan/signature'
export * from './result.js'
export * as Schema from './schema.js'
export * as Selector from './policy/selector.js'
1 change: 1 addition & 0 deletions packages/core/src/policy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as Selector from './policy/selector.js'
1 change: 1 addition & 0 deletions packages/core/src/policy/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {}
102 changes: 102 additions & 0 deletions packages/core/src/policy/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import type { Variant, Result, Phantom } from '@ucanto/interface'

export type { Variant, Result }

export type SelectorParseResult = Result<SelectorPath, ParseError>

export interface ParseError extends Error {
readonly name: 'ParseError'
}

export interface ResolutionError extends Error {
readonly name: 'ResolutionError'
}

/**
* Selector use [jq](https://devdocs.io/jq/) notation.
*/
export type Selector = `.${string}` & Phantom<{ Selector: SelectorPath }>
export type SelectorPath = [{ Identity: {} }, ...SelectorSegment[]]

export type SelectionResult = Variant<{
one: Data
many: Data[]
error: ParseError | ResolutionError
}>

export type ResolutionResult = Variant<{
one: Data
many: Data[]
error: ResolutionError
}>

export type SelectorSegment = Variant<{
Identity: {}
Iterator: { optional: boolean }
Index: { optional: boolean; index: number }
Key: { optional: boolean; key: string }
Slice: {
optional?: boolean
range: [undefined, number] | [number, undefined] | [number, number]
}
}>

export type Data =
| number
| string
| boolean
| null
| Uint8Array
| ListData
| Dictionary

export interface ListData extends Array<Data> {}
export interface Dictionary {
[key: string]: Data
}

/**
* Represents an identity selector per jq.
* @see https://devdocs.io/jq/index#identity
*
* @example
* ```js
* assert.deepEqual(
* select('.', {x: 1}),
* { one: { x: 1 } }
* )
* ```
*/
export type IdentitySegment = '.' & Phantom<{ Identity: '.' }>

/**
* Selector that returns all elements of an array. Selecting `.[]` from
* `[1,2,3]` will produce selection containing those numbers. The form `.foo.[]`
* is identical to `.foo[]`.
*
* You can also use the `[]` on the object, and it will return all the values of
* the object.
*
* @example
* ```js
* assert.deepEqual(
* select('.[]', [
* {"name":"JSON", "good":true},
* {"name":"XML", "good":false}
* ]),
* {
* many: [
* {"name":"JSON", "good":true},
* {"name":"XML", "good":false}
* ]
* }
* )
* ```
*/
export type IteratorSegment = '[]' & Phantom<{ Iterator: '[]' }>

export type IndexSegment = number & Phantom<{ Index: number }>

export type KeySegment = string & Phantom<{ Key: string }>

export type SliceSegment = [start?: number, end?: number]
Loading