Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/logo building #89

Merged
merged 13 commits into from
Jan 31, 2023
Merged
9 changes: 9 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@ module.exports = {
// this was disabled already in all the logo files
"flowtype/require-exact-type": "off",
},
overrides: [
{
files: ["scripts/*"],
rules: {
"flowtype/require-valid-file-annotation": "off",
"no-sync": "off",
},
},
],
};
4 changes: 4 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ jobs:
run: |
git config --global user.email ${{ github.actor }}@users.noreply.github.com
git config --global user.name ${{ github.actor }}

- name: Update cdn folder with new svg files
run: npm run build-logos -- --commit

- name: Publish to npm
run: npm run release
env:
Expand Down
8 changes: 8 additions & 0 deletions .nodeops
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"PROJECT_TYPE": "front-tier",
"web": {
"projectName": "@paypal/sdk-logos",
"staticDirectory": "cdn",
"staticNamespace": "js-sdk-logos"
}
}
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"clean": "rimraf dist coverage",
"reinstall": "rimraf flow-typed && rimraf node_modules && npm install && flow-typed install",
"debug": "cross-env NODE_ENV=debug",
"prepare": "husky install"
"prepare": "husky install",
"build-logos": "babel-node --config-file './scripts/babel.config.json' --ignore ./fake --plugins=transform-es2015-modules-commonjs ./scripts/buildLogos.js"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this --ignore ./fake part do? Can we remove it?

Suggested change
"build-logos": "babel-node --config-file './scripts/babel.config.json' --ignore ./fake --plugins=transform-es2015-modules-commonjs ./scripts/buildLogos.js"
"build-logos": "babel-node --config-file './scripts/babel.config.json' --plugins=transform-es2015-modules-commonjs ./scripts/buildLogos.js"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an ignore flag to fix an issue with babel-node:

/Users/dustijones/code/public/paypal-sdk-logos/node_modules/@krakenjs/belter/src/index.js:3
export * from "./device";
^^^^^^

I'll see if I can find a long-term solution

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it may be a bug that occurs with babel-node when you use the --config-file flag.

