sintetica-cli 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.
@@ -19,18 +19,31 @@ const listCommand = new commander_1.Command('list')
19
19
  }
20
20
  });
21
21
  const createCommand = new commander_1.Command('create')
22
- .description('Create a product from an image URL')
22
+ .description('Create a product from a local image or URL')
23
23
  .requiredOption('--name <name>', 'Product name')
24
- .requiredOption('--image-url <url>', 'URL to product image')
24
+ .option('--image <path>', 'Path to local product image')
25
+ .option('--image-url <url>', 'URL to product image')
25
26
  .option('--description <desc>', 'Product description')
26
27
  .option('--category <cat>', 'Category (beauty, wellness, pharma, apparel, etc.)')
27
28
  .option('--brand-name <brand>', 'Brand name')
28
29
  .action(async (opts) => {
30
+ if (!opts.image && !opts.imageUrl) {
31
+ console.error(JSON.stringify({ error: 'Provide either --image (local file) or --image-url (URL)' }));
32
+ process.exit(1);
33
+ }
29
34
  try {
35
+ let imageUrl = opts.imageUrl;
36
+ // Upload local file first if provided
37
+ if (opts.image) {
38
+ process.stderr.write(' Uploading image...\n');
39
+ const upload = await (0, api_js_1.uploadFile)(opts.image);
40
+ imageUrl = upload.url;
41
+ process.stderr.write(` Uploaded (${(upload.size / 1024).toFixed(0)}KB)\n`);
42
+ }
30
43
  const data = await (0, api_js_1.api)('/api/cli/products', {
31
44
  body: {
32
45
  name: opts.name,
33
- imageUrl: opts.imageUrl,
46
+ imageUrl,
34
47
  description: opts.description,
35
48
  category: opts.category,
36
49
  brandName: opts.brandName,
package/dist/lib/api.d.ts CHANGED
@@ -14,4 +14,12 @@ export declare function downloadBinary(path: string, body?: Record<string, unkno
14
14
  buffer: Buffer;
15
15
  fileName: string;
16
16
  }>;
17
+ /**
18
+ * Upload a local file to the server. Returns the CDN URL.
19
+ */
20
+ export declare function uploadFile(filePath: string): Promise<{
21
+ url: string;
22
+ fileName: string;
23
+ size: number;
24
+ }>;
17
25
  export {};
package/dist/lib/api.js CHANGED
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.api = api;
4
4
  exports.downloadBinary = downloadBinary;
5
+ exports.uploadFile = uploadFile;
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
5
8
  const config_js_1 = require("./config.js");
6
9
  /**
7
10
  * Make an authenticated API call to the Sintetica server.
@@ -53,3 +56,26 @@ async function downloadBinary(path, body) {
53
56
  const buffer = Buffer.from(await res.arrayBuffer());
54
57
  return { buffer, fileName };
55
58
  }
59
+ /**
60
+ * Upload a local file to the server. Returns the CDN URL.
61
+ */
62
+ async function uploadFile(filePath) {
63
+ const baseUrl = (0, config_js_1.getBaseUrl)();
64
+ const apiKey = (0, config_js_1.getApiKey)();
65
+ const fileBuffer = (0, fs_1.readFileSync)(filePath);
66
+ const fileName = (0, path_1.basename)(filePath);
67
+ const formData = new FormData();
68
+ formData.append('file', new Blob([fileBuffer]), fileName);
69
+ const res = await fetch(`${baseUrl}/api/cli/upload`, {
70
+ method: 'POST',
71
+ headers: {
72
+ 'Authorization': `Bearer ${apiKey}`,
73
+ },
74
+ body: formData,
75
+ });
76
+ if (!res.ok) {
77
+ const errorBody = await res.json().catch(() => ({ error: res.statusText }));
78
+ throw new Error(errorBody.error || `HTTP ${res.status}`);
79
+ }
80
+ return res.json();
81
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sintetica-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Sintetica CLI — AI product photography from your terminal. Generate professional product photos with one command.",
5
5
  "keywords": ["sintetica", "ai", "product-photography", "ecommerce", "shopify", "cli", "claude-code"],
6
6
  "author": "Sintetica <hello@sintetica.ro>",