@evcraddock/slug-cli 0.6.2 → 0.6.3

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/README.md CHANGED
@@ -51,7 +51,7 @@ Use `slug --site <name> site config show` to read supported runtime site configu
51
51
 
52
52
  Use `slug --site <name> doctor` to check API compatibility and package metadata. Use `slug --site <name> upgrade` for advisory, non-destructive package update recommendations; it reports suggested dependency changes without rewriting site files.
53
53
 
54
- Use `slug --site <name> post list`, `slug --site <name> post show <slug>`, `slug --site <name> post create`, `slug --site <name> post edit <slug>`, `slug --site <name> post publish <slug>`, `slug --site <name> post unpublish <slug>`, and `slug --site <name> post delete <slug>` to manage posts through the Slugkit posts API.
54
+ Use `slug --site <name> post list`, `slug --site <name> post show <slug>`, `slug --site <name> post create`, `slug --site <name> post edit <slug>`, `slug --site <name> post publish <slug>`, `slug --site <name> post unpublish <slug>`, and `slug --site <name> post delete <slug>` to manage posts through the Slugkit posts API. For migration imports, pass `--published-at <date-or-datetime>` to `post create` or `post publish` to preserve an original publish date without triggering follower delivery by default.
55
55
 
56
56
  Use `slug tag list` to list tags and post usage counts through the Slugkit tags API.
57
57
 
package/dist/commands.js CHANGED
@@ -22,10 +22,10 @@ Usage:
22
22
  slug [--config <file>] init <directory> --name <name> [--site-title <title>] [--template <name>] [--template-url <url>] [--template-dir <dir>] [--json]
23
23
  slug [--config <file>] --site <name> post list [--type article|link|note] [--status draft|published|all] [--tag <slug>] [--json]
24
24
  slug [--config <file>] post show <slug> [--json]
25
- slug [--config <file>] post create --type article|link|note --slug <slug> --content <text> [--title <text>] [--url <url>] [--excerpt <text>] [--tag <slug>]... [--source-id <id>] [--credit-contact-id <id>]... [--json]
26
- slug [--config <file>] post edit <slug> [--slug <new-slug>] [--title <text>] [--content <text>] [--url <url>] [--excerpt <text>] [--tag <slug>]... [--source-id <id>] [--credit-contact-id <id>]... [--json]
25
+ slug [--config <file>] post create --type article|link|note --slug <slug> --content <text> [--title <text>] [--url <url>] [--excerpt <text>] [--published-at <datetime>] [--tag <slug>]... [--source-id <id>] [--credit-contact-id <id>]... [--json]
26
+ slug [--config <file>] post edit <slug> [--slug <new-slug>] [--title <text>] [--content <text>] [--url <url>] [--excerpt <text>] [--published-at <datetime>] [--tag <slug>]... [--source-id <id>] [--credit-contact-id <id>]... [--json]
27
27
  slug [--config <file>] post delete <slug> [--json]
28
- slug [--config <file>] post publish <slug> [--json]
28
+ slug [--config <file>] post publish <slug> [--published-at <datetime>] [--json]
29
29
  slug [--config <file>] post unpublish <slug> [--json]
30
30
  slug [--config <file>] comment list [--post <slug>] [--status pending|approved|hidden|all] [--json]
31
31
  slug [--config <file>] comment approve <id> [--json]
@@ -920,6 +920,7 @@ async function runPostsCreateCommand(context, args) {
920
920
  "tag",
921
921
  "source-id",
922
922
  "credit-contact-id",
923
+ "published-at",
923
924
  ]);
924
925
  const body = createPostMutationInput(parsed.options, true);
925
926
  const api = await createConfiguredApiContext(context);
@@ -946,6 +947,7 @@ async function runPostsEditCommand(context, args) {
946
947
  "tag",
947
948
  "source-id",
948
949
  "credit-contact-id",
950
+ "published-at",
949
951
  ]);
950
952
  const body = createPostMutationInput(parsed.options, false);
