Comparing version 0.4.0-beta.2 to 1.0.0-0
{ | ||
"name": "groq-js", | ||
"version": "0.4.0-beta.2", | ||
"version": "1.0.0-0", | ||
"license": "MIT", | ||
"author": "Sanity.io <hello@sanity.io>", | ||
"main": "dist/groq-js.umd.js", | ||
"module": "dist/groq-js.esm.js", | ||
"main": "./dist/1.umd.cjs", | ||
"types": "./dist/1.umd.d.ts", | ||
"exports": { | ||
".": { | ||
"import": { | ||
"default": "./dist/1.esm.mjs", | ||
"types": "./dist/1.esm.d.ts" | ||
}, | ||
"require": { | ||
"default": "./dist/1.umd.cjs", | ||
"types": "./dist/1.umd.d.ts" | ||
} | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"files": [ | ||
@@ -14,4 +27,5 @@ "dist", | ||
"scripts": { | ||
"prepublishOnly": "vite build", | ||
"build": "vite build", | ||
"prepublishOnly": "npm run build", | ||
"build": "rimraf dist; rollup -c", | ||
"test:generate": "./test/generate.sh", | ||
"test": "tap --no-timeout test/*.test.*", | ||
@@ -21,4 +35,4 @@ "prettify": "prettier --write src/**/*.ts src/*.ts", | ||
}, | ||
"peerDependencies": {}, | ||
"devDependencies": { | ||
"@rollup/plugin-typescript": "^8.3.3", | ||
"@types/tap": "^15.0.5", | ||
@@ -31,9 +45,11 @@ "@typescript-eslint/eslint-plugin": "^4.22.1", | ||
"ndjson": "^2.0.0", | ||
"np": "^7.6.2", | ||
"prettier": "^2.2.1", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.75.7", | ||
"rollup-plugin-dts": "^4.2.2", | ||
"semver": "^7.3.5", | ||
"tap": "^15.0.6", | ||
"tslib": "^2.2.0", | ||
"typescript": "^4.2.4", | ||
"vite": "^2.7.1", | ||
"vite-dts": "^1.0.3" | ||
"typescript": "^4.2.4" | ||
}, | ||
@@ -40,0 +56,0 @@ "tap": { |
# GROQ-JS | ||
GROQ-JS is a (work-in-progress) JavaScript implementation of [GROQ](https://www.sanity.io/docs/data-store/how-queries-work) which follows the official specification. | ||
GROQ-JS is a JavaScript implementation of [GROQ](https://www.sanity.io/docs/data-store/how-queries-work) which follows the official specification. | ||
@@ -15,3 +15,3 @@ ```javascript | ||
{_type: 'user', name: 'Michael'}, | ||
{_type: 'company', name: 'Bluth Company'} | ||
{_type: 'company', name: 'Bluth Company'}, | ||
] | ||
@@ -54,14 +54,43 @@ | ||
## Versioning | ||
GROQ-JS follows [SemVer](https://semver.org) and is currently at version v0.2. | ||
### GROQ | ||
The GROQ spec version is independent of the groq-js library version. When you import groq-js you need to be explicit on which GROQ version you want to use. The GROQ version is tied to the [groq-spec](https://github.com/sanity-io/groq). This allows us to update the library and its API independent of the GROQ version. | ||
### GROQ-JS | ||
GROQ-JS follows [SemVer](https://semver.org). | ||
See [the changelog](CHANGELOG.md) for recent changes. | ||
This is an "experimental" release and anything _may_ change at any time, but we're trying to keep changes as minimal as possible: | ||
- The public API of the parser/evaluator will most likely stay the same in future version. | ||
- The public API of the parser/evaluator will most likely stay the same in future versions. | ||
- The syntax tree is _not_ considered a public API and may change at any time. | ||
- This package always implements the latest version of [GROQ according to the specification](https://github.com/sanity-io/groq). | ||
- The goal is to release a v1.0.0 by the end of 2020. | ||
## Releasing a new version of GROQ-JS | ||
We use the `np` package to roll out new versions to NPM. You can read up more on the package [here](https://github.com/sindresorhus/np). | ||
Make sure you update the CHANGELOG before releasing a new version. Use the previous updates as guidance for the desired formatting, and remember we use [SemVer](https://semver.org)! | ||
To interactively release the version run the following: | ||
```bash | ||
npx np --no-release-draft | ||
``` | ||
The `--no-release-draft` flag prevents a GitHub release draft being created. | ||
The above `np` command will: | ||
1. Update the `version` field in `package.json` | ||
2. Publish the new version to NPM | ||
3. Create a Git tag | ||
4. Commit the Git tag and the updated `package.json` to version control, then push the changes upstream | ||
It also peforms some pre-release checks, like running tests and ensuring you're releasing from the `main` branch. | ||
For further context on the package and for instructions on how to bump versions in a non-interactive way [visit the README](https://github.com/sindresorhus/np). | ||
## License | ||
@@ -86,3 +115,3 @@ | ||
```bash | ||
# Fecth and generate test file: | ||
# Fetch and generate test file: | ||
./test/generate.sh | ||
@@ -93,1 +122,19 @@ | ||
``` | ||
You can generate tests from a specific version: | ||
```shell | ||
GROQTEST_SUITE_VERSION=v0.1.33 ./test/generate.sh | ||
``` | ||
or from a file (as generated by the test suite): | ||
```shell | ||
GROQTEST_SUITE=suite.ndjson ./test/generate.sh | ||
``` | ||
The test arguments are passed to `tap`, so you can use arguments, e.g. to run a specific set of tests: | ||
```shell | ||
npm test -g "array::join" | ||
``` |
@@ -47,3 +47,3 @@ import {ExprNode} from '../nodeTypes' | ||
} catch (err) { | ||
if (err.name === 'ConstantEvaluateError') { | ||
if (err instanceof ConstantEvaluateError) { | ||
return null | ||
@@ -50,0 +50,0 @@ } |
@@ -56,2 +56,8 @@ import * as NodeTypes from '../nodeTypes' | ||
Selector() { | ||
// These should be evaluated separely using a different evaluator. | ||
// At the mooment we haven't implemented this. | ||
throw new Error('Selectors can not be evaluated') | ||
}, | ||
Everything(_, scope) { | ||
@@ -58,0 +64,0 @@ return scope.source |
@@ -18,2 +18,3 @@ import type {ExprNode} from '../nodeTypes' | ||
fromJS, | ||
StreamValue, | ||
} from '../values' | ||
@@ -81,2 +82,8 @@ import {portableTextContent} from './pt' | ||
global.anywhere = async function anywhere() { | ||
throw new Error('not implemented') | ||
} | ||
global.anywhere.arity = 1 | ||
global.coalesce = async function coalesce(args, scope, execute) { | ||
@@ -83,0 +90,0 @@ for (const arg of args) { |
@@ -40,2 +40,3 @@ import {GroqFunction, GroqPipeFunction} from './evaluator/functions' | ||
| SelectNode | ||
| SelectorNode | ||
| SliceNode | ||
@@ -213,2 +214,6 @@ | ThisNode | ||
export interface SelectorNode extends BaseNode { | ||
type: 'Selector' | ||
} | ||
export interface ThisNode extends BaseNode { | ||
@@ -215,0 +220,0 @@ type: 'This' |
@@ -359,5 +359,14 @@ /* eslint-disable camelcase */ | ||
const args: NodeTypes.ExprNode[] = [] | ||
while (p.getMark().name !== 'func_args_end') { | ||
args.push(p.process(EXPR_BUILDER)) | ||
if (argumentShouldBeSelector(namespace, name, args.length)) { | ||
// Since the diff/delta functions aren't validated yet we only want to validate the selector | ||
// being used. We expect the null valued arg to throw an error at evaluation time. | ||
p.process(SELECTOR_BUILDER) | ||
args.push({type: 'Selector'}) | ||
} else { | ||
args.push(p.process(EXPR_BUILDER)) | ||
} | ||
} | ||
p.shift() | ||
@@ -666,2 +675,148 @@ | ||
const SELECTOR_BUILDER: MarkVisitor<null> = { | ||
group(p) { | ||
p.process(SELECTOR_BUILDER) | ||
return null | ||
}, | ||
everything() { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
this() { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
parent() { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
dblparent(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
traverse(p) { | ||
p.process(SELECTOR_BUILDER) | ||
while (p.getMark().name !== 'traversal_end') { | ||
p.process(TRAVERSE_BUILDER) | ||
} | ||
p.shift() | ||
return null | ||
}, | ||
this_attr(p) { | ||
p.processString() | ||
return null | ||
}, | ||
neg(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
pos(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
add(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
sub(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
mul(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
div(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
mod(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
pow(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
comp(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
in_range(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
str(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
integer(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
float(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
sci(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
object(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
array(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
tuple(p) { | ||
// This should only throw an error until we add support for tuples in selectors. | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
func_call(p, mark) { | ||
const func = EXPR_BUILDER.func_call(p, mark) as NodeTypes.FuncCallNode | ||
if (func.name === 'anywhere' && func.args.length === 1) return null | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
pipecall(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
pair(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
and(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
or(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
not(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
asc(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
desc(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
param(p) { | ||
throw new Error('Invalid selector syntax') | ||
}, | ||
} | ||
function extractPropertyKey(node: NodeTypes.ExprNode): string { | ||
@@ -701,2 +856,8 @@ if (node.type === 'AccessAttribute' && !node.base) { | ||
function argumentShouldBeSelector(namespace: string, functionName: string, argCount: number) { | ||
const functionsRequiringSelectors = ['changedAny', 'changedOnly'] | ||
return namespace == 'diff' && argCount == 2 && functionsRequiringSelectors.includes(functionName) | ||
} | ||
class GroqSyntaxError extends Error { | ||
@@ -703,0 +864,0 @@ public position: number |
@@ -768,3 +768,2 @@ 'use strict' | ||
marks.push({name: 'unicode_hex_end', position: pos}) | ||
pos++ | ||
} else { | ||
@@ -771,0 +770,0 @@ marks.push({name: 'unicode_hex', position: pos + 2}) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
452976
12608
137
17
33
4