@teamkeel/wasm 0.329.0 → 0.330.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,14 +1,9 @@
1
1
  export function format(schema: string): Promise<string>;
2
2
 
3
- export function validate(
4
- schemaString: string,
5
- configFile: string
6
- ): Promise<ValidationResult>;
3
+ export function validate(req: ValidateRequest): Promise<ValidationResult>;
7
4
 
8
5
  export function completions(
9
- schemaString: string,
10
- position: SimplePosition,
11
- configFile: string
6
+ req: GetCompletionsRequest
12
7
  ): Promise<CompletionResult>;
13
8
 
14
9
  export function getDefinition(
@@ -24,24 +19,31 @@ export interface SchemaDefinition {
24
19
  schema: SchemaDefinition;
25
20
  }
26
21
 
22
+ export interface GetCompletionsRequest {
23
+ position: Position;
24
+ schemaFiles: SchemaFile[];
25
+ config?: string;
26
+ }
27
+
27
28
  export interface GetDefinitionRequest {
28
29
  position: Position;
29
30
  schemaFiles: SchemaFile[];
30
31
  }
31
32
 
33
+ export interface ValidateRequest {
34
+ schemaFiles: SchemaFile[];
35
+ config?: string;
36
+ }
37
+
32
38
  export interface SchemaFile {
33
39
  filename: string;
34
40
  contents: string;
35
41
  }
36
42
 
37
- export interface SimplePosition {
38
- column: number;
39
- line: number;
40
- }
41
-
42
- export interface Position extends SimplePosition {
43
+ export interface Position {
43
44
  filename: string;
44
- offset: number;
45
+ line: number;
46
+ column: number;
45
47
  }
46
48
 
47
49
  export interface CompletionItem {
package/index.test.ts CHANGED
@@ -40,33 +40,121 @@ test("completions", async () => {
40
40
  name Te
41
41
  }
42
42
  }`;
43
- const result = await completions(
44
- schema,
45
- {
43
+ const result = await completions({
44
+ schemaFiles: [
45
+ {
46
+ filename: "schema.keel",
47
+ contents: schema,
48
+ },
49
+ ],
50
+ position: {
51
+ filename: "schema.keel",
46
52
  line: 3,
47
53
  column: 16,
48
54
  },
49
- configFile
50
- );
55
+ });
51
56
 
52
57
  expect(result.completions.map((x) => x.label)).toContain("Text");
53
58
  });
54
59
 
60
+ test("completions - multi file", async () => {
61
+ const result = await completions({
62
+ schemaFiles: [
63
+ {
64
+ filename: "schema.keel",
65
+ contents: `
66
+ model Person {
67
+ fields {
68
+ name
69
+ }
70
+ }`,
71
+ },
72
+ {
73
+ filename: "other.keel",
74
+ contents: `
75
+ enum Category {
76
+ Sport
77
+ Finance
78
+ }
79
+ `,
80
+ },
81
+ ],
82
+ position: {
83
+ filename: "schema.keel",
84
+ line: 4,
85
+ column: 10,
86
+ },
87
+ });
88
+
89
+ expect(result.completions.map((x) => x.label)).toContain("Category");
90
+ });
91
+
92
+ test("completions - with config", async () => {
93
+ const result = await completions({
94
+ schemaFiles: [
95
+ {
96
+ filename: "schema.keel",
97
+ contents: `
98
+ model Person {
99
+ @permission(
100
+ expression: ctx.secrets.
101
+ )
102
+ }`,
103
+ },
104
+ ],
105
+ position: {
106
+ filename: "schema.keel",
107
+ line: 4,
108
+ column: 29,
109
+ },
110
+ config: configFile,
111
+ });
112
+
113
+ expect(result.completions.map((x) => x.label)).toContain("API_KEY");
114
+ });
115
+
55
116
  test("validate", async () => {
56
117
  const schema = `model Person {
57
118
  fields {
58
119
  name Foo
59
120
  }
60
121
  }`;
61
- const { errors } = await validate(schema, configFile);
122
+ const { errors } = await validate({
123
+ schemaFiles: [{ filename: "schema.keel", contents: schema }],
124
+ config: configFile,
125
+ });
62
126
 
63
127
  expect(errors[0].message).toEqual("field name has an unsupported type Foo");
64
128
  });
65
129
 
130
+ test("validate - multi file", async () => {
131
+ const schemaA = `model Customer {
132
+ fields {
133
+ orders Order[]
134
+ }
135
+ }`;
136
+ const schemaB = `model Order {
137
+ fields {
138
+ customer Customer
139
+ }
140
+ }`;
141
+ const { errors } = await validate({
142
+ schemaFiles: [
143
+ { filename: "customer.keel", contents: schemaA },
144
+ { filename: "hobby.keel", contents: schemaB },
145
+ ],
146
+ });
147
+
148
+ expect(errors.length).toEqual(0);
149
+ });
150
+
66
151
  test("validate - invalid schema", async () => {
67
152
  const schema = `model Person {
68
153
  fields {`;
69
- const { errors } = await validate(schema, configFile);
154
+ const { errors } = await validate({
155
+ schemaFiles: [{ filename: "schema.keel", contents: schema }],
156
+ config: configFile,
157
+ });
70
158
 
71
159
  expect(errors[0].code).toEqual("E025");
72
160
  expect(errors[0].message).toEqual(` unexpected token "<EOF>" (expected "}")`);
@@ -77,7 +165,6 @@ test("getDefinition", async () => {
77
165
  position: {
78
166
  line: 7,
79
167
  column: 21,
80
- offset: 0,
81
168
  filename: "myschema.keel",
82
169
  },
83
170
  schemaFiles: [
@@ -112,7 +199,6 @@ test("getDefinition - no result", async () => {
112
199
  position: {
113
200
  line: 1,
114
201
  column: 1,
115
- offset: 0,
116
202
  filename: "myschema.keel",
117
203
  },
118
204
  schemaFiles: [
package/lib/main.go CHANGED
@@ -78,15 +78,50 @@ func newPromise(fn func() (any, error)) any {
78
78
  return promiseConstructor.New(handler)
79
79
  }
80
80
 
81
+ // Expected argument to definitions API:
82
+ //
83
+ // {
84
+ // position: {
85
+ // filename: "",
86
+ // line: 1,
87
+ // column: 1,
88
+ // },
89
+ // schemaFiles: [
90
+ // {
91
+ // filename: "",
92
+ // contents: "",
93
+ // },
94
+ // ],
95
+ // config: "",
96
+ // }
81
97
  func provideCompletions(this js.Value, args []js.Value) any {
82
98
  return newPromise(func() (any, error) {
83
- line := args[1].Get("line").Int()
84
- column := args[1].Get("column").Int()
99
+ positionArg := args[0].Get("position")
100
+ pos := &node.Position{
101
+ Filename: positionArg.Get("filename").String(),
102
+ Line: positionArg.Get("line").Int(),
103
+ Column: positionArg.Get("column").Int(),
104
+ }
85
105
 
86
- completions := completions.Completions(args[0].String(), &node.Position{
87
- Column: column,
88
- Line: line,
89
- }, args[2].String())
106
+ schemaFilesArg := args[0].Get("schemaFiles")
107
+ schemaFiles := []*reader.SchemaFile{}
108
+ for i := 0; i < schemaFilesArg.Length(); i++ {
109
+ f := schemaFilesArg.Index(i)
110
+ schemaFiles = append(schemaFiles, &reader.SchemaFile{
111
+ FileName: f.Get("filename").String(),
112
+ Contents: f.Get("contents").String(),
113
+ })
114
+ }
115
+
116
+ configSrc := args[0].Get("config")
117
+ var cfg *config.ProjectConfig
118
+ if configSrc.Truthy() {
119
+ // We don't care about errors here, if we can get a config object
120
+ // back we'll use it, if not then we'll run validation without it
121
+ cfg, _ = config.LoadFromBytes([]byte(configSrc.String()))
122
+ }
123
+
124
+ completions := completions.Completions(schemaFiles, pos, cfg)
90
125
 
91
126
  untypedCompletions := toUntypedArray(completions)
92
127
 
@@ -155,28 +190,46 @@ func formatSchema(this js.Value, args []js.Value) any {
155
190
  })
156
191
  }
157
192
 
158
- // Type definition for this function:
193
+ // Expected argument to validate API:
159
194
  //
160
- // validate(schema: string)
195
+ // {
196
+ // schemaFiles: [
197
+ // {
198
+ // filename: "",
199
+ // contents: "",
200
+ // },
201
+ // ],
202
+ // config: "<YAML config file>"
203
+ // }
204
+ //
205
+ // The config file source is optional.
161
206
  func validate(this js.Value, args []js.Value) any {
162
207
  return newPromise(func() (any, error) {
163
- schemaFile := reader.SchemaFile{
164
- FileName: "schema.keel",
165
- Contents: args[0].String(),
208
+
209
+ schemaFilesArg := args[0].Get("schemaFiles")
210
+ schemaFiles := []reader.SchemaFile{}
211
+ for i := 0; i < schemaFilesArg.Length(); i++ {
212
+ f := schemaFilesArg.Index(i)
213
+ schemaFiles = append(schemaFiles, reader.SchemaFile{
214
+ FileName: f.Get("filename").String(),
215
+ Contents: f.Get("contents").String(),
216
+ })
166
217
  }
167
218
 
168
219
  builder := schema.Builder{}
169
220
 
170
- if args[1].Truthy() {
171
- config, err := config.LoadFromBytes([]byte(args[1].String()))
172
- if err != nil {
173
- return nil, err
221
+ configSrc := args[0].Get("config")
222
+ if configSrc.Truthy() {
223
+ // We don't care about errors here, if we can get a config object
224
+ // back we'll use it, if not then we'll run validation without it
225
+ config, _ := config.LoadFromBytes([]byte(configSrc.String()))
226
+ if config != nil {
227
+ builder.Config = config
174
228
  }
175
- builder.Config = config
176
229
  }
177
230
 
178
231
  _, err := builder.MakeFromInputs(&reader.Inputs{
179
- SchemaFiles: []reader.SchemaFile{schemaFile},
232
+ SchemaFiles: schemaFiles,
180
233
  })
181
234
 
182
235
  if err != nil {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamkeel/wasm",
3
- "version": "0.329.0",
3
+ "version": "0.330.1",
4
4
  "description": "A wrapper around the Keel WASM binary",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",