@zampsn/old-man-yells-at 1.0.0 → 1.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/README.md +10 -4
- package/dist/builder.d.ts +13 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +32 -0
- package/dist/builder.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/composite.d.ts +4 -0
- package/dist/composite.d.ts.map +1 -0
- package/dist/composite.js +11 -0
- package/dist/composite.js.map +1 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/template.d.ts +2 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +31 -0
- package/dist/template.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/yell-at.d.ts +3 -0
- package/dist/yell-at.d.ts.map +1 -0
- package/dist/yell-at.js +7 -0
- package/dist/yell-at.js.map +1 -0
- package/package.json +7 -2
- package/static/old-man-yells-at.png +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<p align="center"><img src="/static/old-man-yells-at.png" width="128" alt="Old man yells at" /></p>
|
|
2
|
+
<h3 align="center">old-man-yells-at</h3>
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://npmjs.com/package/@zampsn/old-man-yells-at"><img src="https://badgen.net/npm/v/@zampsn/old-man-yells-at" alt="npm"></a>
|
|
5
|
+
<a href="https://github.com/zampsn/old-man-yells-at/actions"><img src="https://github.com/zampsn/old-man-yells-at/actions/workflows/ci.yaml/badge.svg" alt="workflow status">
|
|
6
|
+
<a href="https://codecov.io/gh/zampsn/old-man-yells-at"><img src="https://codecov.io/gh/zampsn/old-man-yells-at/graph/badge.svg?token=ACgVjXxFeS" alt="code coverage"/></a></a>
|
|
7
|
+
</p>
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
You've got an opinion. A strong one. About something that probably doesn't deserve this much energy. old-man-yells-at is a TypeScript package that turns that frustration into art — specifically, Abe Simpson shaking his fist at whatever you point it at. Pass in a target, get back a meme. Simple as that.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type sharp from 'sharp';
|
|
2
|
+
export declare class Builder {
|
|
3
|
+
private readonly inputPath;
|
|
4
|
+
private readonly templateBuffer;
|
|
5
|
+
private outputWidth;
|
|
6
|
+
private outputHeight;
|
|
7
|
+
constructor(inputPath: string, templateBuffer: Buffer);
|
|
8
|
+
resize(width: number, height: number): this;
|
|
9
|
+
toSharp(): Promise<sharp.Sharp>;
|
|
10
|
+
toBuffer(): Promise<Buffer>;
|
|
11
|
+
toFile(outputPath: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,qBAAa,OAAO;IAChB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,YAAY,CAAwB;gBAEhC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IAKrD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAMrC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IAS/B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAI3B,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlD"}
|
package/dist/builder.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { compositeImages } from './composite.js';
|
|
2
|
+
const DEFAULT_SIZE = 128;
|
|
3
|
+
export class Builder {
|
|
4
|
+
inputPath;
|
|
5
|
+
templateBuffer;
|
|
6
|
+
outputWidth = DEFAULT_SIZE;
|
|
7
|
+
outputHeight = DEFAULT_SIZE;
|
|
8
|
+
constructor(inputPath, templateBuffer) {
|
|
9
|
+
this.inputPath = inputPath;
|
|
10
|
+
this.templateBuffer = templateBuffer;
|
|
11
|
+
}
|
|
12
|
+
resize(width, height) {
|
|
13
|
+
this.outputWidth = width;
|
|
14
|
+
this.outputHeight = height;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
async toSharp() {
|
|
18
|
+
return compositeImages({
|
|
19
|
+
inputPath: this.inputPath,
|
|
20
|
+
templateBuffer: this.templateBuffer,
|
|
21
|
+
width: this.outputWidth,
|
|
22
|
+
height: this.outputHeight,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
async toBuffer() {
|
|
26
|
+
return (await this.toSharp()).toBuffer();
|
|
27
|
+
}
|
|
28
|
+
async toFile(outputPath) {
|
|
29
|
+
await (await this.toSharp()).toFile(outputPath);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB,MAAM,OAAO,OAAO;IACC,SAAS,CAAS;IAClB,cAAc,CAAS;IAChC,WAAW,GAAW,YAAY,CAAC;IACnC,YAAY,GAAW,YAAY,CAAC;IAE5C,YAAY,SAAiB,EAAE,cAAsB;QACjD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,KAAa,EAAE,MAAc;QAChC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;QAC3B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO;QACT,OAAO,eAAe,CAAC;YACnB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,KAAK,EAAE,IAAI,CAAC,WAAW;YACvB,MAAM,EAAE,IAAI,CAAC,YAAY;SAC5B,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,QAAQ;QACV,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAkB;QAC3B,MAAM,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;CACJ"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,CAAC,8BAA8B,CAAC;KACjC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;KACrC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../src/composite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,eAAO,MAAM,eAAe,GAAU,SAAS,gBAAgB,KAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CASpF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
const OVERLAY_SIZE = 48;
|
|
3
|
+
export const compositeImages = async (options) => {
|
|
4
|
+
const { inputPath, templateBuffer, width, height } = options;
|
|
5
|
+
const overlay = await sharp(inputPath).resize(OVERLAY_SIZE, OVERLAY_SIZE, { fit: 'cover' }).toBuffer();
|
|
6
|
+
return sharp(templateBuffer)
|
|
7
|
+
.resize(width, height, { fit: 'cover' })
|
|
8
|
+
.composite([{ input: overlay, top: 16, left: 0 }])
|
|
9
|
+
.png();
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=composite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite.js","sourceRoot":"","sources":["../src/composite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,OAAyB,EAAwB,EAAE;IACrF,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE7D,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEvG,OAAO,KAAK,CAAC,cAAc,CAAC;SACvB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACvC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;SACjD,GAAG,EAAE,CAAC;AACf,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,MAAM,CAQxD,CAAC"}
|
package/dist/template.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @summary template fetches the old-man-yells-at.png base image from GitHub.
|
|
3
|
+
*
|
|
4
|
+
* For security, we verify the checksum of the image on first access.
|
|
5
|
+
*/
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
const EXPECTED_CHECKSUM = '7e0095f6b841b97f2745afcdc803b0895028de7caeeeb665e158ef6a20f35b80';
|
|
8
|
+
const TEMPLATE_URL = 'https://github.com/zampsn/old-man-yells-at/blob/main/static/old-man-yells-at.png?raw=true';
|
|
9
|
+
let cachedTemplate;
|
|
10
|
+
const verifyChecksum = (buffer) => {
|
|
11
|
+
const hash = createHash('sha256').update(buffer).digest('hex');
|
|
12
|
+
if (hash !== EXPECTED_CHECKSUM) {
|
|
13
|
+
throw new Error(`Template image checksum mismatch. Expected ${EXPECTED_CHECKSUM}, got ${hash}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const loadFromRemote = async () => {
|
|
17
|
+
const response = await fetch(TEMPLATE_URL);
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
throw new Error(`Failed to fetch template image: ${response.status} ${response.statusText}`);
|
|
20
|
+
}
|
|
21
|
+
return Buffer.from(await response.arrayBuffer());
|
|
22
|
+
};
|
|
23
|
+
export const getTemplateBuffer = async () => {
|
|
24
|
+
if (cachedTemplate)
|
|
25
|
+
return cachedTemplate;
|
|
26
|
+
const buffer = await loadFromRemote();
|
|
27
|
+
verifyChecksum(buffer);
|
|
28
|
+
cachedTemplate = buffer;
|
|
29
|
+
return buffer;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,iBAAiB,GAAG,kEAAkE,CAAC;AAC7F,MAAM,YAAY,GAAG,2FAA2F,CAAC;AAEjH,IAAI,cAAkC,CAAC;AAEvC,MAAM,cAAc,GAAG,CAAC,MAAc,EAAQ,EAAE;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,iBAAiB,SAAS,IAAI,EAAE,CAAC,CAAC;IACpG,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,KAAK,IAAqB,EAAE;IAC/C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mCAAmC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,IAAqB,EAAE;IACzD,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,cAAc,GAAG,MAAM,CAAC;IACxB,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yell-at.d.ts","sourceRoot":"","sources":["../src/yell-at.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,eAAO,MAAM,MAAM,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,OAAO,CAG/D,CAAC"}
|
package/dist/yell-at.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Builder } from './builder.js';
|
|
2
|
+
import { getTemplateBuffer } from './template.js';
|
|
3
|
+
export const yellAt = async (imagePath) => {
|
|
4
|
+
const templateBuffer = await getTemplateBuffer();
|
|
5
|
+
return new Builder(imagePath, templateBuffer);
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=yell-at.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yell-at.js","sourceRoot":"","sources":["../src/yell-at.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,SAAiB,EAAoB,EAAE;IAChE,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACjD,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAClD,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"main": "./dist/index.js",
|
|
25
25
|
"types": "./dist/index.d.ts",
|
|
26
26
|
"files": [
|
|
27
|
-
"dist"
|
|
27
|
+
"dist",
|
|
28
|
+
"static"
|
|
28
29
|
],
|
|
29
30
|
"publishConfig": {
|
|
30
31
|
"access": "public",
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@eslint/js": "^10.0.1",
|
|
39
|
+
"@types/node": "^25.5.0",
|
|
38
40
|
"@vitest/coverage-v8": "^4.1.1",
|
|
39
41
|
"eslint": "^10.1.0",
|
|
40
42
|
"eslint-config-prettier": "^10.1.8",
|
|
@@ -45,5 +47,8 @@
|
|
|
45
47
|
"typescript-eslint": "^8.57.2",
|
|
46
48
|
"vitest": "^4.1.1"
|
|
47
49
|
},
|
|
48
|
-
"
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"sharp": "^0.34.5"
|
|
52
|
+
},
|
|
53
|
+
"version": "1.1.0"
|
|
49
54
|
}
|
|
Binary file
|