babel/babel#11892

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find. We can keep this. I just wanted to understand why it is needed.

},
"standard-version": {
"types": [
Expand Down Expand Up @@ -95,7 +96,8 @@
"lint-staged": "^13.0.3",
"mocha": "9.2.0",
"prettier": "2.7.1",
"standard-version": "^9.5.0"
"standard-version": "^9.5.0",
"zx": "^4.3.0"
},
"dependencies": {
"@paypal/sdk-constants": "^1.0.128",
Expand Down
3 changes: 3 additions & 0 deletions scripts/babel.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@krakenjs/babel-config-grumbler/babelrc-node"
}
170 changes: 170 additions & 0 deletions scripts/buildLogos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/* @flow */

import fs from "fs-extra";
import { $ } from "zx";
import { html } from "@krakenjs/jsx-pragmatic";

import { getSVGFilename } from "../src/lib";
import { LOGO } from "../src/constants";
import {
APPLEPAY_LOGO_COLORS,
BANCONTACT_LOGO_COLORS,
BLIK_LOGO_COLORS,
BOLETO_LOGO_COLORS,
EPS_LOGO_COLORS,
getApplepaySVG,
getBancontactSVG,
getBlikSVG,
getBoletoSVG,
getEpsSVG,
getGiropaySVG,
getIdealSVG,
getItauSVG,
getMaximaSVG,
getMercadoPagoSVG,
getMultibancoSVG,
getMybankSVG,
getOxxoSVG,
getP24SVG,
getPaidySVG,
getPayuSVG,
getSatispaySVG,
getSepaSVG,
getSofortSVG,
getTrustlySVG,
getVerkkopankkiSVG,
getWechatpaySVG,
getZimplerSVG,
GIROPAY_LOGO_COLORS,
IDEAL_LOGO_COLORS,
ITAU_LOGO_COLORS,
MAXIMA_LOGO_COLORS,
MERCADOPAGO_LOGO_COLORS,
MULTIBANCO_LOGO_COLORS,
MYBANK_LOGO_COLORS,
OXXO_LOGO_COLORS,
P24_LOGO_COLORS,
PAIDY_LOGO_COLORS,
PAYU_LOGO_COLORS,
SATISPAY_LOGO_COLORS,
SEPA_LOGO_COLORS,
SOFORT_LOGO_COLORS,
TRUSTLY_LOGO_COLORS,
VERKKOPANKKI_LOGO_COLORS,
WECHATPAY_LOGO_COLORS,
ZIMPLER_LOGO_COLORS,
} from "../src/logos";
import { version } from "../package.json";

import { getNodeOps, updateCDNUrl } from "./utils";

const LOGO_GETTERS = {
[LOGO.APPLEPAY]: getApplepaySVG,
[LOGO.BANCONTACT]: getBancontactSVG,
[LOGO.BLIK]: getBlikSVG,
[LOGO.BOLETO]: getBoletoSVG,
[LOGO.EPS]: getEpsSVG,
[LOGO.GIROPAY]: getGiropaySVG,
[LOGO.IDEAL]: getIdealSVG,
[LOGO.ITAU]: getItauSVG,
[LOGO.MAXIMA]: getMaximaSVG,
[LOGO.MERCADOPAGO]: getMercadoPagoSVG,
[LOGO.MULTIBANCO]: getMultibancoSVG,
[LOGO.MYBANK]: getMybankSVG,
[LOGO.OXXO]: getOxxoSVG,
[LOGO.P24]: getP24SVG,
[LOGO.PAIDY]: getPaidySVG,
[LOGO.PAYU]: getPayuSVG,
[LOGO.SATISPAY]: getSatispaySVG,
[LOGO.SEPA]: getSepaSVG,
[LOGO.SOFORT]: getSofortSVG,
[LOGO.TRUSTLY]: getTrustlySVG,
[LOGO.VERKKOPANKKI]: getVerkkopankkiSVG,
[LOGO.WECHATPAY]: getWechatpaySVG,
[LOGO.ZIMPLER]: getZimplerSVG,
};

const LOGO_COLOR_MAPS = {
[LOGO.APPLEPAY]: APPLEPAY_LOGO_COLORS,
[LOGO.BANCONTACT]: BANCONTACT_LOGO_COLORS,
[LOGO.BLIK]: BLIK_LOGO_COLORS,
[LOGO.BOLETO]: BOLETO_LOGO_COLORS,
[LOGO.EPS]: EPS_LOGO_COLORS,
[LOGO.GIROPAY]: GIROPAY_LOGO_COLORS,
[LOGO.IDEAL]: IDEAL_LOGO_COLORS,
[LOGO.ITAU]: ITAU_LOGO_COLORS,
[LOGO.MAXIMA]: MAXIMA_LOGO_COLORS,
[LOGO.MERCADOPAGO]: MERCADOPAGO_LOGO_COLORS,
[LOGO.MULTIBANCO]: MULTIBANCO_LOGO_COLORS,
[LOGO.MYBANK]: MYBANK_LOGO_COLORS,
[LOGO.OXXO]: OXXO_LOGO_COLORS,
[LOGO.P24]: P24_LOGO_COLORS,
[LOGO.PAIDY]: PAIDY_LOGO_COLORS,
[LOGO.PAYU]: PAYU_LOGO_COLORS,
[LOGO.SATISPAY]: SATISPAY_LOGO_COLORS,
[LOGO.SEPA]: SEPA_LOGO_COLORS,
[LOGO.SOFORT]: SOFORT_LOGO_COLORS,
[LOGO.TRUSTLY]: TRUSTLY_LOGO_COLORS,
[LOGO.VERKKOPANKKI]: VERKKOPANKKI_LOGO_COLORS,
[LOGO.WECHATPAY]: WECHATPAY_LOGO_COLORS,
[LOGO.ZIMPLER]: ZIMPLER_LOGO_COLORS,
};

async function buildLogos() {
let shouldCommit = false;

if (process.argv.includes("--commit")) {
shouldCommit = true;
}

if (!version) {
throw new Error(`Package version required`);
}

const cdnNamespace = getNodeOps().web.staticNamespace;

if (!cdnNamespace) {
throw new Error(`CDN namespace required`);
}

if (cdnNamespace !== "js-sdk-logos") {
throw new Error("Expected cdnNamespace to be js-sdk-logos");
}

// updates CDN URL in src/constants.js with package version
updateCDNUrl(version);

const outdir = `cdn/${version}`;

await $`mkdir -p ${outdir}`;

const logoPromises = [];

for (const logoName of Object.keys(LOGO_GETTERS)) {
const logoGetter = LOGO_GETTERS[logoName];
const logoColorMap = LOGO_COLOR_MAPS[logoName];

for (const [colorName, logoColors] of Object.entries(logoColorMap)) {
// $FlowFixMe
const svg = logoGetter(logoColors);

// $FlowFixMe
const filename = getSVGFilename(logoName, colorName);
const filepath = `${outdir}/${filename}`;

// $FlowFixMe
logoPromises.push(fs.writeFile(filepath, svg.render(html())));
}
}

// eslint-disable-next-line no-restricted-globals,compat/compat,promise/no-native
await Promise.all(logoPromises);

if (shouldCommit) {
await $`git add cdn src/constants.js`;
await $`git commit -m "chore: generate CDN packages"`;
await $`git push`;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


buildLogos();
30 changes: 30 additions & 0 deletions scripts/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* @flow */

// eslint-disable-next-line import/no-nodejs-modules
import fs from "fs";

type NodeOps = {|
web: {|
staticNamespace: string,
|},
|};

export function getNodeOps(): NodeOps {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use this getNodeOps() function anywhere? If not, can we delete it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right. Should we use it to update the namespace in the CDN URL, like we do with package version? I like the idea of making it dynamic but it's another point of failure as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the .nodeops file can remain static similar to what we do in paypal/sdk-release.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it might be confusing if somebody ever tried to change the namespace and the urls didn't update. I don't see why we would ever need to change the namespace, though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I see your point. We can keep it then to validate the namespace name since its directly tied to the cdn url.

if (!fs.existsSync("./.nodeops")) {
throw new Error(`Node Ops file not found`);
}
return JSON.parse(fs.readFileSync("./.nodeops", "utf-8"));
}

export function updateCDNUrl(packageVersion: string) {
const filepath = "src/constants.js";

let constantsFile = fs.readFileSync(filepath, "utf-8");

constantsFile = constantsFile.replace(
/const PACKAGE_VERSION = ".*";/,
`const PACKAGE_VERSION = "${packageVersion}";`
);

fs.writeFileSync(filepath, constantsFile);
}
3 changes: 3 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ export const LOGO_CLASS = {
CARD: ("paypal-logo-card": "paypal-logo-card"),
LOGO_COLOR: ("paypal-logo-color": "paypal-logo-color"),
};

const PACKAGE_VERSION = "2.1.1";
export const CDN_BASE_URL = `https://www.paypalobjects.com/js-sdk-logos/${PACKAGE_VERSION}`;
12 changes: 11 additions & 1 deletion src/lib/components.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ import { LOGO_CLASS, LOGO_COLOR } from "../constants";

type SVGProps = {|
svg: ElementNode,
cdnUrl?: string,
loadFromCDN?: boolean,
[key: string]: mixed,
|};

export function SVG(props: SVGProps): ElementNode {
let { svg, ...otherProps } = props;
let { svg, cdnUrl, loadFromCDN, ...otherProps } = props;

if (loadFromCDN && cdnUrl) {
// $FlowFixMe
const svgProps: SVGProps = { src: cdnUrl, ...otherProps };
return <img {...svgProps} />;
}

if (!svg) {
throw new TypeError(`Expected svg prop`);
Expand All @@ -42,6 +50,8 @@ export type SVGLogoProps = {
render: () => ElementNode,
name: string,
logoColor?: $Values<typeof LOGO_COLOR>,
cdnUrl?: string,
loadFromCDN?: boolean,
};

export function SVGLogo({
Expand Down
23 changes: 22 additions & 1 deletion src/lib/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* @flow */

import { LOGO_COLOR } from "../constants";
import { CDN_BASE_URL, LOGO, LOGO_COLOR } from "../constants";
import type { LogoColorMap, LogoColors } from "../types";

export function getLogoColors(
Expand All @@ -26,3 +26,24 @@ export function getLogoColors(

return colors;
}

export function getSVGFilename(
logoName: $Values<typeof LOGO>,
logoColor: $Values<typeof LOGO_COLOR>
): string {
return `${logoName}-${logoColor}.svg`;
}

export function getLogoCDNUrl(
logoName: $Values<typeof LOGO>,
logoColorMap: LogoColorMap,
logoColor: $Values<typeof LOGO_COLOR>
): string {
if (!logoColorMap[logoColor]) {
logoColor = LOGO_COLOR.DEFAULT;
}

const svgFilename = getSVGFilename(logoName, logoColor);

return `${CDN_BASE_URL}/${svgFilename}`;
}
Loading