@dagger.io/dagger 0.1.0 → 0.2.0

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/utils.js CHANGED
@@ -1,40 +1,112 @@
1
- export function queryBuilder(q) {
2
- const args = (item) => {
3
- const regex = /\{"[a-zA-Z]+"/gi;
4
- const entries = Object.entries(item.args)
5
- .filter((value) => value[1] !== undefined)
6
- .map((value) => {
7
- if (typeof value[1] === "object") {
8
- return `${value[0]}: ${JSON.stringify(value[1]).replace(regex, (str) => str.replace(/"/g, ""))}`;
9
- }
10
- if (typeof value[1] === "number") {
11
- return `${value[0]}: ${value[1]}`;
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ /* eslint-disable @typescript-eslint/no-explicit-any */
11
+ import { gql } from "graphql-request";
12
+ function buildArgs(item) {
13
+ const entries = Object.entries(item.args)
14
+ .filter((value) => value[1] !== undefined)
15
+ .map((value) => {
16
+ return `${value[0]}: ${JSON.stringify(value[1]).replace(/\{"[a-zA-Z]+"/gi, (str) => str.replace(/"/g, ""))}`;
17
+ });
18
+ if (entries.length === 0) {
19
+ return "";
20
+ }
21
+ return "(" + entries + ")";
22
+ }
23
+ /**
24
+ * Find querytree, convert them into GraphQl query
25
+ * then compute and return the result to the appropriate field
26
+ */
27
+ function computeNestedQuery(query, client) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ /**
30
+ * Check if there is a nested queryTree to be executed
31
+ */
32
+ const isQueryTree = (value) => Object.keys(value).find((val) => val === "_queryTree");
33
+ for (const q of query) {
34
+ if (q.args !== undefined) {
35
+ yield Promise.all(Object.entries(q.args).map((val) => __awaiter(this, void 0, void 0, function* () {
36
+ if (val[1] instanceof Object && isQueryTree(val[1])) {
37
+ // push an id that will be used by the container
38
+ val[1]["_queryTree"].push({ operation: "id" });
39
+ const getQueryTree = buildQuery(val[1]["_queryTree"]);
40
+ const result = yield compute(getQueryTree, client);
41
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
+ //@ts-ignore
43
+ q.args[val[0]] = result;
44
+ }
45
+ })));
12
46
  }
13
- return `${value[0]}: "${value[1]}"`;
14
- });
15
- if (entries.length === 0) {
16
- return "";
17
47
  }
18
- return "(" + entries + ")";
19
- };
48
+ });
49
+ }
50
+ /**
51
+ * Convert the queryTree into a GraphQL query
52
+ * @param q
53
+ * @returns
54
+ */
55
+ export function buildQuery(q) {
20
56
  let query = "{";
21
57
  q.forEach((item, index) => {
22
58
  query += `
23
- ${item.operation} ${item.args ? `${args(item)}` : ""} ${q.length - 1 !== index ? "{" : "}".repeat(q.length - 1)}
59
+ ${item.operation} ${item.args ? `${buildArgs(item)}` : ""} ${q.length - 1 !== index ? "{" : "}".repeat(q.length - 1)}
24
60
  `;
25
61
  });
26
62
  query += "}";
27
- return query.replace(/\s+/g, "");
63
+ return query;
64
+ }
65
+ /**
66
+ * Convert querytree into a Graphql query then compute it
67
+ * @param q | QueryTree[]
68
+ * @param client | GraphQLClient
69
+ * @returns
70
+ */
71
+ export function queryBuilder(q, client) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ yield computeNestedQuery(q, client);
74
+ const query = buildQuery(q);
75
+ const result = yield compute(query, client);
76
+ return result;
77
+ });
28
78
  }
