@usesocial/cli 0.12.0 → 0.12.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @usesocial/cli
2
2
 
3
+ ## 0.12.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#73](https://github.com/usesocial/monorepo/pull/73) [`666b356`](https://github.com/usesocial/monorepo/commit/666b356706c40b7a3dc5e14ec53d76428b25f5c4) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Stop double-wrapping X list mutation output under nested data objects.
8
+
9
+ - [#73](https://github.com/usesocial/monorepo/pull/73) [`1cfedc9`](https://github.com/usesocial/monorepo/commit/1cfedc967b3fa82249bbca059856cc641c87868e) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Detect Bun-installed social CLI when printing update commands.
10
+
11
+ ## 0.12.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [#72](https://github.com/usesocial/monorepo/pull/72) [`affa4d3`](https://github.com/usesocial/monorepo/commit/affa4d30c27cdad8512893065ebd2df080b79aca) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Fix X list OAuth scopes and list read field presets.
16
+
3
17
  ## 0.12.0
4
18
 
5
19
  ### Minor Changes
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from "node:module";
3
3
  import * as fs from "node:fs";
4
4
  import { createReadStream, existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
5
- import { basename, dirname, extname, join, resolve } from "node:path";
5
+ import { basename, delimiter, dirname, extname, join, resolve } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { homedir } from "node:os";
8
8
  import { parseArgs, styleText } from "node:util";
@@ -21098,9 +21098,9 @@ const buildDelete = (deps) => {
21098
21098
  });
21099
21099
  };
21100
21100
  const listFields = "created_at,description,follower_count,id,member_count,name,owner_id,private";
21101
- const listUserFields = "affiliation,confirmed_email,connection_status,created_at,description,entities,id,is_identity_verified,location,most_recent_tweet_id,name,parody,pinned_tweet_id,profile_banner_url,profile_image_url,protected,public_metrics,receives_your_dm,subscription,subscription_type,url,username,verified,verified_followers_count,verified_type,withheld";
21101
+ const listUserFields = "affiliation,created_at,description,entities,id,is_identity_verified,location,most_recent_tweet_id,name,parody,pinned_tweet_id,profile_banner_url,profile_image_url,protected,public_metrics,subscription,subscription_type,url,username,verified,verified_followers_count,verified_type,withheld";
21102
21102
  const listMemberExpansions = "affiliation.user_id,most_recent_tweet_id,pinned_tweet_id";
