gooseworks 0.2.4 → 0.2.6

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.
Files changed (46) hide show
  1. package/dist/auth/oauth-server.d.ts.map +1 -1
  2. package/dist/auth/oauth-server.js +27 -19
  3. package/dist/auth/oauth-server.js.map +1 -1
  4. package/dist/commands/formats.d.ts +3 -0
  5. package/dist/commands/formats.d.ts.map +1 -0
  6. package/dist/commands/formats.js +157 -0
  7. package/dist/commands/formats.js.map +1 -0
  8. package/dist/commands/graphics/get-flow.d.ts +30 -0
  9. package/dist/commands/graphics/get-flow.d.ts.map +1 -0
  10. package/dist/commands/graphics/get-flow.js +212 -0
  11. package/dist/commands/graphics/get-flow.js.map +1 -0
  12. package/dist/commands/graphics/publish-flow.d.ts +33 -0
  13. package/dist/commands/graphics/publish-flow.d.ts.map +1 -0
  14. package/dist/commands/graphics/publish-flow.js +180 -0
  15. package/dist/commands/graphics/publish-flow.js.map +1 -0
  16. package/dist/commands/graphics/shared.d.ts +48 -0
  17. package/dist/commands/graphics/shared.d.ts.map +1 -0
  18. package/dist/commands/graphics/shared.js +190 -0
  19. package/dist/commands/graphics/shared.js.map +1 -0
  20. package/dist/commands/styles.d.ts +3 -0
  21. package/dist/commands/styles.d.ts.map +1 -0
  22. package/dist/commands/styles.js +159 -0
  23. package/dist/commands/styles.js.map +1 -0
  24. package/dist/config.d.ts +2 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +5 -1
  27. package/dist/config.js.map +1 -1
  28. package/dist/index.js +4 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/graphics-api.d.ts +106 -0
  31. package/dist/lib/graphics-api.d.ts.map +1 -0
  32. package/dist/lib/graphics-api.js +310 -0
  33. package/dist/lib/graphics-api.js.map +1 -0
  34. package/dist/lib/graphics-cache.d.ts +31 -0
  35. package/dist/lib/graphics-cache.d.ts.map +1 -0
  36. package/dist/lib/graphics-cache.js +126 -0
  37. package/dist/lib/graphics-cache.js.map +1 -0
  38. package/dist/lib/graphics-manifest.d.ts +96 -0
  39. package/dist/lib/graphics-manifest.d.ts.map +1 -0
  40. package/dist/lib/graphics-manifest.js +289 -0
  41. package/dist/lib/graphics-manifest.js.map +1 -0
  42. package/dist/skills/fetcher.d.ts +18 -0
  43. package/dist/skills/fetcher.d.ts.map +1 -0
  44. package/dist/skills/fetcher.js +118 -0
  45. package/dist/skills/fetcher.js.map +1 -0
  46. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEU,QAAA,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,2BAA2B,CAAC;AAC1E,QAAA,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,2BAA2B,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEU,QAAA,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,2BAA2B,CAAC;AAC1E,QAAA,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,2BAA2B,CAAC;AAC/F,mFAAmF;AACnF,8FAA8F;AACjF,QAAA,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -8,6 +8,8 @@ const logout_1 = require("./commands/logout");
8
8
  const update_1 = require("./commands/update");
9
9
  const credits_1 = require("./commands/credits");
10
10
  const search_1 = require("./commands/search");
11
+ const styles_1 = require("./commands/styles");
12
+ const formats_1 = require("./commands/formats");
11
13
  const version_1 = require("./version");
12
14
  const program = new commander_1.Command();
13
15
  program
@@ -20,5 +22,7 @@ program.addCommand(logout_1.logoutCommand);
20
22
  program.addCommand(update_1.updateCommand);
21
23
  program.addCommand(credits_1.creditsCommand);
22
24
  program.addCommand(search_1.searchCommand);
25
+ program.addCommand(styles_1.stylesCommand);
26
+ program.addCommand(formats_1.formatsCommand);
23
27
  program.parse();