29
- export function queryFlatten(res) {
30
- if (res.errors)
31
- throw res.errors[0];
32
- return Object.assign({}, ...(function _flatten(o) {
33
- return [].concat(...Object.keys(o).map((k) => {
34
- if (typeof o[k] === "object" && !(o[k] instanceof Array))
35
- return _flatten(o[k]);
36
- else
37
- return { [k]: o[k] };
38
- }));
39
- })(res));
79
+ /**
80
+ * Return a Graphql query result flattened
81
+ * @param response any
82
+ * @returns
83
+ */
84
+ export function queryFlatten(response) {
85
+ // Recursion break condition
86
+ // If our response is not an object or an array we assume we reached the value
87
+ if (!(response instanceof Object) || Array.isArray(response)) {
88
+ return response;
89
+ }
90
+ const keys = Object.keys(response);
91
+ if (keys.length != 1) {
92
+ // Dagger is currently expecting to only return one value
93
+ // If the response is nested in a way were more than one object is nested inside throw an error
94
+ // TODO Throw sensible Error
95
+ throw new Error("Too many Graphql nested objects");
96
+ }
97
+ const nestedKey = keys[0];
98
+ return queryFlatten(response[nestedKey]);
99
+ }
100
+ /**
101
+ * Send a GraphQL document to the server
102
+ * return a flatten result
103
+ * @hidden
104
+ */
105
+ export function compute(query, client) {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ const computeQuery = yield client.request(gql `
108
+ ${query}
109
+ `);
110
+ return queryFlatten(computeQuery);
111
+ });
40
112
  }