951
953
  if (Object.keys(body).length === 0) {
@@ -975,12 +977,16 @@ async function runPostsDeleteCommand(context, args) {
975
977
  return { exitCode: ExitCode.Ok };
976
978
  }
977
979
  async function runPostsLifecycleCommand(context, args, action) {
978
- const { slug, json } = readSlugCommandArgs(args, `Usage: slug post ${action} <slug> [--json]`);
980
+ const usage = action === "publish"
981
+ ? "Usage: slug post publish <slug> [--published-at <datetime>] [--json]"
982
+ : "Usage: slug post unpublish <slug> [--json]";
983
+ const { slug, json, publishedAt } = readPostLifecycleArgs(args, usage, action);
979
984
  const api = await createConfiguredApiContext(context);
980
985
  writeMutationTarget(context.writer, api.apiBaseUrl, json);
981
986
  const response = await api.client.requestJson({
982
987
  method: "POST",
983
988
  path: `/posts/${encodeURIComponent(slug)}/${action}`,
989
+ body: publishedAt === undefined ? undefined : { publishedAt },
984
990
  });
985
991
  writePostMutationOutput(context.writer, response, json);
986
992
  return { exitCode: ExitCode.Ok };
@@ -1025,6 +1031,9 @@ function createPostMutationInput(options, requireCreateFields) {
1025
1031
  copyStringOption(options, input, "url", "url");
1026
1032
  copyStringOption(options, input, "excerpt", "excerpt");
1027
1033
  copyNumberOption(options, input, "source-id", "sourceId");
1034
+ if (typeof options["published-at"] === "string") {
1035
+ input.publishedAt = normalizeCliPublishedAt(options["published-at"]);
1036
+ }
1028
1037
  if (Array.isArray(options.tag)) {
1029
1038
  input.tagSlugs = options.tag;
1030
1039
  }
@@ -1065,6 +1074,37 @@ function readSlugCommandArgs(args, usage) {
1065
1074
  }
1066
1075
  return { slug: positional[0], json };
1067
1076
  }
1077
+ function readPostLifecycleArgs(args, usage, action) {
1078
+ if (action === "unpublish") {
1079
+ const { slug, json } = readSlugCommandArgs(args, usage);
1080
+ return { slug, json };
1081
+ }
1082
+ const slug = args[0];
1083
+ if (slug === undefined || slug.startsWith("--")) {
1084
+ throw createInvalidUsageError(usage);
1085
+ }
1086
+ const parsed = parsePostFlags(args.slice(1), ["published-at"]);
1087
+ return {
1088
+ slug,
1089
+ json: parsed.json,
1090
+ publishedAt: typeof parsed.options["published-at"] === "string"
1091
+ ? normalizeCliPublishedAt(parsed.options["published-at"])
1092
+ : undefined,
1093
+ };
1094
+ }
1095
+ function normalizeCliPublishedAt(value) {
1096
+ const isDateOnly = /^\d{4}-\d{2}-\d{2}$/.test(value);
1097
+ const isDateTime = /^\d{4}-\d{2}-\d{2}T/.test(value);
1098
+ if (!isDateOnly && !isDateTime) {
1099
+ throw createInvalidUsageError("--published-at must be a valid ISO date or datetime");
1100
+ }
1101
+ const normalizedInput = isDateOnly ? `${value}T00:00:00.000Z` : value;
1102
+ const date = new Date(normalizedInput);
1103
+ if (Number.isNaN(date.valueOf())) {
1104
+ throw createInvalidUsageError("--published-at must be a valid ISO date or datetime");
1105
+ }
1106
+ return date.toISOString();
1107
+ }
1068
1108
  function addOptionalQuery(query, key, value) {
1069
1109
  if (typeof value === "string") {
1070
1110
  query.set(key, value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evcraddock/slug-cli",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Command-line tool for Slugkit sites.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@evcraddock/slug-core": "0.1.1",
30
- "@evcraddock/slug-template": "0.1.2",
30
+ "@evcraddock/slug-template": "0.1.3",
31
31
  "tar": "^7.5.16"
32
32
  }
33
33
  }