21103
- const listMemberTweetFields = "article,attachments,author_id,card_uri,community_id,context_annotations,conversation_id,created_at,display_text_range,edit_controls,edit_history_tweet_ids,entities,geo,id,in_reply_to_user_id,lang,matched_media_notes,media_metadata,non_public_metrics,note_request_suggestions,note_tweet,organic_metrics,paid_partnership,possibly_sensitive,promoted_metrics,public_metrics,referenced_tweets,reply_settings,scopes,source,suggested_source_links,suggested_source_links_with_counts,text,withheld";
21103
+ const listMemberTweetFields = "article,attachments,author_id,card_uri,community_id,context_annotations,conversation_id,created_at,display_text_range,edit_controls,edit_history_tweet_ids,entities,geo,id,in_reply_to_user_id,lang,matched_media_notes,media_metadata,note_request_suggestions,note_tweet,paid_partnership,possibly_sensitive,public_metrics,referenced_tweets,reply_settings,scopes,source,suggested_source_links,suggested_source_links_with_counts,text,withheld";
21104
21104
  const listReadParams = () => {
21105
21105
  const params = new URLSearchParams();
21106
21106
  params.set("list.fields", listFields);
@@ -21189,14 +21189,23 @@ const listOutputSchema = object({
21189
21189
  includes: record(string(), unknown()).optional(),
21190
21190
  meta: record(string(), unknown()).optional()
21191
21191
  }).passthrough();
21192
- const listWriteAggregateOutputSchema = object({ data: object({
21192
+ const ListWriteOutput = record(string(), unknown());
21193
+ const ListWriteResponse = object({
21194
+ data: ListWriteOutput.optional(),
21195
+ errors: array(record(string(), unknown())).optional()
21196
+ }).passthrough();
21197
+ const ListWriteAggregateOutput = object({
21193
21198
  list_id: string(),
21194
21199
  results: array(object({
21195
21200
  input: string(),
21196
21201
  user_id: string(),
21197
21202
  response: unknown()
21198
21203
  }))
21199
- }) }).passthrough();
21204
+ }).passthrough();
21205
+ const listWriteDataFromResponse = async (response) => {
21206
+ const data = ListWriteResponse.parse(await response.json());
21207
+ return data.data ?? data;
21208
+ };
21200
21209
  const readCost = (category, opts) => {
21201
21210
  const usage = priceUsage(costBPSForCategory(category));
21202
21211
  return {
@@ -21270,7 +21279,7 @@ const listReadContract = (inputSchema, pagination) => manualSchemaContract({
21270
21279
  });
21271
21280
  const listWriteContract = (args) => manualSchemaContract({
21272
21281
  inputSchema: args.inputSchema,
21273
- outputSchema: args.outputSchema ?? listOutputSchema,
21282
+ outputSchema: args.outputSchema ?? ListWriteOutput,
21274
21283
  auth: {
21275
21284
  required: true,
21276
21285
  scopes: ["read", "write"]
@@ -21376,13 +21385,13 @@ const listDeleteContract = listWriteContract({
21376
21385
  const listMemberWriteContract = listWriteContract({
21377
21386
  inputSchema: ListMemberWriteInput,
21378
21387
  method: "POST",
21379
- outputSchema: listWriteAggregateOutputSchema,
21388
+ outputSchema: ListWriteAggregateOutput,
21380
21389
  pricing: "list_manage"
21381
21390
  });
21382
21391
  const listMemberRemoveContract = listWriteContract({
21383
21392
  inputSchema: ListMemberWriteInput,
21384
21393
  method: "DELETE",
21385
- outputSchema: listWriteAggregateOutputSchema,
21394
+ outputSchema: ListWriteAggregateOutput,
21386
21395
  destructive: true,
21387
21396
  pricing: "list_manage"
21388
21397
  });
@@ -21563,7 +21572,7 @@ const buildLists = (deps) => {
21563
21572
  await deps.printResult({
21564
21573
  account: own.account,
21565
21574
  contract: listCreateContract,
21566
- data: await response.json(),
21575
+ data: await listWriteDataFromResponse(response),
21567
21576
  responseHeaders: response.headers
21568
21577
  });
21569
21578
  }
@@ -21624,7 +21633,7 @@ const buildLists = (deps) => {
21624
21633
  await deps.printResult({
21625
21634
  account: own.account,
21626
21635
  contract: listUpdateContract,
21627
- data: await response.json(),
21636
+ data: await listWriteDataFromResponse(response),
21628
21637
  resolved: [target.record],
21629
21638
  responseHeaders: response.headers
21630
21639
  });
@@ -21660,7 +21669,7 @@ const buildLists = (deps) => {
21660
21669
  await deps.printResult({
21661
21670
  account: own.account,
21662
21671
  contract: listDeleteContract,
21663
- data: await response.json(),
21672
+ data: await listWriteDataFromResponse(response),
21664
21673
  resolved: [target.record],
21665
21674
  responseHeaders: response.headers
21666
21675
  });
@@ -21792,16 +21801,16 @@ const buildList = (deps) => {
21792
21801
  results.push({
21793
21802
  input: user,
21794
21803
  user_id: userResolved.id,
21795
- response: await response.json()
21804
+ response: await listWriteDataFromResponse(response)
21796
21805
  });
21797
21806
  }
21798
21807
  await deps.printResult({
21799
21808
  account: own.account,
21800
21809
  contract: kind === "add" ? listMemberWriteContract : listMemberRemoveContract,
21801
- data: { data: {
21810
+ data: {
21802
21811
  list_id: target.id,
21803
21812
  results
21804
- } },
21813
+ },
21805
21814
  resolved
21806
21815
  });
21807
21816
  }
@@ -23913,7 +23922,7 @@ function createEnv(opts) {
23913
23922
  }
23914
23923
  //#endregion
23915
23924
  //#region package.json
23916
- var version$1 = "0.12.0";
23925
+ var version$1 = "0.12.2";
23917
23926
  //#endregion
23918
23927
  //#region src/lib/env.ts
23919
23928
  const URLWithTrailingSlash = url().transform(ensureTrailingSlash);
@@ -25446,8 +25455,8 @@ const isArray = nativeIsArray || function(obj) {
25446
25455
  };
25447
25456
  const isObject = (x) => x === Object(x) && !isArray(x);
25448
25457
  const isUndefined = (x) => void 0 === x;
25449
- const isString = (x) => "[object String]" == type_utils_toString.call(x);
25450
- const isEmptyString = (x) => isString(x) && 0 === x.trim().length;
25458
+ const isString$1 = (x) => "[object String]" == type_utils_toString.call(x);
25459
+ const isEmptyString = (x) => isString$1(x) && 0 === x.trim().length;
25451
25460
  const isNumber = (x) => "[object Number]" == type_utils_toString.call(x) && x === x;
25452
25461
  const isPlainError = (x) => x instanceof Error;
25453
25462
  function isPrimitive(value) {
@@ -26272,7 +26281,7 @@ var ObjectCoercer = class {
26272
26281
  return `${className && "Object" !== className ? `'${className}'` : "Object"} captured as exception with keys: ${keys}`;
26273
26282
  }
26274
26283
  isSeverityLevel(x) {
26275
- return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
26284
+ return isString$1(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
26276
26285
  }
26277
26286
  getErrorPropertyFromObject(obj) {
26278
26287
  for (const prop in obj) if (Object.prototype.hasOwnProperty.call(obj, prop)) {
@@ -38025,12 +38034,47 @@ const compareSemver = (left, right) => {
38025
38034
  }
38026
38035
  return 0;
38027
38036
  };
38028
- const detectPackageManager = (packageRoot) => {
38029
- const normalized = packageRoot.replaceAll("\\", "/");
38037
+ const normalizedPath = (path) => path.replaceAll("\\", "/");
38038
+ const managerFromPath = (path) => {
38039
+ const normalized = normalizedPath(path);
38030
38040
  if (normalized.includes("/Cellar/usesocial/") || normalized.includes("/Cellar/cli/") || normalized.includes("/Homebrew/")) return "brew";
38031
- if (normalized.includes("/.bun/install/global/")) return "bun";
38041
+ if (normalized.includes("/.bun/bin/") || normalized.includes("/.bun/install/global/")) return "bun";
38042
+ };
38043
+ const defaultRealpath = (path) => {
38044
+ try {
38045
+ return realpathSync(path);
38046
+ } catch {
38047
+ return;
38048
+ }
38049
+ };
38050
+ const isString = (value) => value !== void 0;
38051
+ const packageManagerPaths = (packageRoot, options) => {
38052
+ const pathExists = options.pathExists ?? existsSync;
38053
+ const realpath = options.realpath ?? defaultRealpath;
38054
+ const paths = [options.executablePath];
38055
+ if (options.pathEnv) for (const binDir of options.pathEnv.split(delimiter)) {
38056
+ if (!binDir) continue;
38057
+ for (const binary of ["social", "social.cmd"]) {
38058
+ const candidate = join(binDir, binary);
38059
+ if (pathExists(candidate)) paths.push(candidate);
38060
+ }
38061
+ }
38062
+ paths.push(packageRoot);
38063
+ return [...new Set(paths.flatMap((path) => path ? [path, realpath(path)] : []).filter(isString))];
38064
+ };
38065
+ const detectPackageManager = (packageRoot, options = {}) => {
38066
+ for (const path of packageManagerPaths(packageRoot, options)) {
38067
+ const manager = managerFromPath(path);
38068
+ if (manager) return manager;
38069
+ }
38032
38070
  return "npm";
38033
38071
  };
38072
+ const detectPackageManagerFor = (deps) => detectPackageManager(deps.packageRoot ?? internalPackageRoot(), {
38073
+ executablePath: deps.executablePath ?? process.argv[1],
38074
+ pathEnv: deps.pathEnv ?? process.env.PATH,
38075
+ pathExists: deps.pathExists,
38076
+ realpath: deps.realpath
38077
+ });
38034
38078
  const cliUpdateCommand = (manager) => {
38035
38079
  if (manager === "brew") return "brew upgrade usesocial/tap/cli";
38036
38080
  if (manager === "bun") return "bun install -g @usesocial/cli@latest";
@@ -38074,12 +38118,12 @@ const unknownCLIStatus = () => ({
38074
38118
  updateCommand: null
38075
38119
  });
38076
38120
  const checkCLIUpdate = async (deps = {}) => {
38077
- const packageRoot = deps.packageRoot ?? internalPackageRoot();
38121
+ const manager = detectPackageManagerFor(deps);
38078
38122
  const fetchImpl = deps.fetch ?? fetch;
38079
38123
  try {
38080
38124
  const response = await fetchImpl(NPM_REGISTRY_URL, { headers: { accept: "application/json" } });
38081
38125
  if (!response.ok) return unknownCLIStatus();
38082
- return parseNPMUpdateResult(await response.json(), VERSION, detectPackageManager(packageRoot));
38126
+ return parseNPMUpdateResult(await response.json(), VERSION, manager);
38083
38127
  } catch {
38084
38128
  return unknownCLIStatus();
38085
38129
  }
@@ -38243,7 +38287,7 @@ const unknownSkillStatus = () => ({
38243
38287
  updateCommand: null
38244
38288
  });
38245
38289
  const checkSkillUpdate = async (deps = {}) => {
38246
- const manager = detectPackageManager(deps.packageRoot ?? internalPackageRoot());
38290
+ const manager = detectPackageManagerFor(deps);
38247
38291
  const install = await installedSkillCandidate(deps);
38248
38292
  if (!install) return {
38249
38293
  scope: null,
@@ -38314,20 +38358,20 @@ const withNotice = (cache, key, now) => ({
38314
38358
  [key]: now
38315
38359
  }
38316
38360
  });
38317
- const noticeLinesFor = (cache, now) => {
38361
+ const noticeLinesFor = (cache, now, manager) => {
38318
38362
  const notices = [];
38319
- if (cache.cli.status === "update_available" && cache.cli.latestVersion && cache.cli.updateCommand) {
38363
+ if (cache.cli.status === "update_available" && cache.cli.currentVersion === VERSION && cache.cli.latestVersion && compareSemver(cache.cli.latestVersion, VERSION) > 0) {
38320
38364
  const key = `cli:${cache.cli.latestVersion}`;
38321
38365
  if (noticeDue(cache, key, now)) notices.push({
38322
38366
  key,
38323
- line: `Update available: social CLI ${cache.cli.latestVersion} (current ${cache.cli.currentVersion}). Run: ${cache.cli.updateCommand}`
38367
+ line: `Update available: social CLI ${cache.cli.latestVersion} (current ${cache.cli.currentVersion}). Run: ${cliUpdateCommand(manager)}`
38324
38368
  });
38325
38369
  }
38326
- if (cache.skill.status === "update_available" && cache.skill.scope && cache.skill.updateCommand && cache.skill.remoteTreeSHA) {
38370
+ if (cache.skill.status === "update_available" && cache.skill.scope && cache.skill.remoteTreeSHA) {
38327
38371
  const key = `skill:${cache.skill.scope}:${cache.skill.remoteTreeSHA}`;
38328
38372
  if (noticeDue(cache, key, now)) notices.push({
38329
38373
  key,
38330
- line: `Update available: social skill (${cache.skill.scope}). Run: ${cache.skill.updateCommand}`
38374
+ line: `Update available: social skill (${cache.skill.scope}). Run: ${skillUpdateCommand(cache.skill.scope, manager)}`
38331
38375
  });
38332
38376
  }
38333
38377
  return notices;
@@ -38351,8 +38395,9 @@ const maybeRunUpdateAwareness = async (deps = {}) => {
38351
38395
  const home = deps.home;
38352
38396
  const cache = await readCachedUpdateStatus(home);
38353
38397
  if (cache) {
38398
+ const manager = detectPackageManagerFor(deps);
38354
38399
  let next = cache;
38355
- for (const notice of noticeLinesFor(cache, now)) {
38400
+ for (const notice of noticeLinesFor(cache, now, manager)) {
38356
38401
  printStderrLine(notice.line);
38357
38402
  next = withNotice(next, notice.key, now);
38358
38403
  }