@printwithsynergy/artwork-pdf 0.2.1 → 0.3.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/index.d.ts CHANGED
@@ -1,11 +1,37 @@
1
+ /**
2
+ * One stage in a synergy workflow.
3
+ *
4
+ * `nodeType` is the dotted node identifier the synergy engine routes
5
+ * on (e.g. `"artwork.render"`). `config` is node-specific — for
6
+ * artwork.* nodes it's the `JobSubmitRequest` shape from
7
+ * `@artworkpdf/document-model`; for other node types it follows that
8
+ * node's own schema. Synergy validates per-node-type at submit time.
9
+ */
1
10
  export type WorkflowStage = {
2
11
  nodeType: string;
3
12
  config?: Record<string, unknown>;
4
13
  };
14
+ /**
15
+ * Body shape for `POST /api/v1/workflows`.
16
+ *
17
+ * `stages` are executed in declaration order; each stage's output
18
+ * becomes the next stage's input (synergy handles the threading).
19
+ * `input` seeds the first stage — typically the source document or
20
+ * asset reference that flows through the pipeline.
21
+ */
5
22
  export type WorkflowSubmitRequest = {
6
23
  stages: WorkflowStage[];
7
24
  input: Record<string, unknown>;
8
25
  };
26
+ /**
27
+ * Workflow run state, returned by both submit and poll endpoints.
28
+ *
29
+ * `status` is the run-level state machine:
30
+ * `queued → running → done | failed`. Per-stage progress lives in
31
+ * `stages[]` — each entry's `status` is opaquely-typed since each
32
+ * node type defines its own stage state vocabulary; consumers
33
+ * generally only display it or filter on terminal values.
34
+ */
9
35
  export type WorkflowRun = {
10
36
  id: string;
11
37
  status: "queued" | "running" | "done" | "failed";
@@ -14,10 +40,44 @@ export type WorkflowRun = {
14
40
  status: string;
15
41
  }>;
16
42
  };
43
+ /**
44
+ * Minimal HTTP client for the synergy engine's workflow API.
45
+ *
46
+ * Two methods cover the artwork-pdf use case: submit a workflow,
47
+ * poll a workflow run. Both authenticate via the `x-api-key`
48
+ * header; both throw on non-2xx responses with the HTTP status in
49
+ * the message (the synergy API returns a JSON error body, but this
50
+ * skeleton client surfaces only the status code — richer error
51
+ * shapes can land later without breaking the constructor signature).
52
+ *
53
+ * **Response-shape trust:** the 2xx JSON is cast directly to
54
+ * {@link WorkflowRun} without runtime validation. Downstream code
55
+ * is type-safe relative to the synergy contract, not relative to
56
+ * arbitrary network bytes — if the engine ships an incompatible
57
+ * shape, errors surface at the consumer site, not here. Runtime
58
+ * validation (zod) is a future follow-up.
59
+ *
60
+ * The client is stateless apart from `baseUrl` + `apiKey` and is
61
+ * safe to reuse across requests; instantiate once per process.
62
+ */
17
63
  export declare class SynergyClient {
18
64
  #private;
19
65
  constructor(baseUrl: string, apiKey: string);
66
+ /**
67
+ * `POST /api/v1/workflows` — submit a new workflow run.
68
+ * Resolves with the initial {@link WorkflowRun} (typically in
69
+ * `"queued"` state). Throws `Error("synergy error: <status>")` on
70
+ * non-2xx.
71
+ */
20
72
  submitWorkflow(req: WorkflowSubmitRequest): Promise<WorkflowRun>;
73
+ /**
74
+ * `GET /api/v1/workflows/:id` — poll the current state of a
75
+ * previously-submitted workflow run.
76
+ *
77
+ * No long-polling or SSE in this client; callers poll on their
78
+ * own cadence. Throws `Error("synergy error: <status>")` on
79
+ * non-2xx (including 404 for unknown ids).
80
+ */
21
81
  getWorkflow(id: string): Promise<WorkflowRun>;
22
82
  }
