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

Add support for Apollo Connectors Mapping Syntax #230

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d0098ce
minimal changes to inject new grammar into directives
phryneas Oct 18, 2024
2637e5c
minimal (wrong) syntax highlighting for body & selection
phryneas Oct 18, 2024
1ae4203
body...
phryneas Oct 18, 2024
5e7f3dd
first attempt at jsonselection textmate grammar
phryneas Oct 18, 2024
839a650
injection not working yet
phryneas Oct 18, 2024
53c4a31
embed jsonselection as language
phryneas Oct 23, 2024
e4c6c87
some minor highlighting
phryneas Oct 23, 2024
60814f7
change to new ebnf, start over
phryneas Oct 24, 2024
c30aaf4
progress
phryneas Oct 24, 2024
bda40e6
progress
phryneas Oct 28, 2024
d0d2c77
getting somewhere
phryneas Oct 28, 2024
ab78a30
JSONSelectionString
phryneas Oct 28, 2024
e20832b
add comments, snapshot tests
phryneas Oct 28, 2024
b1ff896
update one grammar, move things
phryneas Oct 28, 2024
0ea12de
uncomment
phryneas Oct 28, 2024
5b85408
flip some priorities
phryneas Oct 29, 2024
51c573d
allow leading underscore in identifiers/keys/aliases
phryneas Oct 29, 2024
39c29d2
allow PUT|PATCH|DELETE
phryneas Oct 29, 2024
2a72811
split out connect-jsonselection-nested-argument, test
phryneas Oct 29, 2024
8711cf3
add schema ref
phryneas Oct 29, 2024
7c1fd89
fix: correct handling of nested objects
phryneas Oct 30, 2024
1483930
special highlighting for `({` `})` bracket pairs
phryneas Oct 30, 2024
073162f
fix typo
phryneas Oct 30, 2024
4deca72
highlighting of `@`, `$.` and `$.foo`
phryneas Oct 30, 2024
810cf1a
undo `{(` grouping
phryneas Oct 30, 2024
5c2ea2f
set apart `{` in `JSONSelectionString` visually
phryneas Oct 30, 2024
07b9f61
redo accidental wrong edit
phryneas Oct 30, 2024
f433e14
update snapshots, run more tests in CI
phryneas Oct 31, 2024
304b70c
also write graphql.connectors with a yaml source
phryneas Oct 31, 2024
5738e9a
rename scope according to recommendations
phryneas Oct 31, 2024
c84606b
rename things to "Apollo Connectors Mapping Syntax"
phryneas Oct 31, 2024
4280f23
sort the language at the end of the list
phryneas Oct 31, 2024
9c2ede1
reduce diff to original graphql grammar
phryneas Oct 31, 2024
ca52e1f
add comments to document injection logic
phryneas Oct 31, 2024
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
14 changes: 13 additions & 1 deletion .github/workflows/E2E.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
jobs:
test:
e2e:
name: Run E2E tests
runs-on: ubuntu-latest
strategy:
Expand All @@ -30,3 +30,15 @@ jobs:
- run: xvfb-run -a npm run test:extension
env:
VSCODE_VERSION: "${{ matrix.version }}"
test:
name: Run other tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: "npm"
- run: npm install
- run: npm run build:production
- run: yarn test
- run: yarn test:textmate
9 changes: 7 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
{
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.rulers": [110],
"editor.rulers": [
110
],
"editor.wordWrapColumn": 110,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
Expand All @@ -12,5 +14,8 @@
"node_modules": false
},
"typescript.tsdk": "node_modules/typescript/lib",
"debug.node.autoAttach": "on"
"debug.node.autoAttach": "on",
"yaml.schemas": {
"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json": "/syntaxes/*.yaml"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this JSONSchema which somehow adds a tiny little bit of documentation to the textmate format.

}
}
10 changes: 10 additions & 0 deletions apollo.jsonselection.configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"comments": {
"lineComment": "#"
},
"brackets": [
["[", "]"],
["{", "}"],
["(", ")"]
]
}
32 changes: 31 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"watch": "rimraf lib; npm-run-all -p watch:*",
"watch:esbuild": "npm run build -- --watch",
"watch:tsc": "npm run typecheck -- --watch",
"watch:textmate-yaml": "fswatch syntaxes/*.yaml | sed -u -e 's/\\.yaml$//' | xargs -I {} bash -c \"npx js-yaml {}.yaml > {}.json && echo {}\"",
"sampleWorkspace:run": "node src/__e2e__/mockServer.js",
"changeset-version": "changeset version && npm i",
"changeset-publish": "npm run build -- --production && changeset publish",
Expand All @@ -29,7 +30,10 @@
"format": "prettier --write .",
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
"test:extension": "node src/__e2e__/runTests.js",
"test:textmate": "npx vscode-tmgrammar-snap -s source.ts -g src/language-server/__tests__/fixtures/TypeScript.tmLanguage.json src/language-server/__tests__/fixtures/documents/*.ts",
"test:textmate": "npm run test:textmate-ts && npm run test:textmate-jsonselection && npm run test:textmate-graphql-jsonselection",
"test:textmate-ts": "npx vscode-tmgrammar-snap -s source.ts -g src/language-server/__tests__/fixtures/TypeScript.tmLanguage.json src/language-server/__tests__/fixtures/documents/*.ts",
"test:textmate-jsonselection": "npx vscode-tmgrammar-snap -s source.apollo.connectors.mapping src/__tests__/fixtures/textmate/*.jsonselection",
"test:textmate-graphql-jsonselection": "npx vscode-tmgrammar-snap -s source.graphql src/__tests__/fixtures/textmate/*.graphql",
"codegen": "graphql-codegen",
"vscode:prepublish": "npm run build:production"
},
Expand Down Expand Up @@ -154,6 +158,16 @@
],
"configuration": "./graphql.configuration.json"
},
{
"id": "apollo.connectors.mapping",
"aliases": [
"[Apollo Connectors Mapping Syntax]"
],
"filenames": [
"test.apollo.jsonselection"
],
"configuration": "./apollo.jsonselection.configuration.json"
},
{
"id": "jsonc",
"filenames": [
Expand All @@ -167,6 +181,22 @@
"scopeName": "source.graphql",
"path": "./syntaxes/graphql.json"
},
{
"language": "apollo.connectors.mapping",
"scopeName": "source.apollo.connectors.mapping",
"path": "./syntaxes/connectors.jsonselection.json"
},
{
"injectTo": [
"source.graphql"
],
"scopeName": "source.apollo.connectors.graphql",
"path": "./syntaxes/graphql.connectors.json",
"embeddedLanguages": {
"meta.embedded.block.jsonselection.graphql": "apollo.connectors.mapping",
"meta.embedded.block.string.jsonselection.graphql": "apollo.connectors.mapping"
}
},
{
"injectTo": [
"source.js",
Expand Down
3 changes: 3 additions & 0 deletions sampleWorkspace/sampleWorkspace.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
},
{
"path": "../src/language-server/__tests__/fixtures/documents"
},
{
"path": "../src/__tests__/fixtures"
}
],
"settings": {}
Expand Down
137 changes: 137 additions & 0 deletions src/__tests__/fixtures/textmate/test.apollo.jsonselection
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Examples from https://github.com/apollographql/router/blob/next/apollo-federation/src/sources/connect/json_selection/README.md

id
name
abc: some.nested.path { a b c }
id
name
some.nested.path { a b c }
names: {
first: firstName
last: lastName
}
# Also allowed:
firstName
lastName
postID
title
author: {
id: authorID
name: authorName
}
title
year: publication.year
authorName: author.name
id
created
model

# The { role content } SubSelection is mandatory so the output keys
# can be statically determined:
choices->first.message { role content }

# Multiple PathWithSubSelections are allowed in the same SubSelection:
choices->last.message { lastContent: content }
# For some reason /users/{$args.id} returns an object with name
# and email but no id, so we inject the id manually:
id: $args.id
name
email
id name friends: friend_ids { id: $ }
items: data.nested.items { id name }
firstItem: data.nested.items->first { id name }
firstItemName: data.nested.items->first.name
$.data { id name }
id: data.id
name: data.name
all: $.first->and($.second)->and($.third)
wrapped: field->echo({ fieldValue: @ })
children: parent->echo([@.child1, @.child2, @.child3])
doubled: numbers->map({ value: @->mul(2) })
types: values->map(@->typeof)
__typename: $("Product")
condition: $(true)
alphabetSlice: $("abcdefghijklmnopqrstuvwxyz")->slice($args.start, $args.end)
suffix: results.slice($(-1)->mul($args.suffixLength))
# The ->echo method returns its first input argument as-is, ignoring
# the input data. Useful for embedding literal values, as in
# $->echo("give me this string"), or wrapping the input value.
__typename: $->echo("Book")
wrapped: field->echo({ fieldValue: @ })

# Returns the type of the data as a string, e.g. "object", "array",
# "string", "number", "boolean", or "null". Note that `typeof null` is
# "object" in JavaScript but "null" for our purposes.
typeOfValue: value->typeof

# When invoked against an array, ->map evaluates its first argument
# against each element of the array, binding the element values to `@`,
# and returns an array of the results. When invoked against a non-array,
# ->map evaluates its first argument against that value and returns the
# result without wrapping it in an array.
doubled: numbers->map(@->mul(2))
types: values->map(@->typeof)

# Returns true if the data is deeply equal to the first argument, false
# otherwise. Equality is solely value-based (all JSON), no references.
isObject: value->typeof->eq("object")

# Takes any number of pairs [candidate, value], and returns value for
# the first candidate that equals the input data. If none of the
# pairs match, a runtime error is reported, but a single-element
# [<default>] array as the final argument guarantees a default value.
__typename: kind->match(
["dog", "Canine"],
["cat", "Feline"],
["Exotic"]
)

# Like ->match, but expects the first element of each pair to evaluate
# to a boolean, returning the second element of the first pair whose
# first element is true. This makes providing a final catch-all case
# easy, since the last pair can be [true, <default>].
__typename: kind->matchIf(
[@->eq("dog"), "Canine"],
[@->eq("cat"), "Feline"],
[true, "Exotic"]
)

# Arithmetic methods, supporting both integers and floating point values,
# similar to JavaScript.
sum: $.a->add($.b)->add($.c)
difference: $.a->sub($.b)->sub($.c)
product: $.a->mul($.b, $.c)
quotient: $.a->div($.b)
remainder: $.a->mod($.b)

# Array/string methods
first: list->first
last: list->last
index3: list->get(3)
secondToLast: list->get(-2)
slice: list->slice(0, 5)
substring: string->slice(2, 5)
arraySize: array->size
stringLength: string->size

# Object methods
aValue: $->echo({ a: 123 })->get("a")
hasKey: object->has("key")
hasAB: object->has("a")->and(object->has("b"))
numberOfProperties: object->size
keys: object->keys
values: object->values
entries: object->entries
keysFromEntries: object->entries.key
valuesFromEntries: object->entries.value

# Logical methods
negation: $.condition->not
bangBang: $.condition->not->not
disjunction: $.a->or($.b)->or($.c)
conjunction: $.a->and($.b, $.c)
aImpliesB: $.a->not->or($.b)
excludedMiddle: $.toBe->or($.toBe->not)->eq(true)

# Tests from https://github.com/apollographql/router/blob/next/apollo-federation/src/sources/connect/url_template.rs

Loading