@m2s2/cli 0.2.15 → 0.2.17
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 +16 -0
- package/README.md +98 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.17] - 2026-08-02
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [0.2.16] - 2026-07-31
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
- Angular jest-preset-angular v17 setup API + e2e sandbox dev-spawn skip
|
|
17
|
+
- Sync template dependencies to latest @m2s2 releases
|
|
18
|
+
- Formatting and test fixes
|
|
19
|
+
- Clippy fix
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
- Add `m2s2 publish` command for cross-posting blog articles
|
|
23
|
+
- Add cover image support to publishers
|
|
24
|
+
|
|
25
|
+
|
|
10
26
|
## [0.2.15] - 2026-07-30
|
|
11
27
|
|
|
12
28
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ The official CLI for scaffolding and working with [M²S²](https://github.com/M2
|
|
|
14
14
|
- [generate service](#m2s2-generate-service)
|
|
15
15
|
- [upgrade](#m2s2-upgrade)
|
|
16
16
|
- [completions](#m2s2-completions)
|
|
17
|
+
- [publish](#m2s2-publish)
|
|
17
18
|
- [Building from Source](#building-from-source)
|
|
18
19
|
- [Testing](#testing)
|
|
19
20
|
- [Project Structure](#project-structure)
|
|
@@ -402,6 +403,103 @@ The upgrade command hits the GitHub Releases API, compares the latest release ta
|
|
|
402
403
|
|
|
403
404
|
---
|
|
404
405
|
|
|
406
|
+
### `m2s2 publish`
|
|
407
|
+
|
|
408
|
+
Publish a Markdown article (YAML frontmatter) to Dev.to, Hashnode, and/or your own blog. Unrelated to the scaffolding commands above — this is a general-purpose cross-posting tool that happens to live in the same CLI.
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
m2s2 publish <file> [OPTIONS]
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Arguments**
|
|
415
|
+
|
|
416
|
+
| Argument | Description |
|
|
417
|
+
|----------|-------------|
|
|
418
|
+
| `<file>` | Path to the Markdown article |
|
|
419
|
+
|
|
420
|
+
**Options**
|
|
421
|
+
|
|
422
|
+
| Flag | Description |
|
|
423
|
+
|------|-------------|
|
|
424
|
+
| `--to <targets>` | Comma-separated target list (`devto`, `hashnode`, `platform`), overriding the frontmatter's `publish:` list |
|
|
425
|
+
| `--update` | Update an existing post instead of creating a new one. Only the `platform` target supports this today — see the table below. |
|
|
426
|
+
| `--preflight-only` | Validate every target and build the exact request each would send, then stop — no network requests, nothing published. |
|
|
427
|
+
|
|
428
|
+
**Article format**
|
|
429
|
+
|
|
430
|
+
```markdown
|
|
431
|
+
---
|
|
432
|
+
title: "My Post"
|
|
433
|
+
date: 2026-07-30
|
|
434
|
+
summary: "A short description"
|
|
435
|
+
slug: my-post # optional, derived from the filename otherwise
|
|
436
|
+
tags: [rust, cli]
|
|
437
|
+
excerpt: "..." # optional
|
|
438
|
+
cover_image: https://... # optional — a URL, or a local path resolved relative to the article
|
|
439
|
+
canonical_url: https://... # optional
|
|
440
|
+
publish: [devto, platform] # target list, overridden by --to when given
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
Article body in Markdown.
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`cover_image` accepts either an already-hosted URL or a path to a local file. A local path is uploaded automatically for the `platform` target; Dev.to and Hashnode have no image-upload endpoint in their APIs at all, so a local path there fails *before* anything is published (see the preflight note below) — host the image yourself first and use its URL instead.
|
|
447
|
+
|
|
448
|
+
**Config — `.m2s2-publish.toml`**
|
|
449
|
+
|
|
450
|
+
Credentials live in a `.m2s2-publish.toml` file in the directory you run `m2s2 publish` from — typically your blog-content repo, not a checkout of this CLI. **Make sure that repo gitignores it**, since it holds secrets.
|
|
451
|
+
|
|
452
|
+
```toml
|
|
453
|
+
[devto]
|
|
454
|
+
api_key = "..."
|
|
455
|
+
|
|
456
|
+
[hashnode]
|
|
457
|
+
token = "..."
|
|
458
|
+
publication_id = "..."
|
|
459
|
+
|
|
460
|
+
[platform]
|
|
461
|
+
endpoint = "https://api.example.com"
|
|
462
|
+
# path = "/admin/blog" (optional, this is the default)
|
|
463
|
+
token = "..."
|
|
464
|
+
# body_command = "./hooks/build-body.sh" (optional, see below)
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Any `[section]` that's entirely missing from the file falls back to environment variables instead (the file not existing at all is fine too, as long as env vars cover every target you select). A section already present in the file always wins over env vars — this only fills in a section that's absent, not individual fields within one that exists.
|
|
468
|
+
|
|
469
|
+
| Target | Env vars |
|
|
470
|
+
|--------|----------|
|
|
471
|
+
| `devto` | `M2S2_PUBLISH_DEVTO_API_KEY` |
|
|
472
|
+
| `hashnode` | `M2S2_PUBLISH_HASHNODE_TOKEN` + `M2S2_PUBLISH_HASHNODE_PUBLICATION_ID` |
|
|
473
|
+
| `platform` | `M2S2_PUBLISH_PLATFORM_ENDPOINT` + `M2S2_PUBLISH_PLATFORM_TOKEN` (optionally `_PATH` / `_BODY_COMMAND`) |
|
|
474
|
+
|
|
475
|
+
**Targets**
|
|
476
|
+
|
|
477
|
+
| Target | `--update` | `cover_image` | Notes |
|
|
478
|
+
|--------|------------|----------------|-------|
|
|
479
|
+
| `devto` | Not supported | URL only | Forem/Dev.to API has no image-upload endpoint at all. |
|
|
480
|
+
| `hashnode` | Not supported | URL only | Requires a paid Hashnode Pro subscription as of Hashnode's May 2026 API changes. Same no-upload limitation as Dev.to. |
|
|
481
|
+
| `platform` | Supported | URL, or a local file (uploaded automatically) | A generic target, not specific to any one site — works with any blog exposing a `POST`/`PUT .../admin/blog`-shaped API with bearer auth. `body_command` replaces the request body entirely with your own script's output if the built-in field mapping doesn't match your API. |
|
|
482
|
+
|
|
483
|
+
**Examples**
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
# Publish to whatever targets are listed in the article's frontmatter
|
|
487
|
+
m2s2 publish posts/my-article.md
|
|
488
|
+
|
|
489
|
+
# Publish to specific targets regardless of frontmatter
|
|
490
|
+
m2s2 publish posts/my-article.md --to devto,platform
|
|
491
|
+
|
|
492
|
+
# Update an existing platform post
|
|
493
|
+
m2s2 publish posts/my-article.md --to platform --update
|
|
494
|
+
|
|
495
|
+
# Check everything's valid without publishing anything
|
|
496
|
+
m2s2 publish posts/my-article.md --preflight-only
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
Every selected target is validated (`--update` support, `cover_image` compatibility) *and* has its exact request built *before* any of them publishes — Dev.to and Hashnode have no update support, so if one target succeeded and a later one then failed, a retry would create a duplicate post on the ones that already succeeded rather than safely resuming. `--preflight-only` runs just that step and stops, so you can check everything's valid — credentials present, cover images resolvable, request built — without publishing anything.
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
405
503
|
## Building from Source
|
|
406
504
|
|
|
407
505
|
**Prerequisites:** Rust 1.85+ (edition 2024), Node.js 18+ for running scaffolded projects.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"hasInstallScript": true,
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"name": "@m2s2/cli",
|
|
26
|
-
"version": "0.2.
|
|
26
|
+
"version": "0.2.17"
|
|
27
27
|
},
|
|
28
28
|
"node_modules/@isaacs/cliui": {
|
|
29
29
|
"engines": {
|
|
@@ -542,5 +542,5 @@
|
|
|
542
542
|
}
|
|
543
543
|
},
|
|
544
544
|
"requires": true,
|
|
545
|
-
"version": "0.2.
|
|
545
|
+
"version": "0.2.17"
|
|
546
546
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"artifactDownloadUrls": [
|
|
3
|
-
"https://github.com/M2S2-Engineering-Group/m2s2-cli/releases/download/v0.2.
|
|
3
|
+
"https://github.com/M2S2-Engineering-Group/m2s2-cli/releases/download/v0.2.17"
|
|
4
4
|
],
|
|
5
5
|
"author": "M²S² Engineering Group <contact@m2s2.io>",
|
|
6
6
|
"bin": {
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"zipExt": ".tar.xz"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
|
-
"version": "0.2.
|
|
98
|
+
"version": "0.2.17",
|
|
99
99
|
"volta": {
|
|
100
100
|
"node": "18.14.1",
|
|
101
101
|
"npm": "9.5.0"
|