@neopress/cli 0.1.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.js ADDED
@@ -0,0 +1,681 @@
1
+ // ../sdk/dist/errors.js
2
+ var NeopressApiError = class extends Error {
3
+ code;
4
+ status;
5
+ response;
6
+ constructor(code, message, status, response) {
7
+ super(message);
8
+ this.code = code;
9
+ this.status = status;
10
+ this.response = response;
11
+ this.name = "NeopressApiError";
12
+ }
13
+ };
14
+
15
+ // ../sdk/dist/endpoints/pages.js
16
+ var PagesEndpoint = class {
17
+ client;
18
+ constructor(client) {
19
+ this.client = client;
20
+ }
21
+ get basePath() {
22
+ return `${this.client.siteBasePath}/pages`;
23
+ }
24
+ async list(params) {
25
+ const qs = new URLSearchParams();
26
+ if (params?.page)
27
+ qs.set("page", String(params.page));
28
+ if (params?.limit)
29
+ qs.set("limit", String(params.limit));
30
+ if (params?.status)
31
+ qs.set("status", params.status);
32
+ if (params?.fields)
33
+ qs.set("fields", params.fields.join(","));
34
+ const query = qs.toString();
35
+ return this.client.getList(`${this.basePath}${query ? `?${query}` : ""}`);
36
+ }
37
+ async get(pageId) {
38
+ const res = await this.client.get(`${this.basePath}/${pageId}`);
39
+ return res.data;
40
+ }
41
+ async create(data) {
42
+ const res = await this.client.post(this.basePath, data);
43
+ return res.data;
44
+ }
45
+ async update(pageId, data) {
46
+ const res = await this.client.patch(`${this.basePath}/${pageId}`, data);
47
+ return res.data;
48
+ }
49
+ async delete(pageId) {
50
+ await this.client.delete(`${this.basePath}/${pageId}`);
51
+ }
52
+ async compile(pageId) {
53
+ const res = await this.client.post(`${this.basePath}/${pageId}/compile`);
54
+ return res.data;
55
+ }
56
+ };
57
+
58
+ // ../sdk/dist/endpoints/collections.js
59
+ var CollectionsEndpoint = class {
60
+ client;
61
+ constructor(client) {
62
+ this.client = client;
63
+ }
64
+ get basePath() {
65
+ return `${this.client.siteBasePath}/collections`;
66
+ }
67
+ async list() {
68
+ const res = await this.client.get(this.basePath);
69
+ return res.data;
70
+ }
71
+ async get(collectionId) {
72
+ const res = await this.client.get(`${this.basePath}/${collectionId}`);
73
+ return res.data;
74
+ }
75
+ async create(data) {
76
+ const res = await this.client.post(this.basePath, data);
77
+ return res.data;
78
+ }
79
+ async update(collectionId, data) {
80
+ const res = await this.client.patch(`${this.basePath}/${collectionId}`, data);
81
+ return res.data;
82
+ }
83
+ async delete(collectionId) {
84
+ await this.client.delete(`${this.basePath}/${collectionId}`);
85
+ }
86
+ async getSchema(collectionId) {
87
+ const res = await this.client.get(`${this.basePath}/${collectionId}/schema`);
88
+ return res.data;
89
+ }
90
+ async updateSchema(collectionId, schema) {
91
+ const res = await this.client.patch(`${this.basePath}/${collectionId}/schema`, { schema });
92
+ return res.data;
93
+ }
94
+ };
95
+
96
+ // ../sdk/dist/endpoints/entries.js
97
+ var EntriesEndpoint = class {
98
+ client;
99
+ constructor(client) {
100
+ this.client = client;
101
+ }
102
+ async list(collectionId, params) {
103
+ const qs = new URLSearchParams();
104
+ if (params?.page)
105
+ qs.set("page", String(params.page));
106
+ if (params?.limit)
107
+ qs.set("limit", String(params.limit));
108
+ if (params?.status)
109
+ qs.set("status", params.status);
110
+ if (params?.locale)
111
+ qs.set("locale", params.locale);
112
+ const query = qs.toString();
113
+ return this.client.getList(`${this.client.siteBasePath}/collections/${collectionId}/entries${query ? `?${query}` : ""}`);
114
+ }
115
+ async get(entryId) {
116
+ const res = await this.client.get(`${this.client.siteBasePath}/entries/${entryId}`);
117
+ return res.data;
118
+ }
119
+ async create(collectionId, data) {
120
+ const res = await this.client.post(`${this.client.siteBasePath}/collections/${collectionId}/entries`, data);
121
+ return res.data;
122
+ }
123
+ async update(entryId, data) {
124
+ const res = await this.client.patch(`${this.client.siteBasePath}/entries/${entryId}`, data);
125
+ return res.data;
126
+ }
127
+ async delete(entryId) {
128
+ await this.client.delete(`${this.client.siteBasePath}/entries/${entryId}`);
129
+ }
130
+ async publish(entryId) {
131
+ const res = await this.client.post(`${this.client.siteBasePath}/entries/${entryId}/publish`);
132
+ return res.data;
133
+ }
134
+ async unpublish(entryId) {
135
+ const res = await this.client.post(`${this.client.siteBasePath}/entries/${entryId}/unpublish`);
136
+ return res.data;
137
+ }
138
+ async listVersions(entryId) {
139
+ const res = await this.client.get(`${this.client.siteBasePath}/entries/${entryId}/versions`);
140
+ return res.data;
141
+ }
142
+ async pinVersion(entryId, versionId) {
143
+ const res = await this.client.post(`${this.client.siteBasePath}/entries/${entryId}/versions/${versionId}/pin`);
144
+ return res.data;
145
+ }
146
+ };
147
+
148
+ // ../sdk/dist/endpoints/forms.js
149
+ var FormsEndpoint = class {
150
+ client;
151
+ constructor(client) {
152
+ this.client = client;
153
+ }
154
+ get basePath() {
155
+ return `${this.client.siteBasePath}/forms`;
156
+ }
157
+ async list() {
158
+ const res = await this.client.get(this.basePath);
159
+ return res.data;
160
+ }
161
+ async get(formId) {
162
+ const res = await this.client.get(`${this.basePath}/${formId}`);
163
+ return res.data;
164
+ }
165
+ async create(data) {
166
+ const res = await this.client.post(this.basePath, data);
167
+ return res.data;
168
+ }
169
+ async update(formId, data) {
170
+ const res = await this.client.patch(`${this.basePath}/${formId}`, data);
171
+ return res.data;
172
+ }
173
+ async delete(formId) {
174
+ await this.client.delete(`${this.basePath}/${formId}`);
175
+ }
176
+ async publish(formId) {
177
+ const res = await this.client.post(`${this.basePath}/${formId}/publish`);
178
+ return res.data;
179
+ }
180
+ async listResponses(formId, params) {
181
+ const qs = new URLSearchParams();
182
+ if (params?.page)
183
+ qs.set("page", String(params.page));
184
+ if (params?.limit)
185
+ qs.set("limit", String(params.limit));
186
+ const query = qs.toString();
187
+ return this.client.getList(`${this.basePath}/${formId}/responses${query ? `?${query}` : ""}`);
188
+ }
189
+ async deleteResponse(formId, responseId) {
190
+ await this.client.delete(`${this.basePath}/${formId}/responses/${responseId}`);
191
+ }
192
+ };
193
+
194
+ // ../sdk/dist/endpoints/assets.js
195
+ var AssetsEndpoint = class {
196
+ client;
197
+ constructor(client) {
198
+ this.client = client;
199
+ }
200
+ get basePath() {
201
+ return `${this.client.siteBasePath}/assets`;
202
+ }
203
+ async list(params) {
204
+ const qs = new URLSearchParams();
205
+ if (params?.page)
206
+ qs.set("page", String(params.page));
207
+ if (params?.limit)
208
+ qs.set("limit", String(params.limit));
209
+ const query = qs.toString();
210
+ return this.client.getList(`${this.basePath}${query ? `?${query}` : ""}`);
211
+ }
212
+ async get(assetId) {
213
+ const res = await this.client.get(`${this.basePath}/${assetId}`);
214
+ return res.data;
215
+ }
216
+ async register(data) {
217
+ const res = await this.client.post(this.basePath, data);
218
+ return res.data;
219
+ }
220
+ async update(assetId, data) {
221
+ const res = await this.client.patch(`${this.basePath}/${assetId}`, data);
222
+ return res.data;
223
+ }
224
+ async delete(assetId) {
225
+ await this.client.delete(`${this.basePath}/${assetId}`);
226
+ }
227
+ async presign(data) {
228
+ const res = await this.client.post(`${this.basePath}/presign`, data);
229
+ return res.data;
230
+ }
231
+ };
232
+
233
+ // ../sdk/dist/endpoints/site.js
234
+ var SiteEndpoint = class {
235
+ client;
236
+ constructor(client) {
237
+ this.client = client;
238
+ }
239
+ async list() {
240
+ const res = await this.client.get("/api/v1/sites");
241
+ return res.data;
242
+ }
243
+ async get() {
244
+ const res = await this.client.get(this.client.siteBasePath);
245
+ return res.data;
246
+ }
247
+ async create(data) {
248
+ const res = await this.client.post("/api/v1/sites", data);
249
+ return res.data;
250
+ }
251
+ async update(data) {
252
+ const res = await this.client.patch(this.client.siteBasePath, data);
253
+ return res.data;
254
+ }
255
+ async getLayout() {
256
+ const res = await this.client.get(`${this.client.siteBasePath}/layout`);
257
+ return res.data;
258
+ }
259
+ async updateLayout(data) {
260
+ const res = await this.client.patch(`${this.client.siteBasePath}/layout`, data);
261
+ return res.data;
262
+ }
263
+ };
264
+
265
+ // ../sdk/dist/endpoints/redirects.js
266
+ var RedirectsEndpoint = class {
267
+ client;
268
+ constructor(client) {
269
+ this.client = client;
270
+ }
271
+ get basePath() {
272
+ return `${this.client.siteBasePath}/redirects`;
273
+ }
274
+ async list() {
275
+ const res = await this.client.get(this.basePath);
276
+ return res.data;
277
+ }
278
+ async create(data) {
279
+ const res = await this.client.post(this.basePath, data);
280
+ return res.data;
281
+ }
282
+ async update(ruleId, data) {
283
+ const res = await this.client.patch(`${this.basePath}/${ruleId}`, data);
284
+ return res.data;
285
+ }
286
+ async delete(ruleId) {
287
+ await this.client.delete(`${this.basePath}/${ruleId}`);
288
+ }
289
+ };
290
+
291
+ // ../sdk/dist/endpoints/publish.js
292
+ var PublishEndpoint = class {
293
+ client;
294
+ constructor(client) {
295
+ this.client = client;
296
+ }
297
+ async preview() {
298
+ const res = await this.client.get(`${this.client.siteBasePath}/publish`);
299
+ return res.data;
300
+ }
301
+ async site() {
302
+ const res = await this.client.post(`${this.client.siteBasePath}/publish`);
303
+ return res.data;
304
+ }
305
+ };
306
+
307
+ // ../sdk/dist/endpoints/entry-references.js
308
+ var EntryReferencesEndpoint = class {
309
+ client;
310
+ constructor(client) {
311
+ this.client = client;
312
+ }
313
+ get basePath() {
314
+ return `${this.client.siteBasePath}/entry-references`;
315
+ }
316
+ async list(params) {
317
+ const qs = new URLSearchParams();
318
+ if (params?.fromEntryId)
319
+ qs.set("fromEntryId", String(params.fromEntryId));
320
+ if (params?.toEntryId)
321
+ qs.set("toEntryId", String(params.toEntryId));
322
+ const query = qs.toString();
323
+ const res = await this.client.get(`${this.basePath}${query ? `?${query}` : ""}`);
324
+ return res.data;
325
+ }
326
+ async create(data) {
327
+ const res = await this.client.post(this.basePath, data);
328
+ return res.data;
329
+ }
330
+ async delete(referenceId) {
331
+ await this.client.delete(`${this.basePath}/${referenceId}`);
332
+ }
333
+ };
334
+
335
+ // ../sdk/dist/endpoints/analytics.js
336
+ var RESERVED_ANALYTICS_PARAMS = /* @__PURE__ */ new Set([
337
+ "pipe",
338
+ "site",
339
+ "site_id",
340
+ "timezone",
341
+ "token",
342
+ "q"
343
+ ]);
344
+ function setQueryValue(qs, key, value) {
345
+ if (value === void 0)
346
+ return;
347
+ qs.set(key, String(value));
348
+ }
349
+ function appendCommonAnalyticsParams(qs, params) {
350
+ setQueryValue(qs, "date_from", params?.dateFrom);
351
+ setQueryValue(qs, "date_to", params?.dateTo);
352
+ setQueryValue(qs, "timezone", params?.timezone);
353
+ setQueryValue(qs, "limit", params?.limit);
354
+ for (const [key, value] of Object.entries(params?.params ?? {})) {
355
+ if (RESERVED_ANALYTICS_PARAMS.has(key))
356
+ continue;
357
+ setQueryValue(qs, key, value);
358
+ }
359
+ }
360
+ var AnalyticsEndpoint = class {
361
+ client;
362
+ constructor(client) {
363
+ this.client = client;
364
+ }
365
+ get basePath() {
366
+ return `${this.client.siteBasePath}/analytics`;
367
+ }
368
+ async query(params) {
369
+ const qs = new URLSearchParams();
370
+ qs.set("pipe", params.pipe);
371
+ appendCommonAnalyticsParams(qs, params);
372
+ const res = await this.client.get(`${this.basePath}/query?${qs.toString()}`);
373
+ return res.data;
374
+ }
375
+ async pageviews(params) {
376
+ return this.query({ pipe: "get_pageviews", ...params });
377
+ }
378
+ async summary(params) {
379
+ return this.query({ pipe: "get_engagement_summary", ...params });
380
+ }
381
+ async topPages(params) {
382
+ return this.query({ pipe: "get_top_pages", ...params });
383
+ }
384
+ async trafficSources(params) {
385
+ return this.query({ pipe: "get_traffic_sources", ...params });
386
+ }
387
+ async formAnalytics(params) {
388
+ return this.query({ pipe: "get_form_analytics", ...params });
389
+ }
390
+ async crawlerSummary(params) {
391
+ return this.query({ pipe: "get_crawler_summary", ...params });
392
+ }
393
+ async searchConsole(params) {
394
+ const qs = new URLSearchParams();
395
+ qs.set("date_from", params.dateFrom);
396
+ qs.set("date_to", params.dateTo);
397
+ if (params.dimensions)
398
+ qs.set("dimensions", params.dimensions.join(","));
399
+ if (params.queryFilter)
400
+ qs.set("query_filter", params.queryFilter);
401
+ if (params.pageFilter)
402
+ qs.set("page_filter", params.pageFilter);
403
+ if (params.rowLimit)
404
+ qs.set("row_limit", String(params.rowLimit));
405
+ const res = await this.client.get(`${this.basePath}/search-console?${qs.toString()}`);
406
+ return res.data;
407
+ }
408
+ };
409
+
410
+ // ../sdk/dist/client.js
411
+ var NeopressClient = class {
412
+ baseUrl;
413
+ accessToken;
414
+ siteId;
415
+ timeout;
416
+ pages;
417
+ collections;
418
+ entries;
419
+ forms;
420
+ assets;
421
+ site;
422
+ redirects;
423
+ publish;
424
+ entryReferences;
425
+ analytics;
426
+ constructor(options) {
427
+ this.baseUrl = (options.baseUrl || "https://app.neopress.ai").replace(/\/$/, "");
428
+ this.accessToken = options.accessToken || "";
429
+ this.siteId = options.siteId;
430
+ this.timeout = options.timeout ?? 3e4;
431
+ this.pages = new PagesEndpoint(this);
432
+ this.collections = new CollectionsEndpoint(this);
433
+ this.entries = new EntriesEndpoint(this);
434
+ this.forms = new FormsEndpoint(this);
435
+ this.assets = new AssetsEndpoint(this);
436
+ this.site = new SiteEndpoint(this);
437
+ this.redirects = new RedirectsEndpoint(this);
438
+ this.publish = new PublishEndpoint(this);
439
+ this.entryReferences = new EntryReferencesEndpoint(this);
440
+ this.analytics = new AnalyticsEndpoint(this);
441
+ }
442
+ get siteBasePath() {
443
+ return `/api/v1/sites/${this.siteId}`;
444
+ }
445
+ async request(method, path, body) {
446
+ const url = `${this.baseUrl}${path}`;
447
+ const headers = {
448
+ "Authorization": `Bearer ${this.accessToken}`
449
+ };
450
+ if (body !== void 0) {
451
+ headers["Content-Type"] = "application/json";
452
+ }
453
+ const controller = new AbortController();
454
+ const timeout = setTimeout(() => controller.abort(), this.timeout);
455
+ let response;
456
+ try {
457
+ response = await fetch(url, {
458
+ method,
459
+ headers,
460
+ body: body ? JSON.stringify(body) : void 0,
461
+ signal: controller.signal
462
+ });
463
+ } catch (err) {
464
+ clearTimeout(timeout);
465
+ if (err?.name === "AbortError") {
466
+ throw new NeopressApiError("TIMEOUT", `Request timed out: ${method} ${path}`, 0);
467
+ }
468
+ throw new NeopressApiError("CONNECTION_ERROR", `Cannot connect to ${this.baseUrl} \u2014 is the dev server running?`, 0);
469
+ }
470
+ clearTimeout(timeout);
471
+ const json = await response.json();
472
+ if (!response.ok) {
473
+ const err = json?.error || {};
474
+ throw new NeopressApiError(err.code || "UNKNOWN", err.message || response.statusText, response.status, json);
475
+ }
476
+ return json;
477
+ }
478
+ async get(path) {
479
+ return this.request("GET", path);
480
+ }
481
+ async getList(path) {
482
+ return this.request("GET", path);
483
+ }
484
+ async post(path, body) {
485
+ return this.request("POST", path, body);
486
+ }
487
+ async patch(path, body) {
488
+ return this.request("PATCH", path, body);
489
+ }
490
+ async delete(path) {
491
+ return this.request("DELETE", path);
492
+ }
493
+ };
494
+
495
+ // src/utils/token-store.ts
496
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from "fs";
497
+ import { homedir } from "os";
498
+ import { join } from "path";
499
+ var CONFIG_DIR = join(homedir(), ".config", "neopress");
500
+ var TOKENS_FILE = join(CONFIG_DIR, "tokens.json");
501
+ function ensureConfigDir() {
502
+ if (!existsSync(CONFIG_DIR)) {
503
+ mkdirSync(CONFIG_DIR, { recursive: true });
504
+ }
505
+ }
506
+ function loadSession() {
507
+ try {
508
+ return JSON.parse(readFileSync(TOKENS_FILE, "utf-8"));
509
+ } catch {
510
+ return {};
511
+ }
512
+ }
513
+ function saveSession(session) {
514
+ ensureConfigDir();
515
+ writeFileSync(TOKENS_FILE, JSON.stringify(session, null, 2) + "\n");
516
+ try {
517
+ chmodSync(TOKENS_FILE, 384);
518
+ } catch {
519
+ }
520
+ }
521
+ function clearSession() {
522
+ saveSession({});
523
+ }
524
+
525
+ // src/utils/supabase-config.ts
526
+ function getSupabaseConfig() {
527
+ return {
528
+ url: process.env.NEOPRESS_SUPABASE_URL || "https://gxrfyjmsmiakirmtzkmv.supabase.co",
529
+ anonKey: process.env.NEOPRESS_SUPABASE_ANON_KEY || "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imd4cmZ5am1zbWlha2lybXR6a212Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjIxNDM2MzQsImV4cCI6MjA3NzcxOTYzNH0.Xzx6Xg5O1EBXZ64_5BP7KhsVyafJ0GI-62HcDpq6WRk"
530
+ };
531
+ }
532
+
533
+ // src/utils/token-refresh.ts
534
+ var REFRESH_BUFFER_SECONDS = 60;
535
+ async function refreshAccessToken(refreshToken) {
536
+ const { url, anonKey } = getSupabaseConfig();
537
+ const response = await fetch(`${url}/auth/v1/token?grant_type=refresh_token`, {
538
+ method: "POST",
539
+ headers: {
540
+ "Content-Type": "application/json",
541
+ "apikey": anonKey
542
+ },
543
+ body: JSON.stringify({
544
+ refresh_token: refreshToken
545
+ })
546
+ });
547
+ if (!response.ok) {
548
+ const err = await response.text();
549
+ throw new Error(`Token refresh failed: ${err}`);
550
+ }
551
+ const data = await response.json();
552
+ return {
553
+ accessToken: data.access_token,
554
+ refreshToken: data.refresh_token,
555
+ expiresAt: Math.floor(Date.now() / 1e3) + data.expires_in,
556
+ userId: data.user?.id || ""
557
+ };
558
+ }
559
+ async function getValidAccessToken() {
560
+ const session = loadSession();
561
+ if (!session.tokens) return null;
562
+ const now = Math.floor(Date.now() / 1e3);
563
+ if (session.tokens.expiresAt > now + REFRESH_BUFFER_SECONDS) {
564
+ return session.tokens.accessToken;
565
+ }
566
+ try {
567
+ const newTokens = await refreshAccessToken(session.tokens.refreshToken);
568
+ saveSession({ ...session, tokens: newTokens });
569
+ return newTokens.accessToken;
570
+ } catch {
571
+ return null;
572
+ }
573
+ }
574
+
575
+ // src/utils/output.ts
576
+ var jsonMode = false;
577
+ function fail(message, code = 1) {
578
+ if (jsonMode) {
579
+ console.error(JSON.stringify({ ok: false, error: message }));
580
+ } else {
581
+ console.error(`Error: ${message}`);
582
+ }
583
+ process.exit(code);
584
+ }
585
+
586
+ // src/utils/config.ts
587
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
588
+ import { dirname } from "path";
589
+ var PROJECT_CONFIG = ".neopressrc.json";
590
+ var WORKSPACE_CONFIG = ".neopress/config.json";
591
+ function readProjectConfig() {
592
+ let config = {};
593
+ for (const file of [PROJECT_CONFIG, WORKSPACE_CONFIG]) {
594
+ try {
595
+ const parsed = JSON.parse(readFileSync2(file, "utf-8"));
596
+ config = {
597
+ ...config,
598
+ ...typeof parsed.siteId === "number" ? { siteId: parsed.siteId } : {},
599
+ ...typeof parsed.baseUrl === "string" ? { baseUrl: parsed.baseUrl } : {}
600
+ };
601
+ } catch {
602
+ }
603
+ }
604
+ return config;
605
+ }
606
+ function writeWorkspaceConfig(next) {
607
+ mkdirSync2(dirname(WORKSPACE_CONFIG), { recursive: true });
608
+ writeFileSync2(WORKSPACE_CONFIG, JSON.stringify(next, null, 2) + "\n", "utf-8");
609
+ }
610
+ function getAccessToken() {
611
+ return process.env.NEOPRESS_ACCESS_TOKEN || loadSession().tokens?.accessToken;
612
+ }
613
+ function getSiteId() {
614
+ const envSiteId = process.env.NEOPRESS_SITE_ID;
615
+ if (envSiteId) return parseInt(envSiteId, 10);
616
+ const projectConfig = readProjectConfig();
617
+ if (projectConfig.siteId) return projectConfig.siteId;
618
+ return loadSession().activeSiteId;
619
+ }
620
+ function getBaseUrl() {
621
+ return process.env.NEOPRESS_BASE_URL || readProjectConfig().baseUrl || "https://app.neopress.ai";
622
+ }
623
+ function setActiveSiteId(siteId) {
624
+ const session = loadSession();
625
+ saveSession({ ...session, activeSiteId: siteId });
626
+ if (existsSync2(".neopress") || existsSync2(WORKSPACE_CONFIG)) {
627
+ writeWorkspaceConfig({ ...readProjectConfig(), siteId });
628
+ }
629
+ }
630
+
631
+ // src/utils/client.ts
632
+ function getClient(siteIdOverride) {
633
+ const session = loadSession();
634
+ const accessToken = process.env.NEOPRESS_ACCESS_TOKEN || session.tokens?.accessToken;
635
+ const siteId = siteIdOverride ?? getSiteId();
636
+ if (!siteId) {
637
+ fail("No site selected. Run `neopress sites use <siteId>` or set NEOPRESS_SITE_ID.");
638
+ }
639
+ if (accessToken) {
640
+ return new NeopressClient({
641
+ accessToken,
642
+ siteId,
643
+ baseUrl: getBaseUrl()
644
+ });
645
+ }
646
+ fail("Not authenticated. Run `neopress login` or set NEOPRESS_ACCESS_TOKEN.");
647
+ }
648
+ async function getClientAsync(siteIdOverride) {
649
+ const siteId = siteIdOverride ?? getSiteId();
650
+ if (!siteId) {
651
+ fail("No site selected. Run `neopress sites use <siteId>` or set NEOPRESS_SITE_ID.");
652
+ }
653
+ if (process.env.NEOPRESS_ACCESS_TOKEN) {
654
+ return new NeopressClient({
655
+ accessToken: process.env.NEOPRESS_ACCESS_TOKEN,
656
+ siteId,
657
+ baseUrl: getBaseUrl()
658
+ });
659
+ }
660
+ const accessToken = await getValidAccessToken();
661
+ if (!accessToken) {
662
+ fail("Session expired. Run `neopress login` again.");
663
+ }
664
+ return new NeopressClient({
665
+ accessToken,
666
+ siteId,
667
+ baseUrl: getBaseUrl()
668
+ });
669
+ }
670
+ export {
671
+ clearSession,
672
+ getAccessToken,
673
+ getBaseUrl,
674
+ getClient,
675
+ getClientAsync,
676
+ getSiteId,
677
+ getValidAccessToken,
678
+ loadSession,
679
+ saveSession,
680
+ setActiveSiteId
681
+ };
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@neopress/cli",
3
+ "version": "0.1.0",
4
+ "description": "Neopress CLI — manage your Neopress site from the terminal",
5
+ "type": "module",
6
+ "bin": {
7
+ "neopress": "./dist/bin.cjs"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^22.0.0",
19
+ "commander": "^13.0.0",
20
+ "tsup": "^8.5.1",
21
+ "typescript": "^5.7.0",
22
+ "@neopress/sdk": "0.1.0"
23
+ },
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "dev": "tsup --watch",
27
+ "lint": "tsc --noEmit"
28
+ }
29
+ }