@@ -0,0 +1,21 @@
1
+ import { ConnectOpts, EngineConn } from "../engineconn.js";
2
+ import Client from "../../api/client.gen.js";
3
+ /**
4
+ * Bin runs an engine session from a specified binary
5
+ */
6
+ export declare class Bin implements EngineConn {
7
+ private subProcess?;
8
+ private path;
9
+ constructor(u: URL);
10
+ Addr(): string;
11
+ Connect(opts: ConnectOpts): Promise<Client>;
12
+ /**
13
+ * runEngineSession execute the engine binary and set up a GraphQL client that
14
+ * target this engine.
15
+ * TODO:(sipsma) dedupe this with equivalent code in image.ts
16
+ */
17
+ private runEngineSession;
18
+ private readPort;
19
+ Close(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../../provisioning/bin/bin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG1D,OAAO,MAAM,MAAM,yBAAyB,CAAA;AAE5C;;GAEG;AACH,qBAAa,GAAI,YAAW,UAAU;IACpC,OAAO,CAAC,UAAU,CAAC,CAAmB;IAEtC,OAAO,CAAC,IAAI,CAAQ;gBAER,CAAC,EAAE,GAAG;IAQlB,IAAI,IAAI,MAAM;IAIR,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjD;;;;OAIG;YACW,gBAAgB;YAqChB,QAAQ;IAShB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
@@ -0,0 +1,112 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
11
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
12
+ var m = o[Symbol.asyncIterator], i;
13
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
14
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
15
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
16
+ };
17
+ import readline from "readline";
18
+ import { execaCommand } from "execa";
19
+ import Client from "../../api/client.gen.js";
20
+ /**
21
+ * Bin runs an engine session from a specified binary
22
+ */
23
+ export class Bin {
24
+ constructor(u) {
25
+ this.path = u.host + u.pathname;
26
+ if (this.path == "") {
27
+ // this results in execa looking for it in the $PATH
28
+ this.path = "dagger-engine-session";
29
+ }
30
+ }
31
+ Addr() {
32
+ return "http://dagger";
33
+ }
34
+ Connect(opts) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ return this.runEngineSession(this.path, opts);
37
+ });
38
+ }
39
+ /**
40
+ * runEngineSession execute the engine binary and set up a GraphQL client that
41
+ * target this engine.
42
+ * TODO:(sipsma) dedupe this with equivalent code in image.ts
43
+ */
44
+ runEngineSession(engineSessionBinPath, opts) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ const engineSessionArgs = [engineSessionBinPath];
47
+ if (opts.Workdir) {
48
+ engineSessionArgs.push("--workdir", opts.Workdir);
49
+ }
50
+ if (opts.Project) {
51
+ engineSessionArgs.push("--project", opts.Project);
52
+ }
53
+ this.subProcess = execaCommand(engineSessionArgs.join(" "), {
54
+ stderr: opts.LogOutput || "ignore",
55
+ // Kill the process if parent exit.
56
+ cleanup: true,
57
+ });
58
+ const stdoutReader = readline.createInterface({
59
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
+ input: this.subProcess.stdout,
61
+ });
62
+ const port = yield Promise.race([
63
+ this.readPort(stdoutReader),
64
+ new Promise((_, reject) => {
65
+ setTimeout(() => {
66
+ reject(new Error("timeout reading port from engine session"));
67
+ }, 300000).unref(); // long timeout to account for extensions, though that should be optimized in future
68
+ }),
69
+ ]);
70
+ return new Client({ host: `127.0.0.1:${port}` });
71
+ });
72
+ }
73
+ readPort(stdoutReader) {
74
+ var _a, stdoutReader_1, stdoutReader_1_1;
75
+ var _b, e_1, _c, _d;
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ try {
78
+ for (_a = true, stdoutReader_1 = __asyncValues(stdoutReader); stdoutReader_1_1 = yield stdoutReader_1.next(), _b = stdoutReader_1_1.done, !_b;) {
79
+ _d = stdoutReader_1_1.value;
80
+ _a = false;
81
+ try {
82
+ const line = _d;
83
+ // Read line as a port number
84
+ const port = parseInt(line);
85
+ return port;
86
+ }
87
+ finally {
88
+ _a = true;
89
+ }
90
+ }
91
+ }
92
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
93
+ finally {
94
+ try {
95
+ if (!_a && !_b && (_c = stdoutReader_1.return)) yield _c.call(stdoutReader_1);
96
+ }
97
+ finally { if (e_1) throw e_1.error; }
98
+ }
99
+ throw new Error("failed to read port from engine session");
100
+ });
101
+ }
102
+ Close() {
103
+ var _a;
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ if ((_a = this.subProcess) === null || _a === void 0 ? void 0 : _a.pid) {
106
+ this.subProcess.kill("SIGTERM", {
107
+ forceKillAfterTimeout: 2000,
108
+ });
109
+ }
110
+ });
111
+ }
112
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./bin.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../provisioning/bin/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
@@ -0,0 +1 @@
1
+ export * from "./bin.js";
@@ -1 +1 @@
1
- {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../provisioning/default.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,QAAwC,CAAA"}
1
+ {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../provisioning/default.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,QAAwC,CAAA"}
@@ -1,2 +1,3 @@
1
- const DEFAULT_IMAGE_REF = "ghcr.io/dagger/engine:v0.3.4@sha256:666b958a2f716c0d6b22d869c585d6fe07954133ec769bb3d1f310e931cb118f";
1
+ // Code generated by dagger. DO NOT EDIT.
2
+ const DEFAULT_IMAGE_REF = "ghcr.io/dagger/engine:v0.3.6@sha256:d124de285773409fd83d203d3f46364e20149ee46842c50eec6cc51c50fffb62";
2
3
  export const DEFAULT_HOST = `docker-image://${DEFAULT_IMAGE_REF}`;
@@ -1 +1 @@
1
- {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../provisioning/docker-provision/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAM1D,OAAO,MAAM,MAAM,yBAAyB,CAAA;AAqD5C;;;GAGG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC5C,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGxB;IAED,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA0B;IAEvE,OAAO,CAAC,UAAU,CAAC,CAAmB;gBAE1B,CAAC,EAAE,GAAG;IAIlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,IAAI,IAAI,MAAM;IAIR,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAWjD;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA+D5B;;;OAGG;YACW,gBAAgB;YAyChB,QAAQ;IAShB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../provisioning/docker-provision/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAM1D,OAAO,MAAM,MAAM,yBAAyB,CAAA;AAqD5C;;;GAGG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC5C,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGxB;IAED,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA0B;IAEvE,OAAO,CAAC,UAAU,CAAC,CAAmB;gBAE1B,CAAC,EAAE,GAAG;IAIlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,IAAI,IAAI,MAAM;IAIR,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAWjD;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA+D5B;;;OAGG;YACW,gBAAgB;YA4ChB,QAAQ;IAShB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
@@ -195,11 +195,11 @@ export class DockerImage {
195
195
  */
196
196
  runEngineSession(engineSessionBinPath, opts) {
197
197
  return __awaiter(this, void 0, void 0, function* () {
198
- const engineSessionArgs = [
199
- engineSessionBinPath,
200
- "--remote",
201
- `docker-image://${this.imageRef.Ref}`,
202
- ];
198
+ const env = process.env;
199
+ if (!env.DAGGER_RUNNER_HOST) {
200
+ env.DAGGER_RUNNER_HOST = `docker-image://${this.imageRef.Ref}`;
201
+ }
202
+ const engineSessionArgs = [engineSessionBinPath];
203
203
  if (opts.Workdir) {
204
204
  engineSessionArgs.push("--workdir", opts.Workdir);
205
205
  }
@@ -210,6 +210,7 @@ export class DockerImage {
210
210
  stderr: opts.LogOutput || "ignore",
211
211
  // Kill the process if parent exit.
212
212
  cleanup: true,
213
+ env: env,
213
214
  });
214
215
  const stdoutReader = readline.createInterface({
215
216
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../provisioning/provisioner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAW5C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAWvD"}
1
+ {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../provisioning/provisioner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAa5C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAWvD"}
@@ -1,8 +1,10 @@
1
1
  import { DockerImage } from "./docker-provision/image.js";
2
2
  import { HTTP } from "./http/http.js";
3
+ import { Bin } from "./bin/bin.js";
3
4
  const provisioners = {
4
5
  "docker-image": (u) => new DockerImage(u),
5
6
  http: (u) => new HTTP(u),
7
+ bin: (u) => new Bin(u),
6
8
  };
7
9
  /**
8
10
  * getProvisioner returns a ready to use Engine connector.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dagger.io/dagger",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "author": "hello@dagger.io",
5
5
  "license": "Apache-2.0",
6
6
  "types": "./dist/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "main": "dist/index.js",
18
18
  "dependencies": {
19
19
  "@lifeomic/axios-fetch": "^3.0.1",
20
- "axios": "^1.1.2",
20
+ "axios": "^1.2.0",
21
21
  "execa": "^6.1.0",
22
22
  "graphql": "^16.5.0",
23
23
  "graphql-request": "^5.0.0",
@@ -29,18 +29,18 @@
29
29
  "test": "mocha",
30
30
  "gen:typedoc": "yarn typedoc",
31
31
  "lint": "yarn eslint --max-warnings=0 .",
32
- "fmt": "yarn eslint --fix ."
32
+ "fmt": "yarn eslint --fix"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/mocha": "latest",
36
36
  "@types/node": "~16",
37
- "@typescript-eslint/eslint-plugin": "^5.42.1",
38
- "@typescript-eslint/parser": "^5.42.1",
39
- "eslint": "^8.27.0",
37
+ "@typescript-eslint/eslint-plugin": "^5.45.0",
38
+ "@typescript-eslint/parser": "^5.45.0",
39
+ "eslint": "^8.28.0",
40
40
  "eslint-config-prettier": "^8.5.0",
41
41
  "eslint-plugin-prettier": "^4.2.1",
42
42
  "mocha": "^10.1.0",
43
- "prettier": "^2.7.1",
43
+ "prettier": "^2.8.0",
44
44
  "ts-node": "^10.9.1",
45
45
  "typedoc": "^0.23.21",
46
46
  "typedoc-plugin-markdown": "^3.13.6",