shipseal 0.1.0 → 0.1.1
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 +1 -1
- package/dist/cli.js +98 -71
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -409,8 +409,22 @@ function firstSentence(text) {
|
|
|
409
409
|
* sentences, and the fitting pass comfortably handles more.
|
|
410
410
|
*/
|
|
411
411
|
const HEADLINE_MAX_CHARS = 72;
|
|
412
|
+
/**
|
|
413
|
+
* Emoji ranges, removed from anything that reaches a card.
|
|
414
|
+
*
|
|
415
|
+
* No font we register carries these glyphs, so `\u{1F310} Human-friendly ...` (got's real
|
|
416
|
+
* GitHub description) rendered a tofu box on shipseal.dev. Takumi ships an emoji helper, but it
|
|
417
|
+
* rewrites each emoji into an <img> pointing at jsDelivr, and `generate()` does no network.
|
|
418
|
+
*
|
|
419
|
+
* The ranges deliberately start at U+2600, which keeps the textual symbols people put in real
|
|
420
|
+
* product names: (c) U+00A9, (r) U+00AE and (tm) U+2122 all sit below it.
|
|
421
|
+
*/
|
|
422
|
+
const EMOJI = /[\u{1F000}-\u{1FAFF}]|[\u{2600}-\u{27BF}]|[\u{FE00}-\u{FE0F}]|\u200D/gu;
|
|
423
|
+
function stripEmoji(text) {
|
|
424
|
+
return text.replaceAll(EMOJI, "").replace(/\s+/g, " ").trim();
|
|
425
|
+
}
|
|
412
426
|
function cleanLine(text) {
|
|
413
|
-
const stripped = text.replace(/\s*\u2014\s*/g, ": ").replace(/\s+\u2013\s+/g, ", ").replaceAll("–", "-").replaceAll("!", ".").replace(/\s+/g, " ").trim();
|
|
427
|
+
const stripped = stripEmoji(text).replace(/\s*\u2014\s*/g, ": ").replace(/\s+\u2013\s+/g, ", ").replaceAll("–", "-").replaceAll("!", ".").replace(/\s+/g, " ").trim();
|
|
414
428
|
const noTrail = stripped.endsWith(".") ? stripped.slice(0, -1) : stripped;
|
|
415
429
|
const first = noTrail.at(0);
|
|
416
430
|
if (first === void 0) return noTrail;
|
|
@@ -1820,7 +1834,7 @@ const storyPage = {
|
|
|
1820
1834
|
title: {
|
|
1821
1835
|
maxLines: tall ? 3 : 2,
|
|
1822
1836
|
maxFontSize: tall ? 64 : 48,
|
|
1823
|
-
minFontSize:
|
|
1837
|
+
minFontSize: tall ? 36 : 30,
|
|
1824
1838
|
step: 2,
|
|
1825
1839
|
box: {
|
|
1826
1840
|
width: width - 32,
|
|
@@ -1877,7 +1891,7 @@ const storyPage = {
|
|
|
1877
1891
|
render(raw, ctx) {
|
|
1878
1892
|
const props = propsSchema.parse(raw);
|
|
1879
1893
|
const colors = themeColors(ctx.brand, ctx.theme);
|
|
1880
|
-
const { tall,
|
|
1894
|
+
const { tall, bodyHeight, width } = geometry(ctx.format);
|
|
1881
1895
|
const editorial = ctx.brand.style === "editorial";
|
|
1882
1896
|
const terminal = ctx.brand.style === "terminal";
|
|
1883
1897
|
const code = isCommand(props.page);
|
|
@@ -1911,6 +1925,7 @@ const storyPage = {
|
|
|
1911
1925
|
justifyContent: "space-between",
|
|
1912
1926
|
alignItems: "center",
|
|
1913
1927
|
height: HEADER_HEIGHT,
|
|
1928
|
+
flexShrink: 0,
|
|
1914
1929
|
borderBottom: terminal ? `1px solid ${colors.muted}` : NO_BORDER,
|
|
1915
1930
|
paddingBottom: terminal ? 12 : 0
|
|
1916
1931
|
},
|
|
@@ -1943,83 +1958,91 @@ const storyPage = {
|
|
|
1943
1958
|
children: ctx.fitted.version?.text ?? props.version
|
|
1944
1959
|
})]
|
|
1945
1960
|
}),
|
|
1946
|
-
/* @__PURE__ */
|
|
1961
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1947
1962
|
style: {
|
|
1948
1963
|
display: "flex",
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1964
|
+
flexDirection: "column",
|
|
1965
|
+
flexGrow: 1,
|
|
1966
|
+
justifyContent: "center",
|
|
1967
|
+
gap: 24,
|
|
1968
|
+
minHeight: 0
|
|
1954
1969
|
},
|
|
1955
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
1970
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1956
1971
|
style: {
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1972
|
+
display: "flex",
|
|
1973
|
+
alignItems: "center",
|
|
1974
|
+
flexShrink: 0,
|
|
1975
|
+
paddingLeft: editorial ? 24 : 0,
|
|
1976
|
+
borderLeft: editorial ? `8px solid ${colors.primary}` : NO_BORDER
|
|
1962
1977
|
},
|
|
1963
|
-
children:
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1978
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1979
|
+
style: {
|
|
1980
|
+
fontFamily: props.heading,
|
|
1981
|
+
fontWeight: props.weight,
|
|
1982
|
+
fontSize: title?.fontSize ?? 48,
|
|
1983
|
+
lineHeight: 1.2,
|
|
1984
|
+
maxWidth: width - (editorial ? 32 : 0)
|
|
1985
|
+
},
|
|
1986
|
+
children: title?.text ?? props.page.title.value
|
|
1987
|
+
})
|
|
1988
|
+
}), comparison ? /* @__PURE__ */ jsx("div", {
|
|
1974
1989
|
style: {
|
|
1975
1990
|
display: "flex",
|
|
1976
|
-
flexDirection: "column",
|
|
1977
|
-
gap:
|
|
1978
|
-
|
|
1979
|
-
height: paneHeight
|
|
1991
|
+
flexDirection: tall ? "column" : "row",
|
|
1992
|
+
gap: 16,
|
|
1993
|
+
height: bodyHeight
|
|
1980
1994
|
},
|
|
1981
|
-
children: [/* @__PURE__ */
|
|
1995
|
+
children: ["before", "after"].map((label) => /* @__PURE__ */ jsxs("div", {
|
|
1982
1996
|
style: {
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1997
|
+
display: "flex",
|
|
1998
|
+
flexDirection: "column",
|
|
1999
|
+
gap: 8,
|
|
2000
|
+
width: paneWidth,
|
|
2001
|
+
height: paneHeight
|
|
1986
2002
|
},
|
|
1987
|
-
children:
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
backgroundColor: terminal || code ? colors.card : "transparent",
|
|
2003
|
-
borderRadius: terminal ? 0 : ctx.brand.radius,
|
|
2004
|
-
borderLeft: terminal ? `3px solid ${colors.primary}` : NO_BORDER
|
|
2005
|
-
},
|
|
2006
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
2003
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
2004
|
+
style: {
|
|
2005
|
+
fontFamily: props.body,
|
|
2006
|
+
fontSize: 20,
|
|
2007
|
+
color: colors.muted
|
|
2008
|
+
},
|
|
2009
|
+
children: label === "before" ? "Before" : "After"
|
|
2010
|
+
}), /* @__PURE__ */ jsx("img", {
|
|
2011
|
+
src: `story-${label}`,
|
|
2012
|
+
width: paneWidth,
|
|
2013
|
+
height: paneHeight - HEADER_HEIGHT,
|
|
2014
|
+
style: { objectFit: "contain" }
|
|
2015
|
+
})]
|
|
2016
|
+
}, label))
|
|
2017
|
+
}) : hasBody ? /* @__PURE__ */ jsx("div", {
|
|
2007
2018
|
style: {
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2019
|
+
display: "flex",
|
|
2020
|
+
flexDirection: "column",
|
|
2021
|
+
justifyContent: "flex-start",
|
|
2022
|
+
maxHeight: bodyHeight,
|
|
2023
|
+
padding: terminal || code ? BODY_PAD : 0,
|
|
2024
|
+
backgroundColor: terminal || code ? colors.card : "transparent",
|
|
2025
|
+
borderRadius: terminal ? 0 : ctx.brand.radius,
|
|
2026
|
+
borderLeft: terminal ? `3px solid ${colors.primary}` : NO_BORDER
|
|
2014
2027
|
},
|
|
2015
|
-
children:
|
|
2016
|
-
|
|
2017
|
-
|
|
2028
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
2029
|
+
style: {
|
|
2030
|
+
fontFamily: code ? props.mono : props.body,
|
|
2031
|
+
fontWeight: 400,
|
|
2032
|
+
fontSize: bodyFontSize,
|
|
2033
|
+
lineHeight: code ? CODE_LINE_HEIGHT : 1.2,
|
|
2034
|
+
whiteSpace: code ? "pre" : "normal",
|
|
2035
|
+
color: colors.foreground
|
|
2036
|
+
},
|
|
2037
|
+
children: bodyText
|
|
2038
|
+
})
|
|
2039
|
+
}) : void 0]
|
|
2040
|
+
}),
|
|
2018
2041
|
/* @__PURE__ */ jsxs("div", {
|
|
2019
2042
|
style: {
|
|
2020
2043
|
display: "flex",
|
|
2021
2044
|
justifyContent: "space-between",
|
|
2022
|
-
|
|
2045
|
+
flexShrink: 0,
|
|
2023
2046
|
fontFamily: props.mono,
|
|
2024
2047
|
fontWeight: 400,
|
|
2025
2048
|
fontSize: 16,
|
|
@@ -2408,7 +2431,7 @@ async function collectReadme(cwd) {
|
|
|
2408
2431
|
ref: "README.md H1",
|
|
2409
2432
|
fetchedAt
|
|
2410
2433
|
});
|
|
2411
|
-
if (tagline !== void 0) project.tagline = fact(tagline, {
|
|
2434
|
+
if (tagline !== void 0) project.tagline = fact(stripEmoji(tagline), {
|
|
2412
2435
|
source: "readme",
|
|
2413
2436
|
ref: "README.md first paragraph",
|
|
2414
2437
|
fetchedAt
|
|
@@ -2887,7 +2910,7 @@ async function collectGithub(options) {
|
|
|
2887
2910
|
};
|
|
2888
2911
|
if (repo.description !== void 0 && repo.description !== null && repo.description.length > 0) out.project = {
|
|
2889
2912
|
...out.project,
|
|
2890
|
-
tagline: fact(repo.description, {
|
|
2913
|
+
tagline: fact(stripEmoji(repo.description), {
|
|
2891
2914
|
source: "github-api",
|
|
2892
2915
|
ref: `GET /repos/${slug.owner}/${slug.repo} description`,
|
|
2893
2916
|
fetchedAt
|
|
@@ -3083,7 +3106,7 @@ async function collectPackageJson(cwd, packagePath = "package.json") {
|
|
|
3083
3106
|
ref: rawName === void 0 ? `${packagePath} directory name` : `${packagePath}#name`,
|
|
3084
3107
|
fetchedAt
|
|
3085
3108
|
}) };
|
|
3086
|
-
if (pkg.data.description !== void 0 && pkg.data.description.length > 0) project.tagline = fact(pkg.data.description, {
|
|
3109
|
+
if (pkg.data.description !== void 0 && pkg.data.description.length > 0) project.tagline = fact(stripEmoji(pkg.data.description), {
|
|
3087
3110
|
source: "package-json",
|
|
3088
3111
|
ref: `${packagePath}#description`,
|
|
3089
3112
|
fetchedAt
|
|
@@ -5596,10 +5619,10 @@ function overlayReleaseConfig(config, flags) {
|
|
|
5596
5619
|
//#region src/core/story.ts
|
|
5597
5620
|
const DEFAULT_CHANGE_PAGES = 4;
|
|
5598
5621
|
const STORY_FORMATS$1 = "portrait, square, og, github-social, x, linkedin, or producthunt";
|
|
5599
|
-
function storyFacts(facts, config,
|
|
5622
|
+
function storyFacts(facts, config, brand, generatedAt) {
|
|
5600
5623
|
const release = facts.release;
|
|
5601
5624
|
if (release === void 0) throw new ShipsealError("story.no-release", "No release facts are available for a story.", "Choose a published release or pass --tag to a local repository.");
|
|
5602
|
-
const copy = deterministicCopy(facts, config.release?.maxHighlights, name);
|
|
5625
|
+
const copy = deterministicCopy(facts, config.release?.maxHighlights, brand.name);
|
|
5603
5626
|
const configured = (value, ref) => fact(value, {
|
|
5604
5627
|
source: "user-config",
|
|
5605
5628
|
ref,
|
|
@@ -5614,7 +5637,11 @@ function storyFacts(facts, config, name, generatedAt) {
|
|
|
5614
5637
|
const pages = [{
|
|
5615
5638
|
kind: "cover",
|
|
5616
5639
|
title: fact(copy.headline, headlineSource.provenance),
|
|
5617
|
-
body: release.subheadline ?? facts.project.tagline ?? fact("Release notes", release.tag.provenance)
|
|
5640
|
+
body: release.subheadline ?? facts.project.tagline ?? (brand.tagline === void 0 ? fact("Release notes", release.tag.provenance) : fact(brand.tagline, {
|
|
5641
|
+
source: "user-config",
|
|
5642
|
+
ref: "brand.json#tagline",
|
|
5643
|
+
fetchedAt: generatedAt
|
|
5644
|
+
}))
|
|
5618
5645
|
}];
|
|
5619
5646
|
for (const item of changes.slice(0, config.release?.maxHighlights ?? DEFAULT_CHANGE_PAGES)) {
|
|
5620
5647
|
const collapsed = item.value.replaceAll(/\s+/g, " ").trim();
|
|
@@ -5657,7 +5684,7 @@ function storyFacts(facts, config, name, generatedAt) {
|
|
|
5657
5684
|
};
|
|
5658
5685
|
}
|
|
5659
5686
|
async function generateStory(input) {
|
|
5660
|
-
const facts = storyFacts(input.facts, input.config, input.brand
|
|
5687
|
+
const facts = storyFacts(input.facts, input.config, input.brand, input.generatedAt);
|
|
5661
5688
|
const pages = facts.story ?? [];
|
|
5662
5689
|
const result = {
|
|
5663
5690
|
files: [],
|