23
83
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACjD,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD,CAAC;AAEF,qBAAa,aAAa;;gBAIZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKrC,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IAahE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAOpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACjD,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,aAAa;;gBAIZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAK3C;;;;;OAKG;IACG,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IAatE;;;;;;;OAOG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAOpD"}
package/dist/index.js CHANGED
@@ -1,4 +1,41 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ //
3
+ // `@printwithsynergy/artwork-pdf` — typed HTTP client for the synergy
4
+ // engine's workflow API, scoped to artworkPDF's node usage.
5
+ //
6
+ // The synergy engine orchestrates multi-stage pipelines across
7
+ // disparate node types (`artwork.render`, `artwork.thumbnail`,
8
+ // `artwork.preview-separations` plus equivalents from sibling
9
+ // nodes). artwork-pdf hosts that want to submit synergy workflows
10
+ // (e.g. the marketing site's "submit-for-print" flow) use this
11
+ // client; it is *not* the in-process pg-boss boundary inside
12
+ // `apps/service` — that boundary lives in `apps/service/src/db/boss.ts`
13
+ // and consumes jobs that synergy enqueued.
14
+ //
15
+ // Public surface:
16
+ // - {@link WorkflowStage} / {@link WorkflowSubmitRequest} /
17
+ // {@link WorkflowRun} — wire shapes for `/api/v1/workflows`.
18
+ // - {@link SynergyClient} — minimal POST/GET client.
19
+ /**
20
+ * Minimal HTTP client for the synergy engine's workflow API.
21
+ *
22
+ * Two methods cover the artwork-pdf use case: submit a workflow,
23
+ * poll a workflow run. Both authenticate via the `x-api-key`
24
+ * header; both throw on non-2xx responses with the HTTP status in
25
+ * the message (the synergy API returns a JSON error body, but this
26
+ * skeleton client surfaces only the status code — richer error
27
+ * shapes can land later without breaking the constructor signature).
28
+ *
29
+ * **Response-shape trust:** the 2xx JSON is cast directly to
30
+ * {@link WorkflowRun} without runtime validation. Downstream code
31
+ * is type-safe relative to the synergy contract, not relative to
32
+ * arbitrary network bytes — if the engine ships an incompatible
33
+ * shape, errors surface at the consumer site, not here. Runtime
34
+ * validation (zod) is a future follow-up.
35
+ *
36
+ * The client is stateless apart from `baseUrl` + `apiKey` and is
37
+ * safe to reuse across requests; instantiate once per process.
38
+ */
2
39
  export class SynergyClient {
3
40
  #baseUrl;
4
41
  #apiKey;
@@ -6,6 +43,12 @@ export class SynergyClient {
6
43
  this.#baseUrl = baseUrl;
7
44
  this.#apiKey = apiKey;
8
45
  }
46
+ /**
47
+ * `POST /api/v1/workflows` — submit a new workflow run.
48
+ * Resolves with the initial {@link WorkflowRun} (typically in
49
+ * `"queued"` state). Throws `Error("synergy error: <status>")` on
50
+ * non-2xx.
51
+ */
9
52
  async submitWorkflow(req) {
10
53
  const res = await fetch(`${this.#baseUrl}/api/v1/workflows`, {
11
54
  method: "POST",
@@ -19,6 +62,14 @@ export class SynergyClient {
19
62
  throw new Error(`synergy error: ${res.status}`);
20
63
  return res.json();
21
64
  }
65
+ /**
66
+ * `GET /api/v1/workflows/:id` — poll the current state of a
67
+ * previously-submitted workflow run.
68
+ *
69
+ * No long-polling or SSE in this client; callers poll on their
70
+ * own cadence. Throws `Error("synergy error: <status>")` on
71
+ * non-2xx (including 404 for unknown ids).
72
+ */
22
73
  async getWorkflow(id) {
23
74
  const res = await fetch(`${this.#baseUrl}/api/v1/workflows/${id}`, {
24
75
  headers: { "x-api-key": this.#apiKey },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAkB7C,MAAM,OAAO,aAAa;IACf,QAAQ,CAAS;IACjB,OAAO,CAAS;IAEzB,YAAY,OAAe,EAAE,MAAc;QACzC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,GAA0B;QAC7C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,mBAAmB,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,IAAI,CAAC,OAAO;aAC1B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC,IAAI,EAA0B,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC1B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,qBAAqB,EAAE,EAAE,EAAE;YACjE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE;SACvC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC,IAAI,EAA0B,CAAC;IAC5C,CAAC;CACF"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,4DAA4D;AAC5D,EAAE;AACF,+DAA+D;AAC/D,+DAA+D;AAC/D,8DAA8D;AAC9D,kEAAkE;AAClE,+DAA+D;AAC/D,6DAA6D;AAC7D,wEAAwE;AACxE,2CAA2C;AAC3C,EAAE;AACF,kBAAkB;AAClB,4DAA4D;AAC5D,+DAA+D;AAC/D,qDAAqD;AA4CrD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,aAAa;IACf,QAAQ,CAAS;IACjB,OAAO,CAAS;IAEzB,YAAY,OAAe,EAAE,MAAc;QACzC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,GAA0B;QAC7C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,mBAAmB,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,IAAI,CAAC,OAAO;aAC1B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC,IAAI,EAA0B,CAAC;IAC5C,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CAAC,EAAU;QAC1B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,qBAAqB,EAAE,EAAE,EAAE;YACjE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE;SACvC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC,IAAI,EAA0B,CAAC;IAC5C,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@printwithsynergy/artwork-pdf",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Typed client for the artworkPDF synergy node",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "type": "module",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "devDependencies": {
18
18
  "typescript": "^5.7.0",
19
- "vitest": "^2.1.0"
19
+ "vitest": "^4.1.0"
20
20
  },
21
21
  "scripts": {
22
22
  "build": "tsc",
package/src/index.ts CHANGED
@@ -1,21 +1,84 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ //
3
+ // `@printwithsynergy/artwork-pdf` — typed HTTP client for the synergy
4
+ // engine's workflow API, scoped to artworkPDF's node usage.
5
+ //
6
+ // The synergy engine orchestrates multi-stage pipelines across
7
+ // disparate node types (`artwork.render`, `artwork.thumbnail`,
8
+ // `artwork.preview-separations` plus equivalents from sibling
9
+ // nodes). artwork-pdf hosts that want to submit synergy workflows
10
+ // (e.g. the marketing site's "submit-for-print" flow) use this
11
+ // client; it is *not* the in-process pg-boss boundary inside
12
+ // `apps/service` — that boundary lives in `apps/service/src/db/boss.ts`
13
+ // and consumes jobs that synergy enqueued.
14
+ //
15
+ // Public surface:
16
+ // - {@link WorkflowStage} / {@link WorkflowSubmitRequest} /
17
+ // {@link WorkflowRun} — wire shapes for `/api/v1/workflows`.
18
+ // - {@link SynergyClient} — minimal POST/GET client.
2
19
 
20
+ /**
21
+ * One stage in a synergy workflow.
22
+ *
23
+ * `nodeType` is the dotted node identifier the synergy engine routes
24
+ * on (e.g. `"artwork.render"`). `config` is node-specific — for
25
+ * artwork.* nodes it's the `JobSubmitRequest` shape from
26
+ * `@artworkpdf/document-model`; for other node types it follows that
27
+ * node's own schema. Synergy validates per-node-type at submit time.
28
+ */
3
29
  export type WorkflowStage = {
4
30
  nodeType: string;
5
31
  config?: Record<string, unknown>;
6
32
  };
7
33
 
34
+ /**
35
+ * Body shape for `POST /api/v1/workflows`.
36
+ *
37
+ * `stages` are executed in declaration order; each stage's output
38
+ * becomes the next stage's input (synergy handles the threading).
39
+ * `input` seeds the first stage — typically the source document or
40
+ * asset reference that flows through the pipeline.
41
+ */
8
42
  export type WorkflowSubmitRequest = {
9
43
  stages: WorkflowStage[];
10
44
  input: Record<string, unknown>;
11
45
  };
12
46
 
47
+ /**
48
+ * Workflow run state, returned by both submit and poll endpoints.
49
+ *
50
+ * `status` is the run-level state machine:
51
+ * `queued → running → done | failed`. Per-stage progress lives in
52
+ * `stages[]` — each entry's `status` is opaquely-typed since each
53
+ * node type defines its own stage state vocabulary; consumers
54
+ * generally only display it or filter on terminal values.
55
+ */
13
56
  export type WorkflowRun = {
14
57
  id: string;
15
58
  status: "queued" | "running" | "done" | "failed";
16
59
  stages: Array<{ nodeType: string; status: string }>;
17
60
  };
18
61
 
62
+ /**
63
+ * Minimal HTTP client for the synergy engine's workflow API.
64
+ *
65
+ * Two methods cover the artwork-pdf use case: submit a workflow,
66
+ * poll a workflow run. Both authenticate via the `x-api-key`
67
+ * header; both throw on non-2xx responses with the HTTP status in
68
+ * the message (the synergy API returns a JSON error body, but this
69
+ * skeleton client surfaces only the status code — richer error
70
+ * shapes can land later without breaking the constructor signature).
71
+ *
72
+ * **Response-shape trust:** the 2xx JSON is cast directly to
73
+ * {@link WorkflowRun} without runtime validation. Downstream code
74
+ * is type-safe relative to the synergy contract, not relative to
75
+ * arbitrary network bytes — if the engine ships an incompatible
76
+ * shape, errors surface at the consumer site, not here. Runtime
77
+ * validation (zod) is a future follow-up.
78
+ *
79
+ * The client is stateless apart from `baseUrl` + `apiKey` and is
80
+ * safe to reuse across requests; instantiate once per process.
81
+ */
19
82
  export class SynergyClient {
20
83
  readonly #baseUrl: string;
21
84
  readonly #apiKey: string;
@@ -25,6 +88,12 @@ export class SynergyClient {
25
88
  this.#apiKey = apiKey;
26
89
  }
27
90
 
91
+ /**
92
+ * `POST /api/v1/workflows` — submit a new workflow run.
93
+ * Resolves with the initial {@link WorkflowRun} (typically in
94
+ * `"queued"` state). Throws `Error("synergy error: <status>")` on
95
+ * non-2xx.
96
+ */
28
97
  async submitWorkflow(req: WorkflowSubmitRequest): Promise<WorkflowRun> {
29
98
  const res = await fetch(`${this.#baseUrl}/api/v1/workflows`, {
30
99
  method: "POST",
@@ -38,6 +107,14 @@ export class SynergyClient {
38
107
  return res.json() as Promise<WorkflowRun>;
39
108
  }
40
109
 
110
+ /**
111
+ * `GET /api/v1/workflows/:id` — poll the current state of a
112
+ * previously-submitted workflow run.
113
+ *
114
+ * No long-polling or SSE in this client; callers poll on their
115
+ * own cadence. Throws `Error("synergy error: <status>")` on
116
+ * non-2xx (including 404 for unknown ids).
117
+ */
41
118
  async getWorkflow(id: string): Promise<WorkflowRun> {
42
119
  const res = await fetch(`${this.#baseUrl}/api/v1/workflows/${id}`, {
43
120
  headers: { "x-api-key": this.#apiKey },