24
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,gDAAoD;AACpD,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,8CAAkD;AAClD,uCAAuC;AAEvC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,IAAA,oBAAU,GAAE,CAAC,CAAC;AAEzB,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,gDAAoD;AACpD,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,uCAAuC;AAEvC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,IAAA,oBAAU,GAAE,CAAC,CAAC;AAEzB,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,sBAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,wBAAc,CAAC,CAAC;AAEnC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * HTTP client for the Gooseworks graphics API.
3
+ *
4
+ * Uses the global fetch (Node 18+) and FormData/Blob for multipart uploads.
5
+ * Endpoint shapes are documented in gooseworks-app GOOSE-1468.
6
+ */
7
+ import type { ResolvedExampleFile } from './graphics-manifest';
8
+ export interface ApiClientOptions {
9
+ apiBase: string;
10
+ /** Bearer token. Optional for public reads, but always sent if available. */
11
+ apiKey?: string | null;
12
+ }
13
+ export interface AuthedApiClientOptions {
14
+ apiBase: string;
15
+ apiKey: string;
16
+ }
17
+ export declare class ApiError extends Error {
18
+ readonly status: number;
19
+ readonly code: string | null;
20
+ readonly body?: unknown | undefined;
21
+ constructor(status: number, code: string | null, message: string, body?: unknown | undefined);
22
+ }
23
+ export declare class NetworkError extends Error {
24
+ readonly cause?: unknown | undefined;
25
+ constructor(message: string, cause?: unknown | undefined);
26
+ }
27
+ export interface ListQuery {
28
+ q?: string;
29
+ mood?: string;
30
+ tag?: string;
31
+ featured?: boolean;
32
+ limit?: number;
33
+ offset?: number;
34
+ }
35
+ export interface GraphicStyleSummary {
36
+ id: string;
37
+ slug: string;
38
+ name: string;
39
+ description?: string | null;
40
+ moodGroup?: string | null;
41
+ tags?: string[];
42
+ featured?: boolean;
43
+ authorHandle?: string | null;
44
+ [key: string]: unknown;
45
+ }
46
+ export interface GraphicFormatSummary {
47
+ id: string;
48
+ slug: string;
49
+ name: string;
50
+ description?: string | null;
51
+ width?: number;
52
+ height?: number;
53
+ featured?: boolean;
54
+ authorHandle?: string | null;
55
+ [key: string]: unknown;
56
+ }
57
+ export interface ListEnvelope<T> {
58
+ status: 'success';
59
+ data: T[];
60
+ meta?: {
61
+ total?: number;
62
+ limit?: number;
63
+ offset?: number;
64
+ };
65
+ }
66
+ export declare function listStyles(opts: ApiClientOptions, query?: ListQuery): Promise<ListEnvelope<GraphicStyleSummary>>;
67
+ export declare function listFormats(opts: ApiClientOptions, query?: ListQuery): Promise<ListEnvelope<GraphicFormatSummary>>;
68
+ export interface ItemEnvelope<T> {
69
+ status: 'success';
70
+ data: T;
71
+ }
72
+ /**
73
+ * ETag-aware response for JSON record fetches. On 304, `envelope` is null
74
+ * and the caller should fall back to its cached body.
75
+ */
76
+ export interface RecordResponse<T> {
77
+ status: 200 | 304;
78
+ envelope: ItemEnvelope<T> | null;
79
+ etag: string | null;
80
+ }
81
+ export declare function getStyleRecord(opts: ApiClientOptions, slug: string, etag?: string | null): Promise<RecordResponse<GraphicStyleSummary & {
82
+ examples?: unknown[];
83
+ }>>;
84
+ export declare function getFormatRecord(opts: ApiClientOptions, slug: string, etag?: string | null): Promise<RecordResponse<GraphicFormatSummary & {
85
+ examples?: unknown[];
86
+ }>>;
87
+ export interface MarkdownResponse {
88
+ /** 200 with a fresh body, or 304 if If-None-Match matched (body is null). */
89
+ status: 200 | 304;
90
+ body: string | null;
91
+ etag: string | null;
92
+ }
93
+ export declare function getStyleDesignMd(opts: ApiClientOptions, slug: string, etag?: string | null): Promise<MarkdownResponse>;
94
+ export declare function getFormatSpecMd(opts: ApiClientOptions, slug: string, etag?: string | null): Promise<MarkdownResponse>;
95
+ export interface WriteResult {
96
+ slug: string;
97
+ id: string;
98
+ }
99
+ export declare function publishStyle(opts: AuthedApiClientOptions, manifest: unknown, files: ResolvedExampleFile[]): Promise<WriteResult>;
100
+ export declare function updateStyle(opts: AuthedApiClientOptions, slug: string, manifest: unknown, files: ResolvedExampleFile[]): Promise<WriteResult>;
101
+ export declare function deleteStyle(opts: AuthedApiClientOptions, slug: string): Promise<void>;
102
+ export declare function publishFormat(opts: AuthedApiClientOptions, manifest: unknown, files: ResolvedExampleFile[]): Promise<WriteResult>;
103
+ export declare function updateFormat(opts: AuthedApiClientOptions, slug: string, manifest: unknown, files: ResolvedExampleFile[]): Promise<WriteResult>;
104
+ export declare function deleteFormat(opts: AuthedApiClientOptions, slug: string): Promise<void>;
105
+ export declare function downloadBytes(url: string): Promise<Buffer>;
106
+ //# sourceMappingURL=graphics-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphics-api.d.ts","sourceRoot":"","sources":["../../src/lib/graphics-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ /**
3
+ * HTTP client for the Gooseworks graphics API.
4
+ *
5
+ * Uses the global fetch (Node 18+) and FormData/Blob for multipart uploads.
6
+ * Endpoint shapes are documented in gooseworks-app GOOSE-1468.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.NetworkError = exports.ApiError = void 0;
43
+ exports.listStyles = listStyles;
44
+ exports.listFormats = listFormats;
45
+ exports.getStyleRecord = getStyleRecord;
46
+ exports.getFormatRecord = getFormatRecord;
47
+ exports.getStyleDesignMd = getStyleDesignMd;
48
+ exports.getFormatSpecMd = getFormatSpecMd;
49
+ exports.publishStyle = publishStyle;
50
+ exports.updateStyle = updateStyle;
51
+ exports.deleteStyle = deleteStyle;
52
+ exports.publishFormat = publishFormat;
53
+ exports.updateFormat = updateFormat;
54
+ exports.deleteFormat = deleteFormat;
55
+ exports.downloadBytes = downloadBytes;
56
+ const fs = __importStar(require("fs"));
57
+ const path = __importStar(require("path"));
58
+ class ApiError extends Error {
59
+ status;
60
+ code;
61
+ body;
62
+ constructor(status, code, message, body) {
63
+ super(message);
64
+ this.status = status;
65
+ this.code = code;
66
+ this.body = body;
67
+ this.name = 'ApiError';
68
+ }
69
+ }
70
+ exports.ApiError = ApiError;
71
+ class NetworkError extends Error {
72
+ cause;
73
+ constructor(message, cause) {
74
+ super(message);
75
+ this.cause = cause;
76
+ this.name = 'NetworkError';
77
+ }
78
+ }
79
+ exports.NetworkError = NetworkError;
80
+ function authHeaders(apiKey) {
81
+ return apiKey ? { Authorization: `Bearer ${apiKey}` } : {};
82
+ }
83
+ async function readJsonSafe(res) {
84
+ const text = await res.text();
85
+ if (!text)
86
+ return null;
87
+ try {
88
+ return JSON.parse(text);
89
+ }
90
+ catch {
91
+ return text;
92
+ }
93
+ }
94
+ function extractMessage(body, fallback) {
95
+ if (body && typeof body === 'object') {
96
+ const env = body;
97
+ if (typeof env.message === 'string')
98
+ return env.message;
99
+ if (typeof env.error === 'string')
100
+ return env.error;
101
+ }
102
+ return fallback;
103
+ }
104
+ async function asApiError(res, defaultMessage) {
105
+ const body = await readJsonSafe(res);
106
+ let code = null;
107
+ if (body && typeof body === 'object' && typeof body.error === 'string') {
108
+ code = body.error || null;
109
+ }
110
+ return new ApiError(res.status, code, extractMessage(body, defaultMessage), body);
111
+ }
112
+ async function safeFetch(url, init) {
113
+ try {
114
+ return await fetch(url, init);
115
+ }
116
+ catch (err) {
117
+ const message = err instanceof Error ? err.message : String(err);
118
+ throw new NetworkError(message, err);
119
+ }
120
+ }
121
+ function buildQuery(q) {
122
+ const params = new URLSearchParams();
123
+ if (q.q)
124
+ params.set('q', q.q);
125
+ if (q.mood)
126
+ params.set('mood', q.mood);
127
+ if (q.tag)
128
+ params.set('tag', q.tag);
129
+ if (q.featured)
130
+ params.set('featured', 'true');
131
+ if (q.limit !== undefined)
132
+ params.set('limit', String(q.limit));
133
+ if (q.offset !== undefined)
134
+ params.set('offset', String(q.offset));
135
+ const s = params.toString();
136
+ return s ? `?${s}` : '';
137
+ }
138
+ async function getJsonEnvelope(url, apiKey) {
139
+ const res = await safeFetch(url, {
140
+ method: 'GET',
141
+ headers: { Accept: 'application/json', ...authHeaders(apiKey) },
142
+ });
143
+ if (!res.ok)
144
+ throw await asApiError(res, `request failed (${res.status})`);
145
+ const body = (await readJsonSafe(res));
146
+ if (!body || body.status !== 'success') {
147
+ throw new ApiError(res.status, null, 'unexpected response shape', body);
148
+ }
149
+ return body;
150
+ }
151
+ async function listStyles(opts, query = {}) {
152
+ const url = `${opts.apiBase}/api/graphics/styles${buildQuery(query)}`;
153
+ return getJsonEnvelope(url, opts.apiKey);
154
+ }
155
+ async function listFormats(opts, query = {}) {
156
+ const url = `${opts.apiBase}/api/graphics/formats${buildQuery(query)}`;
157
+ return getJsonEnvelope(url, opts.apiKey);
158
+ }
159
+ async function fetchRecord(url, apiKey, etag) {
160
+ const headers = {
161
+ Accept: 'application/json',
162
+ ...authHeaders(apiKey),
163
+ };
164
+ if (etag)
165
+ headers['If-None-Match'] = etag;
166
+ const res = await safeFetch(url, { method: 'GET', headers });
167
+ if (res.status === 304) {
168
+ return { status: 304, envelope: null, etag };
169
+ }
170
+ if (!res.ok)
171
+ throw await asApiError(res, `request failed (${res.status})`);
172
+ const body = (await readJsonSafe(res));
173
+ if (!body || body.status !== 'success') {
174
+ throw new ApiError(res.status, null, 'unexpected response shape', body);
175
+ }
176
+ return {
177
+ status: 200,
178
+ envelope: body,
179
+ etag: res.headers.get('etag'),
180
+ };
181
+ }
182
+ async function getStyleRecord(opts, slug, etag = null) {
183
+ const url = `${opts.apiBase}/api/graphics/styles/${encodeURIComponent(slug)}`;
184
+ return fetchRecord(url, opts.apiKey, etag);
185
+ }
186
+ async function getFormatRecord(opts, slug, etag = null) {
187
+ const url = `${opts.apiBase}/api/graphics/formats/${encodeURIComponent(slug)}`;
188
+ return fetchRecord(url, opts.apiKey, etag);
189
+ }
190
+ async function fetchMarkdown(url, apiKey, etag) {
191
+ const headers = {
192
+ Accept: 'text/plain',
193
+ ...authHeaders(apiKey),
194
+ };
195
+ if (etag)
196
+ headers['If-None-Match'] = etag;
197
+ const res = await safeFetch(url, { method: 'GET', headers });
198
+ if (res.status === 304) {
199
+ return { status: 304, body: null, etag };
200
+ }
201
+ if (!res.ok)
202
+ throw await asApiError(res, `request failed (${res.status})`);
203
+ const body = await res.text();
204
+ return { status: 200, body, etag: res.headers.get('etag') };
205
+ }
206
+ async function getStyleDesignMd(opts, slug, etag = null) {
207
+ const url = `${opts.apiBase}/api/graphics/styles/${encodeURIComponent(slug)}/design.md`;
208
+ return fetchMarkdown(url, opts.apiKey, etag);
209
+ }
210
+ async function getFormatSpecMd(opts, slug, etag = null) {
211
+ const url = `${opts.apiBase}/api/graphics/formats/${encodeURIComponent(slug)}/spec.md`;
212
+ return fetchMarkdown(url, opts.apiKey, etag);
213
+ }
214
+ function inferContentType(absolutePath) {
215
+ const ext = path.extname(absolutePath).toLowerCase();
216
+ switch (ext) {
217
+ case '.png':
218
+ return 'image/png';
219
+ case '.jpg':
220
+ case '.jpeg':
221
+ return 'image/jpeg';
222
+ case '.webp':
223
+ return 'image/webp';
224
+ case '.gif':
225
+ return 'image/gif';
226
+ case '.svg':
227
+ return 'image/svg+xml';
228
+ default:
229
+ return 'application/octet-stream';
230
+ }
231
+ }
232
+ function buildMultipart(manifest, files) {
233
+ const fd = new FormData();
234
+ fd.append('manifest', JSON.stringify(manifest));
235
+ for (const f of files) {
236
+ const buf = fs.readFileSync(f.absolutePath);
237
+ // Node's Blob accepts a Uint8Array. We use the file's basename as the
238
+ // filename, but the field name carries the manifest reference (with "./"
239
+ // stripped) so the server can match it back to the manifest entry.
240
+ const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
241
+ // Without a `type`, Node's FormData serialises the part as
242
+ // `Content-Type: application/octet-stream`, which the server's image
243
+ // allowlist rejects with a 400.
244
+ const blob = new Blob([ab], { type: inferContentType(f.absolutePath) });
245
+ fd.append(f.fieldName, blob, path.basename(f.absolutePath));
246
+ }
247
+ return fd;
248
+ }
249
+ async function readWriteResponse(res) {
250
+ const body = (await readJsonSafe(res));
251
+ if (!body || body.status !== 'success' || !body.data?.slug || !body.data.id) {
252
+ throw new ApiError(res.status, null, 'unexpected write response shape', body);
253
+ }
254
+ return { slug: body.data.slug, id: body.data.id };
255
+ }
256
+ async function postMultipart(url, apiKey, manifest, files, method) {
257
+ const fd = buildMultipart(manifest, files);
258
+ const res = await safeFetch(url, {
259
+ method,
260
+ headers: authHeaders(apiKey),
261
+ body: fd,
262
+ });
263
+ if (!res.ok)
264
+ throw await asApiError(res, `${method} ${url} failed (${res.status})`);
265
+ return readWriteResponse(res);
266
+ }
267
+ async function publishStyle(opts, manifest, files) {
268
+ const url = `${opts.apiBase}/api/graphics/styles`;
269
+ return postMultipart(url, opts.apiKey, manifest, files, 'POST');
270
+ }
271
+ async function updateStyle(opts, slug, manifest, files) {
272
+ const url = `${opts.apiBase}/api/graphics/styles/${encodeURIComponent(slug)}`;
273
+ return postMultipart(url, opts.apiKey, manifest, files, 'PATCH');
274
+ }
275
+ async function deleteStyle(opts, slug) {
276
+ const url = `${opts.apiBase}/api/graphics/styles/${encodeURIComponent(slug)}`;
277
+ const res = await safeFetch(url, {
278
+ method: 'DELETE',
279
+ headers: authHeaders(opts.apiKey),
280
+ });
281
+ if (!res.ok)
282
+ throw await asApiError(res, `DELETE ${url} failed (${res.status})`);
283
+ }
284
+ async function publishFormat(opts, manifest, files) {
285
+ const url = `${opts.apiBase}/api/graphics/formats`;
286
+ return postMultipart(url, opts.apiKey, manifest, files, 'POST');
287
+ }
288
+ async function updateFormat(opts, slug, manifest, files) {
289
+ const url = `${opts.apiBase}/api/graphics/formats/${encodeURIComponent(slug)}`;
290
+ return postMultipart(url, opts.apiKey, manifest, files, 'PATCH');
291
+ }
292
+ async function deleteFormat(opts, slug) {
293
+ const url = `${opts.apiBase}/api/graphics/formats/${encodeURIComponent(slug)}`;
294
+ const res = await safeFetch(url, {
295
+ method: 'DELETE',
296
+ headers: authHeaders(opts.apiKey),
297
+ });
298
+ if (!res.ok)
299
+ throw await asApiError(res, `DELETE ${url} failed (${res.status})`);
300
+ }
301
+ // ─────────────────────────────────────────────────────────────────────────────
302
+ // Example PNG download (for `get --include-examples`)
303
+ async function downloadBytes(url) {
304
+ const res = await safeFetch(url, { method: 'GET' });
305
+ if (!res.ok)
306
+ throw await asApiError(res, `download failed (${res.status})`);
307
+ const ab = await res.arrayBuffer();
308
+ return Buffer.from(ab);
309
+ }
310
+ //# sourceMappingURL=graphics-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphics-api.js","sourceRoot":"","sources":["../../src/lib/graphics-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * ETag-keyed disk cache for the graphics design.md/spec.md endpoints.
3
+ *
4
+ * Layout:
5
+ * ~/.gooseworks/cache/graphics/styles/<slug>.md
6
+ * ~/.gooseworks/cache/graphics/styles/<slug>.md.etag
7
+ * ~/.gooseworks/cache/graphics/styles/<slug>.json
8
+ * ~/.gooseworks/cache/graphics/styles/<slug>.json.etag
9
+ * ~/.gooseworks/cache/graphics/formats/<slug>.md
10
+ * …
11
+ *
12
+ * Freshness is implicit (HTTP ETag handles it); there's no fixed TTL.
13
+ */
14
+ export type Resource = 'styles' | 'formats';
15
+ export type Variant = 'md' | 'json';
16
+ export interface CacheEntry {
17
+ body: string;
18
+ etag: string | null;
19
+ }
20
+ export declare function readCache(resource: Resource, slug: string, variant: Variant): CacheEntry | null;
21
+ /**
22
+ * Atomically writes the cache body and (optionally) etag. Each file is
23
+ * written via a PID-suffixed temp file then renamed, so a crash mid-write
24
+ * never leaves a torn body file readable. Concurrent writers can still
25
+ * race on body-vs-etag consistency, but that race is self-healing on the
26
+ * next fetch (mismatched etag → 200 with fresh body → both rewritten).
27
+ */
28
+ export declare function writeCache(resource: Resource, slug: string, variant: Variant, body: string, etag: string | null): void;
29
+ /** Test seam — exposes the resolved cache root for unit tests. */
30
+ export declare function getCacheRoot(): string;
31
+ //# sourceMappingURL=graphics-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphics-cache.d.ts","sourceRoot":"","sources":["../../src/lib/graphics-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC5C,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;AAsBpC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,UAAU,GAAG,IAAI,CAcnB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,IAAI,GAClB,IAAI,CAeN;AAQD,kEAAkE;AAClE,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * ETag-keyed disk cache for the graphics design.md/spec.md endpoints.
4
+ *
5
+ * Layout:
6
+ * ~/.gooseworks/cache/graphics/styles/<slug>.md
7
+ * ~/.gooseworks/cache/graphics/styles/<slug>.md.etag
8
+ * ~/.gooseworks/cache/graphics/styles/<slug>.json
9
+ * ~/.gooseworks/cache/graphics/styles/<slug>.json.etag
10
+ * ~/.gooseworks/cache/graphics/formats/<slug>.md
11
+ * …
12
+ *
13
+ * Freshness is implicit (HTTP ETag handles it); there's no fixed TTL.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.readCache = readCache;
50
+ exports.writeCache = writeCache;
51
+ exports.getCacheRoot = getCacheRoot;
52
+ const fs = __importStar(require("fs"));
53
+ const path = __importStar(require("path"));
54
+ const os = __importStar(require("os"));
55
+ const graphics_manifest_1 = require("./graphics-manifest");
56
+ function getCacheRootInternal() {
57
+ return (process.env.GOOSEWORKS_GRAPHICS_CACHE_DIR ||
58
+ path.join(os.homedir(), '.gooseworks', 'cache', 'graphics'));
59
+ }
60
+ /**
61
+ * Returns the cache file path for a slug, or null if the slug fails the
62
+ * public grammar. Returning null instead of throwing means a malformed user
63
+ * arg falls through to the network layer (which will reject it with a
64
+ * normal 404), rather than crashing the CLI before any request is made.
65
+ * The check also blocks path traversal via slugs sourced from server JSON.
66
+ */
67
+ function pathFor(resource, slug, variant) {
68
+ if (!graphics_manifest_1.SLUG_RE.test(slug))
69
+ return null;
70
+ const ext = variant === 'md' ? '.md' : '.json';
71
+ return path.join(getCacheRootInternal(), resource, `${slug}${ext}`);
72
+ }
73
+ function readCache(resource, slug, variant) {
74
+ const bodyPath = pathFor(resource, slug, variant);
75
+ if (!bodyPath)
76
+ return null;
77
+ if (!fs.existsSync(bodyPath))
78
+ return null;
79
+ try {
80
+ const body = fs.readFileSync(bodyPath, 'utf-8');
81
+ const etagPath = `${bodyPath}.etag`;
82
+ const etag = fs.existsSync(etagPath)
83
+ ? fs.readFileSync(etagPath, 'utf-8').trim() || null
84
+ : null;
85
+ return { body, etag };
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
91
+ /**
92
+ * Atomically writes the cache body and (optionally) etag. Each file is
93
+ * written via a PID-suffixed temp file then renamed, so a crash mid-write
94
+ * never leaves a torn body file readable. Concurrent writers can still
95
+ * race on body-vs-etag consistency, but that race is self-healing on the
96
+ * next fetch (mismatched etag → 200 with fresh body → both rewritten).
97
+ */
98
+ function writeCache(resource, slug, variant, body, etag) {
99
+ const bodyPath = pathFor(resource, slug, variant);
100
+ if (!bodyPath)
101
+ return;
102
+ fs.mkdirSync(path.dirname(bodyPath), { recursive: true });
103
+ atomicWrite(bodyPath, body);
104
+ const etagPath = `${bodyPath}.etag`;
105
+ if (etag) {
106
+ atomicWrite(etagPath, etag);
107
+ }
108
+ else if (fs.existsSync(etagPath)) {
109
+ try {
110
+ fs.unlinkSync(etagPath);
111
+ }
112
+ catch {
113
+ // best effort
114
+ }
115
+ }
116
+ }
117
+ function atomicWrite(target, contents) {
118
+ const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
119
+ fs.writeFileSync(tmp, contents, 'utf-8');
120
+ fs.renameSync(tmp, target);
121
+ }
122
+ /** Test seam — exposes the resolved cache root for unit tests. */
123
+ function getCacheRoot() {
124
+ return getCacheRootInternal();
125
+ }
126
+ //# sourceMappingURL=graphics-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphics-cache.js","sourceRoot":"","sources":["../../src/lib/graphics-cache.ts"],"names":[],"mappings":"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"}