@dagger.io/dagger 0.10.0 → 0.10.2
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/dist/api/client.gen.d.ts +35 -5
- package/dist/api/client.gen.d.ts.map +1 -1
- package/dist/api/client.gen.js +12 -4
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/api/utils.js +6 -2
- package/dist/common/errors/ExecError.d.ts.map +1 -1
- package/dist/entrypoint/context.d.ts +8 -0
- package/dist/entrypoint/context.d.ts.map +1 -0
- package/dist/entrypoint/invoke.d.ts +3 -9
- package/dist/entrypoint/invoke.d.ts.map +1 -1
- package/dist/entrypoint/invoke.js +17 -28
- package/dist/entrypoint/load.d.ts +29 -69
- package/dist/entrypoint/load.d.ts.map +1 -1
- package/dist/entrypoint/load.js +90 -173
- package/dist/entrypoint/register.d.ts +2 -2
- package/dist/entrypoint/register.d.ts.map +1 -1
- package/dist/entrypoint/register.js +12 -12
- package/dist/introspector/scanner/abtractions/argument.d.ts +75 -0
- package/dist/introspector/scanner/abtractions/argument.d.ts.map +1 -0
- package/dist/introspector/scanner/abtractions/argument.js +137 -0
- package/dist/introspector/scanner/abtractions/constructor.d.ts +16 -0
- package/dist/introspector/scanner/abtractions/constructor.d.ts.map +1 -0
- package/dist/introspector/scanner/abtractions/constructor.js +42 -0
- package/dist/introspector/scanner/abtractions/method.d.ts +51 -0
- package/dist/introspector/scanner/abtractions/method.d.ts.map +1 -0
- package/dist/introspector/scanner/abtractions/method.js +105 -0
- package/dist/introspector/scanner/abtractions/module.d.ts +18 -0
- package/dist/introspector/scanner/abtractions/module.d.ts.map +1 -0
- package/dist/introspector/scanner/abtractions/module.js +59 -0
- package/dist/introspector/scanner/abtractions/object.d.ts +37 -0
- package/dist/introspector/scanner/abtractions/object.d.ts.map +1 -0
- package/dist/introspector/scanner/abtractions/object.js +94 -0
- package/dist/introspector/scanner/abtractions/property.d.ts +46 -0
- package/dist/introspector/scanner/abtractions/property.d.ts.map +1 -0
- package/dist/introspector/scanner/abtractions/property.js +93 -0
- package/dist/introspector/scanner/scan.d.ts +2 -1
- package/dist/introspector/scanner/scan.d.ts.map +1 -1
- package/dist/introspector/scanner/scan.js +2 -181
- package/dist/introspector/scanner/serialize.d.ts +0 -24
- package/dist/introspector/scanner/serialize.d.ts.map +1 -1
- package/dist/introspector/scanner/serialize.js +0 -53
- package/dist/introspector/scanner/typeDefs.d.ts +3 -3
- package/dist/introspector/scanner/typeDefs.d.ts.map +1 -1
- package/dist/introspector/scanner/utils.d.ts +1 -57
- package/dist/introspector/scanner/utils.d.ts.map +1 -1
- package/dist/introspector/scanner/utils.js +16 -139
- package/dist/provisioning/bin.d.ts.map +1 -1
- package/dist/provisioning/bin.js +9 -3
- package/dist/provisioning/default.d.ts +1 -1
- package/dist/provisioning/default.js +1 -1
- package/package.json +6 -5
- package/dist/introspector/scanner/metadata.d.ts +0 -24
- package/dist/introspector/scanner/metadata.d.ts.map +0 -1
- /package/dist/{introspector/scanner/metadata.js → entrypoint/context.js} +0 -0
package/dist/entrypoint/load.js
CHANGED
|
@@ -10,198 +10,85 @@ export async function load(files) {
|
|
|
10
10
|
await Promise.all(files.map(async (f) => await import(f)));
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Return the object invoked from the module.
|
|
14
14
|
*
|
|
15
|
-
* @param
|
|
16
|
-
* @param parentName The name of the
|
|
17
|
-
* @param fnName The name of the function.
|
|
18
|
-
*
|
|
19
|
-
* @returns An array of strings representing the order of arguments.
|
|
20
|
-
*/
|
|
21
|
-
export function loadArgOrder(scanResult, parentName, fnName) {
|
|
22
|
-
const classTypeDef = scanResult.classes[parentName];
|
|
23
|
-
if (!classTypeDef) {
|
|
24
|
-
throw new Error(`could not find class ${parentName}`);
|
|
25
|
-
}
|
|
26
|
-
// Call for the constructor
|
|
27
|
-
if (fnName === "") {
|
|
28
|
-
return Object.keys(classTypeDef.constructor?.args ?? {});
|
|
29
|
-
}
|
|
30
|
-
const methodTypeDef = classTypeDef.methods[fnName];
|
|
31
|
-
if (!methodTypeDef) {
|
|
32
|
-
throw new Error(`could not find method ${fnName}`);
|
|
33
|
-
}
|
|
34
|
-
return Object.keys(methodTypeDef.args);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Load the argument for the given function and check if it's variadic.
|
|
38
|
-
*
|
|
39
|
-
* @param scanResult The result of the scan.
|
|
40
|
-
* @param parentName The name of the class.
|
|
41
|
-
* @param fnName The name of the function.
|
|
42
|
-
* @param argName The name of the argument.
|
|
43
|
-
*
|
|
44
|
-
* @returns True if the argument is variadic, false otherwise.
|
|
45
|
-
*/
|
|
46
|
-
export function isArgVariadic(scanResult, parentName, fnName, argName) {
|
|
47
|
-
const classTypeDef = scanResult.classes[parentName];
|
|
48
|
-
if (!classTypeDef) {
|
|
49
|
-
throw new Error(`could not find class ${parentName}`);
|
|
50
|
-
}
|
|
51
|
-
// It's not possible to have variadic arguments in the constructor.
|
|
52
|
-
if (fnName === "") {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
const methodTypeDef = classTypeDef.methods[fnName];
|
|
56
|
-
if (!methodTypeDef) {
|
|
57
|
-
throw new Error(`could not find method ${fnName}`);
|
|
58
|
-
}
|
|
59
|
-
return methodTypeDef.args[argName].isVariadic;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Load the argument type from the scan result.
|
|
63
|
-
*
|
|
64
|
-
* @param scanResult Result of the scan
|
|
65
|
-
* @param parentName Class called
|
|
66
|
-
* @param fnName Function called
|
|
67
|
-
* @param argName Argument name
|
|
68
|
-
* @returns The type of the argument
|
|
15
|
+
* @param module The module to load the object from.
|
|
16
|
+
* @param parentName The name of the parent object.
|
|
69
17
|
*/
|
|
70
|
-
export function
|
|
71
|
-
|
|
72
|
-
if (!classTypeDef) {
|
|
73
|
-
throw new Error(`could not find class ${parentName}`);
|
|
74
|
-
}
|
|
75
|
-
// Call for the constructor
|
|
76
|
-
if (fnName === "") {
|
|
77
|
-
const argTypeDef = classTypeDef.constructor?.args[argName];
|
|
78
|
-
if (!argTypeDef) {
|
|
79
|
-
throw new Error(`could not find argument ${argName} type in constructor`);
|
|
80
|
-
}
|
|
81
|
-
return argTypeDef.typeDef;
|
|
82
|
-
}
|
|
83
|
-
const methodTypeDef = classTypeDef.methods[fnName];
|
|
84
|
-
if (!methodTypeDef) {
|
|
85
|
-
throw new Error(`could not find method ${fnName}`);
|
|
86
|
-
}
|
|
87
|
-
const argTypeDef = methodTypeDef.args[argName];
|
|
88
|
-
if (!argTypeDef) {
|
|
89
|
-
throw new Error(`could not find argument ${argName} type`);
|
|
90
|
-
}
|
|
91
|
-
return argTypeDef.typeDef;
|
|
18
|
+
export function loadInvokedObject(module, parentName) {
|
|
19
|
+
return module.objects[parentName];
|
|
92
20
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
* @param scanResult Result of the scan
|
|
97
|
-
* @param parentName Class called
|
|
98
|
-
* @param propertyName property of the class
|
|
99
|
-
* @returns the type of the property
|
|
100
|
-
*/
|
|
101
|
-
export function loadPropertyType(scanResult, parentName, propertyName) {
|
|
102
|
-
const classTypeDef = scanResult.classes[parentName];
|
|
103
|
-
if (!classTypeDef) {
|
|
104
|
-
throw new Error(`could not find class ${parentName}`);
|
|
105
|
-
}
|
|
106
|
-
const propertyTypeDef = classTypeDef.fields[propertyName];
|
|
107
|
-
if (!propertyTypeDef) {
|
|
108
|
-
throw new Error(`could not find property ${propertyName} type`);
|
|
21
|
+
export function loadInvokedMethod(object, ctx) {
|
|
22
|
+
if (ctx.fnName === "") {
|
|
23
|
+
return object._constructor;
|
|
109
24
|
}
|
|
110
|
-
return
|
|
25
|
+
return object.methods[ctx.fnName];
|
|
111
26
|
}
|
|
112
27
|
/**
|
|
113
|
-
* Load the
|
|
28
|
+
* Load the values of the arguments from the context.
|
|
114
29
|
*
|
|
115
|
-
* @param
|
|
116
|
-
* @param
|
|
117
|
-
* @param alias exposed name
|
|
118
|
-
* @param kind location of the alias
|
|
30
|
+
* @param method Method to load the arguments from.
|
|
31
|
+
* @param ctx The context of the invocation.
|
|
119
32
|
*/
|
|
120
|
-
export function
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return classTypeDef.name;
|
|
33
|
+
export async function loadArgs(method, ctx) {
|
|
34
|
+
const args = {};
|
|
35
|
+
// Load arguments
|
|
36
|
+
for (const argName of method.getArgOrder()) {
|
|
37
|
+
const argument = method.arguments[argName];
|
|
38
|
+
if (!argument) {
|
|
39
|
+
throw new Error(`could not find argument ${argName}`);
|
|
128
40
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
throw new Error(`could not find method ${alias} type`);
|
|
41
|
+
const loadedArg = await loadValue(ctx.fnArgs[argName], argument.type);
|
|
42
|
+
// If the argument is variadic, we need to load each args independently
|
|
43
|
+
// so it's correctly propagated when it's sent to the function.
|
|
44
|
+
// Note: variadic args are always last in the list of args.
|
|
45
|
+
if (argument.isVariadic) {
|
|
46
|
+
for (const [i, arg] of (loadedArg ?? []).entries()) {
|
|
47
|
+
args[`${argName}${i}`] = arg;
|
|
137
48
|
}
|
|
138
|
-
|
|
49
|
+
continue;
|
|
139
50
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
51
|
+
// If the argument is nullable and the loaded arg is undefined with no default value, we set it to null.
|
|
52
|
+
if (argument.isNullable &&
|
|
53
|
+
loadedArg === undefined &&
|
|
54
|
+
!argument.defaultValue) {
|
|
55
|
+
args[argName] = null;
|
|
56
|
+
continue;
|
|
146
57
|
}
|
|
58
|
+
args[argName] = loadedArg;
|
|
147
59
|
}
|
|
60
|
+
return args;
|
|
148
61
|
}
|
|
149
62
|
/**
|
|
150
|
-
* Load the
|
|
151
|
-
* If not found, return the original alias because it's not
|
|
152
|
-
* a registered field.
|
|
153
|
-
*
|
|
154
|
-
* @param scanResult Result of the scan
|
|
155
|
-
* @param parentName Class called
|
|
156
|
-
* @param alias exposed name
|
|
157
|
-
*/
|
|
158
|
-
export function loadResultAlias(scanResult, parentName, alias) {
|
|
159
|
-
const classTypeDef = scanResult.classes[parentName];
|
|
160
|
-
if (!classTypeDef) {
|
|
161
|
-
return alias;
|
|
162
|
-
}
|
|
163
|
-
const fieldTypeDef = Object.values(classTypeDef.fields).find((field) => field.name === alias);
|
|
164
|
-
if (!fieldTypeDef) {
|
|
165
|
-
return alias;
|
|
166
|
-
}
|
|
167
|
-
return fieldTypeDef.alias ?? fieldTypeDef.name;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Return the eventual parent name of a field if its return type is a
|
|
171
|
-
* registered object.
|
|
172
|
-
* If not found, return the original parent name.
|
|
63
|
+
* Load the state of the parent object from the context.
|
|
173
64
|
*
|
|
174
|
-
* @param
|
|
175
|
-
* @param
|
|
176
|
-
* @param alias The field alias
|
|
65
|
+
* @param object The object to load the parent state from.
|
|
66
|
+
* @param ctx The context of the invocation.
|
|
177
67
|
*/
|
|
178
|
-
export function
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
if (fieldTypeDef.typeDef.kind === TypeDefKind.ObjectKind) {
|
|
188
|
-
return fieldTypeDef.typeDef.name;
|
|
68
|
+
export async function loadParentState(object, ctx) {
|
|
69
|
+
const parentState = {};
|
|
70
|
+
for (const [key, value] of Object.entries(ctx.parentArgs)) {
|
|
71
|
+
const property = object.properties[key];
|
|
72
|
+
if (!property) {
|
|
73
|
+
throw new Error(`could not find parent property ${key}`);
|
|
74
|
+
}
|
|
75
|
+
parentState[property.name] = await loadValue(value, property.type);
|
|
189
76
|
}
|
|
190
|
-
return
|
|
77
|
+
return parentState;
|
|
191
78
|
}
|
|
192
79
|
/**
|
|
193
|
-
* This function load the
|
|
80
|
+
* This function load the value as a Dagger type.
|
|
194
81
|
*
|
|
195
82
|
* Note: The JSON.parse() is required to remove extra quotes
|
|
196
83
|
*/
|
|
197
|
-
export async function
|
|
84
|
+
export async function loadValue(value, type) {
|
|
198
85
|
// If value is undefinied, return it directly.
|
|
199
86
|
if (value === undefined) {
|
|
200
87
|
return value;
|
|
201
88
|
}
|
|
202
89
|
switch (type.kind) {
|
|
203
90
|
case TypeDefKind.ListKind:
|
|
204
|
-
return Promise.all(value.map(async (v) => await
|
|
91
|
+
return Promise.all(value.map(async (v) => await loadValue(v, type.typeDef)));
|
|
205
92
|
case TypeDefKind.ObjectKind: {
|
|
206
93
|
const objectType = type.name;
|
|
207
94
|
// Workaround to call get any object that has an id
|
|
@@ -215,7 +102,7 @@ export async function loadArg(value, type) {
|
|
|
215
102
|
// TODO(supports subfields serialization)
|
|
216
103
|
return value;
|
|
217
104
|
}
|
|
218
|
-
// Cannot use
|
|
105
|
+
// Cannot use `,` to specify multiple matching case so instead we use fallthrough.
|
|
219
106
|
case TypeDefKind.StringKind:
|
|
220
107
|
case TypeDefKind.IntegerKind:
|
|
221
108
|
case TypeDefKind.BooleanKind:
|
|
@@ -226,30 +113,60 @@ export async function loadArg(value, type) {
|
|
|
226
113
|
}
|
|
227
114
|
}
|
|
228
115
|
/**
|
|
229
|
-
* Load
|
|
116
|
+
* Load the object type from the return type of the method.
|
|
117
|
+
* This covers the case where the return type is an other object of the module.
|
|
118
|
+
* For example: `msg(): Message` where message is an object of the module.
|
|
230
119
|
*
|
|
231
|
-
* @param
|
|
232
|
-
* @param
|
|
233
|
-
* @param
|
|
234
|
-
* @returns Loaded result.
|
|
120
|
+
* @param module The module to load the object from.
|
|
121
|
+
* @param object The current object to load the return type from.
|
|
122
|
+
* @param method The method to load the return type from.
|
|
235
123
|
*/
|
|
236
|
-
export
|
|
124
|
+
export function loadObjectReturnType(module, object, method) {
|
|
125
|
+
const retType = method.returnType;
|
|
126
|
+
switch (retType.kind) {
|
|
127
|
+
case TypeDefKind.ListKind: {
|
|
128
|
+
// Loop until we find the original object type.
|
|
129
|
+
// This way we handle the list of list (e.g Object[][][]...[])
|
|
130
|
+
let listType = retType;
|
|
131
|
+
while (listType.kind === TypeDefKind.ListKind) {
|
|
132
|
+
listType = listType.typeDef;
|
|
133
|
+
}
|
|
134
|
+
return module.objects[listType.name];
|
|
135
|
+
}
|
|
136
|
+
case TypeDefKind.ObjectKind:
|
|
137
|
+
return module.objects[retType.name];
|
|
138
|
+
default:
|
|
139
|
+
return object;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export async function loadResult(result, module, object) {
|
|
237
143
|
// Handle IDable objects
|
|
238
144
|
if (result && typeof result?.id === "function") {
|
|
239
145
|
result = await result.id();
|
|
240
146
|
}
|
|
241
147
|
// Handle arrays
|
|
242
148
|
if (Array.isArray(result)) {
|
|
243
|
-
result = await Promise.all(result.map(async (r) => await loadResult(r,
|
|
149
|
+
result = await Promise.all(result.map(async (r) => await loadResult(r, module, object)));
|
|
244
150
|
return result;
|
|
245
151
|
}
|
|
246
152
|
// Handle objects
|
|
247
153
|
if (typeof result === "object") {
|
|
248
154
|
const state = {};
|
|
249
155
|
for (const [key, value] of Object.entries(result)) {
|
|
250
|
-
|
|
156
|
+
const property = Object.values(object.properties).find((p) => p.name === key);
|
|
157
|
+
if (!property) {
|
|
158
|
+
throw new Error(`could not find result property ${key}`);
|
|
159
|
+
}
|
|
160
|
+
if (property.type.kind === TypeDefKind.ObjectKind) {
|
|
161
|
+
const referencedObject = module.objects[property.type.name];
|
|
162
|
+
if (referencedObject) {
|
|
163
|
+
object = referencedObject;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
state[property.alias ?? property.name] = await loadResult(value, module, object);
|
|
251
167
|
}
|
|
252
|
-
|
|
168
|
+
return state;
|
|
253
169
|
}
|
|
170
|
+
// Handle primitive types
|
|
254
171
|
return result;
|
|
255
172
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ModuleID } from "../api/client.gen.js";
|
|
2
|
-
import {
|
|
2
|
+
import { DaggerModule } from "../introspector/scanner/abtractions/module.js";
|
|
3
3
|
/**
|
|
4
4
|
* Register the module files and returns its ID
|
|
5
5
|
*/
|
|
6
|
-
export declare function register(files: string[],
|
|
6
|
+
export declare function register(files: string[], module: DaggerModule): Promise<ModuleID>;
|
|
7
7
|
//# sourceMappingURL=register.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../entrypoint/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,QAAQ,EAGT,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../entrypoint/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,QAAQ,EAGT,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AAU5E;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,QAAQ,CAAC,CA8CnB"}
|
|
@@ -2,33 +2,33 @@ import { dag, TypeDefKind, } from "../api/client.gen.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Register the module files and returns its ID
|
|
4
4
|
*/
|
|
5
|
-
export async function register(files,
|
|
5
|
+
export async function register(files, module) {
|
|
6
6
|
// Get a new module that we will fill in with all the types
|
|
7
7
|
let mod = dag.module_();
|
|
8
8
|
// Add module description if any.
|
|
9
|
-
if (
|
|
10
|
-
mod = mod.withDescription(
|
|
9
|
+
if (module.description) {
|
|
10
|
+
mod = mod.withDescription(module.description);
|
|
11
11
|
}
|
|
12
12
|
// For each class scanned, register its type, method and properties in the module.
|
|
13
|
-
Object.values(
|
|
13
|
+
Object.values(module.objects).forEach((object) => {
|
|
14
14
|
// Register the class Typedef object in Dagger
|
|
15
|
-
let typeDef = dag.typeDef().withObject(
|
|
16
|
-
description:
|
|
15
|
+
let typeDef = dag.typeDef().withObject(object.name, {
|
|
16
|
+
description: object.description,
|
|
17
17
|
});
|
|
18
18
|
// Register all functions (methods) to this object
|
|
19
|
-
Object.values(
|
|
20
|
-
typeDef = typeDef.withFunction(addFunction(method));
|
|
19
|
+
Object.values(object.methods).forEach((method) => {
|
|
20
|
+
typeDef = typeDef.withFunction(addFunction(method.typeDef));
|
|
21
21
|
});
|
|
22
22
|
// Register all fields that belong to this object
|
|
23
|
-
Object.values(
|
|
23
|
+
Object.values(object.properties).forEach((field) => {
|
|
24
24
|
if (field.isExposed) {
|
|
25
|
-
typeDef = typeDef.withField(field.alias ?? field.name, addTypeDef(field.typeDef), {
|
|
25
|
+
typeDef = typeDef.withField(field.alias ?? field.name, addTypeDef(field.typeDef.typeDef), {
|
|
26
26
|
description: field.description,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
|
-
if (
|
|
31
|
-
typeDef = typeDef.withConstructor(addConstructor(
|
|
30
|
+
if (object._constructor) {
|
|
31
|
+
typeDef = typeDef.withConstructor(addConstructor(object._constructor.typeDef, typeDef));
|
|
32
32
|
}
|
|
33
33
|
// Add it to the module object
|
|
34
34
|
mod = mod.withObject(typeDef);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { TypeDefKind } from "../../../api/client.gen.js";
|
|
3
|
+
import { FunctionArgTypeDef, TypeDef } from "../typeDefs.js";
|
|
4
|
+
export type Arguments = {
|
|
5
|
+
[name: string]: Argument;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Argument is an abstraction of a function argument.
|
|
9
|
+
*
|
|
10
|
+
* This aims to simplify and adds clarity to how we analyse the code and using
|
|
11
|
+
* clear accessor.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Argument {
|
|
14
|
+
private symbol;
|
|
15
|
+
private checker;
|
|
16
|
+
private param;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new Argument instance.
|
|
19
|
+
*
|
|
20
|
+
* @param checker Checker to use to introspect the type of the argument.
|
|
21
|
+
* @param param The symbol of the argument to introspect.
|
|
22
|
+
*
|
|
23
|
+
* @throws UnknownDaggerError If the symbol doesn't have any declaration.
|
|
24
|
+
* @throws UnknownDaggerError If the declaration of the symbol isn't a parameter.
|
|
25
|
+
*/
|
|
26
|
+
constructor(checker: ts.TypeChecker, param: ts.Symbol);
|
|
27
|
+
get name(): string;
|
|
28
|
+
get description(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Return the type of the argument in a Dagger TypeDef format.
|
|
31
|
+
*/
|
|
32
|
+
get type(): TypeDef<TypeDefKind>;
|
|
33
|
+
get defaultValue(): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Return true if the parameter is optional.
|
|
36
|
+
*
|
|
37
|
+
* A parameter is considered optional if he fits one of the following:
|
|
38
|
+
* - It has a question token (e.g. `foo?: <type>`).
|
|
39
|
+
* - It's variadic (e.g. `...foo: <type>[]`).
|
|
40
|
+
* - It's nullable (e.g. `foo: <type> | null`).
|
|
41
|
+
*/
|
|
42
|
+
get isOptional(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Return true if the parameter is nullable.
|
|
45
|
+
*
|
|
46
|
+
* A parameter is considered nullable if itstype is a union type with `null`
|
|
47
|
+
* on the list of types.
|
|
48
|
+
* Example: `foo: string | null`.
|
|
49
|
+
*/
|
|
50
|
+
get isNullable(): boolean;
|
|
51
|
+
get isVariadic(): boolean;
|
|
52
|
+
get typeDef(): FunctionArgTypeDef;
|
|
53
|
+
toJSON(): {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string;
|
|
56
|
+
type: TypeDef<TypeDefKind>;
|
|
57
|
+
isVariadic: boolean;
|
|
58
|
+
isNullable: boolean;
|
|
59
|
+
isOptional: boolean;
|
|
60
|
+
defaultValue: string | undefined;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The TypeScript Compiler API returns the raw default value as it is written
|
|
64
|
+
* by the user.
|
|
65
|
+
* However, some notations are not supported by GraphQL so this function
|
|
66
|
+
* formats the default value to be compatible with the GraphQL syntax.
|
|
67
|
+
*
|
|
68
|
+
* Formatting rules:
|
|
69
|
+
* - Single quote strings are converted to double quote strings.
|
|
70
|
+
*
|
|
71
|
+
* @param value The value to format.
|
|
72
|
+
*/
|
|
73
|
+
private formatDefaultValue;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=argument.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argument.d.ts","sourceRoot":"","sources":["../../../../introspector/scanner/abtractions/argument.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAG3B,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAI5D,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,CAAA;AAEpD;;;;;GAKG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAW;IAEzB,OAAO,CAAC,OAAO,CAAgB;IAE/B,OAAO,CAAC,KAAK,CAAyB;IAEtC;;;;;;;;OAQG;gBACS,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM;IAuBrD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,WAAW,IAAI,MAAM,CAIxB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC,CAgB/B;IAED,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAMrC;IAED;;;;;;;OAOG;IACH,IAAI,UAAU,IAAI,OAAO,CAMxB;IAED;;;;;;OAMG;IACH,IAAI,UAAU,IAAI,OAAO,CAcxB;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAID,IAAI,OAAO,IAAI,kBAAkB,CAShC;IAED,MAAM;;;;;;;;;IAYN;;;;;;;;;;OAUG;IACH,OAAO,CAAC,kBAAkB;CAU3B"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { UnknownDaggerError } from "../../../common/errors/UnknownDaggerError.js";
|
|
3
|
+
import { serializeType } from "../serialize.js";
|
|
4
|
+
import { typeNameToTypedef } from "../utils.js";
|
|
5
|
+
/**
|
|
6
|
+
* Argument is an abstraction of a function argument.
|
|
7
|
+
*
|
|
8
|
+
* This aims to simplify and adds clarity to how we analyse the code and using
|
|
9
|
+
* clear accessor.
|
|
10
|
+
*/
|
|
11
|
+
export class Argument {
|
|
12
|
+
symbol;
|
|
13
|
+
checker;
|
|
14
|
+
param;
|
|
15
|
+
/**
|
|
16
|
+
* Create a new Argument instance.
|
|
17
|
+
*
|
|
18
|
+
* @param checker Checker to use to introspect the type of the argument.
|
|
19
|
+
* @param param The symbol of the argument to introspect.
|
|
20
|
+
*
|
|
21
|
+
* @throws UnknownDaggerError If the symbol doesn't have any declaration.
|
|
22
|
+
* @throws UnknownDaggerError If the declaration of the symbol isn't a parameter.
|
|
23
|
+
*/
|
|
24
|
+
constructor(checker, param) {
|
|
25
|
+
this.symbol = param;
|
|
26
|
+
this.checker = checker;
|
|
27
|
+
const declarations = this.symbol.getDeclarations();
|
|
28
|
+
if (!declarations || declarations.length < 0) {
|
|
29
|
+
throw new UnknownDaggerError(`could not find param declarations of symbol ${this.symbol.name}`, {});
|
|
30
|
+
}
|
|
31
|
+
const parameterDeclaration = declarations[0];
|
|
32
|
+
if (!ts.isParameter(parameterDeclaration)) {
|
|
33
|
+
throw new UnknownDaggerError(`the declaration of symbol ${this.symbol.name} isn't a parameter`, {});
|
|
34
|
+
}
|
|
35
|
+
this.param = parameterDeclaration;
|
|
36
|
+
}
|
|
37
|
+
get name() {
|
|
38
|
+
return this.symbol.getName();
|
|
39
|
+
}
|
|
40
|
+
get description() {
|
|
41
|
+
return ts.displayPartsToString(this.symbol.getDocumentationComment(this.checker));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Return the type of the argument in a Dagger TypeDef format.
|
|
45
|
+
*/
|
|
46
|
+
get type() {
|
|
47
|
+
if (!this.symbol.valueDeclaration) {
|
|
48
|
+
throw new UnknownDaggerError("could not find symbol value declaration", {});
|
|
49
|
+
}
|
|
50
|
+
const type = this.checker.getTypeOfSymbolAtLocation(this.symbol, this.symbol.valueDeclaration);
|
|
51
|
+
const typeName = serializeType(this.checker, type);
|
|
52
|
+
return typeNameToTypedef(typeName);
|
|
53
|
+
}
|
|
54
|
+
get defaultValue() {
|
|
55
|
+
if (this.param.initializer === undefined) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return this.formatDefaultValue(this.param.initializer.getText());
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Return true if the parameter is optional.
|
|
62
|
+
*
|
|
63
|
+
* A parameter is considered optional if he fits one of the following:
|
|
64
|
+
* - It has a question token (e.g. `foo?: <type>`).
|
|
65
|
+
* - It's variadic (e.g. `...foo: <type>[]`).
|
|
66
|
+
* - It's nullable (e.g. `foo: <type> | null`).
|
|
67
|
+
*/
|
|
68
|
+
get isOptional() {
|
|
69
|
+
return (this.param.questionToken !== undefined ||
|
|
70
|
+
this.isVariadic ||
|
|
71
|
+
this.isNullable);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Return true if the parameter is nullable.
|
|
75
|
+
*
|
|
76
|
+
* A parameter is considered nullable if itstype is a union type with `null`
|
|
77
|
+
* on the list of types.
|
|
78
|
+
* Example: `foo: string | null`.
|
|
79
|
+
*/
|
|
80
|
+
get isNullable() {
|
|
81
|
+
if (!this.param.type) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (ts.isUnionTypeNode(this.param.type)) {
|
|
85
|
+
for (const _type of this.param.type.types) {
|
|
86
|
+
if (_type.getText() === "null") {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
get isVariadic() {
|
|
94
|
+
return this.param.dotDotDotToken !== undefined;
|
|
95
|
+
}
|
|
96
|
+
// TODO(TomChv): replace with `ToJson` method
|
|
97
|
+
// after the refactor is complete.
|
|
98
|
+
get typeDef() {
|
|
99
|
+
return {
|
|
100
|
+
name: this.name,
|
|
101
|
+
description: this.description,
|
|
102
|
+
optional: this.isOptional,
|
|
103
|
+
defaultValue: this.defaultValue,
|
|
104
|
+
isVariadic: this.isVariadic,
|
|
105
|
+
typeDef: this.type,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
toJSON() {
|
|
109
|
+
return {
|
|
110
|
+
name: this.name,
|
|
111
|
+
description: this.description,
|
|
112
|
+
type: this.type,
|
|
113
|
+
isVariadic: this.isVariadic,
|
|
114
|
+
isNullable: this.isNullable,
|
|
115
|
+
isOptional: this.isOptional,
|
|
116
|
+
defaultValue: this.defaultValue,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The TypeScript Compiler API returns the raw default value as it is written
|
|
121
|
+
* by the user.
|
|
122
|
+
* However, some notations are not supported by GraphQL so this function
|
|
123
|
+
* formats the default value to be compatible with the GraphQL syntax.
|
|
124
|
+
*
|
|
125
|
+
* Formatting rules:
|
|
126
|
+
* - Single quote strings are converted to double quote strings.
|
|
127
|
+
*
|
|
128
|
+
* @param value The value to format.
|
|
129
|
+
*/
|
|
130
|
+
formatDefaultValue(value) {
|
|
131
|
+
const isSingleQuoteString = () => value.startsWith("'") && value.endsWith("'");
|
|
132
|
+
if (isSingleQuoteString()) {
|
|
133
|
+
return `"${value.slice(1, value.length - 1)}"`;
|
|
134
|
+
}
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { Arguments } from "./argument.js";
|
|
3
|
+
import { ConstructorTypeDef } from "../typeDefs.js";
|
|
4
|
+
export declare class Constructor {
|
|
5
|
+
private checker;
|
|
6
|
+
private declaration;
|
|
7
|
+
constructor(checker: ts.TypeChecker, declaration: ts.ConstructorDeclaration);
|
|
8
|
+
get name(): string;
|
|
9
|
+
get arguments(): Arguments;
|
|
10
|
+
get typeDef(): ConstructorTypeDef;
|
|
11
|
+
toJSON(): {
|
|
12
|
+
args: Arguments;
|
|
13
|
+
};
|
|
14
|
+
getArgOrder(): string[];
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=constructor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constructor.d.ts","sourceRoot":"","sources":["../../../../introspector/scanner/abtractions/constructor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EAAY,SAAS,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAsB,MAAM,gBAAgB,CAAA;AAEvE,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAgB;IAE/B,OAAO,CAAC,WAAW,CAA2B;gBAElC,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,CAAC,sBAAsB;IAK3E,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,SAAS,IAAI,SAAS,CAgBzB;IAID,IAAI,OAAO,IAAI,kBAAkB,CAWhC;IAED,MAAM;;;IAMN,WAAW,IAAI,MAAM,EAAE;CAGxB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { UnknownDaggerError } from "../../../common/errors/UnknownDaggerError.js";
|
|
2
|
+
import { Argument } from "./argument.js";
|
|
3
|
+
export class Constructor {
|
|
4
|
+
checker;
|
|
5
|
+
declaration;
|
|
6
|
+
constructor(checker, declaration) {
|
|
7
|
+
this.checker = checker;
|
|
8
|
+
this.declaration = declaration;
|
|
9
|
+
}
|
|
10
|
+
get name() {
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
get arguments() {
|
|
14
|
+
return this.declaration.parameters.reduce((acc, param) => {
|
|
15
|
+
const symbol = this.checker.getSymbolAtLocation(param.name);
|
|
16
|
+
if (!symbol) {
|
|
17
|
+
throw new UnknownDaggerError(`could not get constructor param: ${param.name.getText()}`, {});
|
|
18
|
+
}
|
|
19
|
+
const argument = new Argument(this.checker, symbol);
|
|
20
|
+
acc[argument.name] = argument;
|
|
21
|
+
return acc;
|
|
22
|
+
}, {});
|
|
23
|
+
}
|
|
24
|
+
// TODO(TomChv): replace with `ToJson` method
|
|
25
|
+
// after the refactor is complete.
|
|
26
|
+
get typeDef() {
|
|
27
|
+
return {
|
|
28
|
+
args: Object.entries(this.arguments).reduce((acc, [name, arg]) => {
|
|
29
|
+
acc[name] = arg.typeDef;
|
|
30
|
+
return acc;
|
|
31
|
+
}, {}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
toJSON() {
|
|
35
|
+
return {
|
|
36
|
+
args: this.arguments,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
getArgOrder() {
|
|
40
|
+
return Object.keys(this.arguments);
|
|
41
|
+
}
|
|
42
|
+
}
|