[컴][웹] Nextjs 의 pages/_app.tsx

 

넥스트js / 페이지 / 앱 / 파일 /변경 / next.js

Nextjs 의 pages/_app.tsx

pages/_app.tsx는 custom app 을 만들때 추가하게 된다. 여기를 통해서 다음과 같은 것들을 할 수 있다. [ref. 1]

  • 페이지 초기화
  • page 들의 공통적인 layout 등을 설정하거나,
  • page사이에 유지돼야 할 state 들
  • page 에 추가적으로 inject 할 데이터
  • global CSS 등을 추가할 수 있다.

References

  1. Advanced Features: Custom App | Next.js : pages/_app.js 에 대한 설명
  2. What is the _app File in Next.js?

[컴][웹] next.js commerce에서 provider 분석

커머스 넥스트 커머스 / 디버거/ 디버깅 / nextjs

next.js commerce에서 provider 분석

여기서는 이미구현된 vendure commerce provider 를 가지고 파악해 본다.

src/provider.tssrc/api/index.ts

provider.ts 와 api/index.ts 의 내용을 구현하면 되는 듯 하다.

  • <nextjs_commerce_root>\packages\vendure\src\provider.ts: Commerce Hooks에 대한 handler들을 export 한다.
  • <nextjs_commerce_root>\packages\vendure\src\api\index.ts: Commerce API 를 위한 provider 들을 export 한다.

provider 이름 추가

  • commerce-config.js에 있는 PROVIDERS 에 provider 이름 추가
  • .env.template에 provider 이름이 추가되어 있다. 여기에 넣어놓고, 나중에 .env.local등을 만들때 COMMERCE_PROVIDER에 이름을 적는다.

src/provider.ts

src/provider.ts에서 vendureProvider 를 볼 수 있는데, 이 object는 Provider type 에 match 돼야만 한다.

// <nextjs_commerce_root>\packages\vendure\src\provider.ts
//
import { handler as useCart } from './cart/use-cart'
import { handler as useAddItem } from './cart/use-add-item'
import { handler as useUpdateItem } from './cart/use-update-item'
import { handler as useRemoveItem } from './cart/use-remove-item'
import { handler as useCustomer } from './customer/use-customer'
import { handler as useSearch } from './product/use-search'
import { handler as useLogin } from './auth/use-login'
import { handler as useLogout } from './auth/use-logout'
import { handler as useSignup } from './auth/use-signup'
import { fetcher } from './fetcher'

export const vendureProvider = {
  locale: 'en-us',
  cartCookie: 'session',
  fetcher,
  cart: { useCart, useAddItem, useUpdateItem, useRemoveItem },
  customer: { useCustomer },
  products: { useSearch },
  auth: { useLogin, useLogout, useSignup },
}

export type VendureProvider = typeof vendureProvider

위에 보면 useCart 같은 handler 들이 보인다.

  • SWRHook : 이 useCart handler 들 처럼 data fetching 을 하는 handler 라면, SWRHook 을 implement해야 한다. 이 SWRHook 은 commerce/packages/commerce/src/utils/types.ts에 정의되어 있다.
  • MutationHook : useAddItem 같은 handler 처럼 mutation 을 사용하는 것이라면, MutationHook을 사용해야 한다.

어떻게 지정된 provider 이 사용되어지는가?

provider 를 정의해 놓으면, 이것과 관련해서 tsconfig.jsonpaths 추가하게 된다. @framework 라는 이름으로 지정한 provider 의 source 를 넣어주게 된다. 그래서 만들어진 provider 들을 사용하게 된다.

// /site/commerce-config.js
/**
 * This file is expected to be used in next.config.js only
 */
...

const PROVIDERS = [
  ...
  '@vercel/commerce-vendure',
  ...
]
function getProviderName() {
  return (
    process.env.COMMERCE_PROVIDER ||
    (process.env.BIGCOMMERCE_STOREFRONT_API_URL
      ? '@vercel/commerce-bigcommerce'
      : process.env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN
      ? '@vercel/commerce-shopify'
      : process.env.NEXT_PUBLIC_SWELL_STORE_ID
      ? '@vercel/commerce-swell'
      : '@vercel/commerce-local')
  )
}
...
function withCommerceConfig(nextConfig = {}) {
  const config = merge(
    { commerce: { provider: getProviderName() } },
    nextConfig
  )
  const { commerce } = config
  const { provider } = commerce

  ...
  // Update paths in `tsconfig.json` to point to the selected provider
  if (commerce.updateTSConfig !== false) {
    const tsconfigPath = path.join(
      process.cwd(),
      commerce.tsconfigPath || 'tsconfig.json'
    )
    const tsconfig = require(tsconfigPath)
    // The module path is a symlink in node_modules
    // -> /node_modules/[name]/dist/index.js
    const absolutePath = require.resolve(provider)
    // but we want references to go to the real path in /packages instead
    // -> packages/[name]/dist
    const distPath = path.join(path.relative(process.cwd(), absolutePath), '..')
    // -> /packages/[name]/src
    const modulePath = path.join(distPath, '../src')

    tsconfig.compilerOptions.paths['@framework'] = [`${modulePath}`]
    tsconfig.compilerOptions.paths['@framework/*'] = [`${modulePath}/*`]

    fs.writeFileSync(
      tsconfigPath,
      prettier.format(JSON.stringify(tsconfig), { parser: 'json' })
    )

    ...
  }

  return core.withCommerceConfig(config)
}

module.exports = { withCommerceConfig, getProviderName }
// tsconfig.json
{
  "compilerOptions": {
    ...
    "paths": {
      ...
      "@framework": ["..\\packages\\vendure\\src"],
      "@framework/*": ["..\\packages\\vendure\\src/*"]
    }
  },
  ...
}
// /site/pages/cart.tsx

import type { GetStaticPropsContext } from 'next'
import useCart from '@framework/cart/use-cart'
import usePrice from '@framework/product/use-price'
...

export async function getStaticProps({
  preview,
  locale,
  locales,
}: GetStaticPropsContext) {
  ...
  return {
    props: { pages, categories },
  }
}

export default function Cart() {
  const error = null
  const success = null
  const { data, isLoading, isEmpty } = useCart()
  const { openSidebar, setSidebarView } = useUI()

  const { price: subTotal } = usePrice(
    data && {
      amount: Number(data.subtotalPrice),
      currencyCode: data.currency.code,
    }
  )
  const { price: total } = usePrice(
    data && {
      amount: Number(data.totalPrice),
      currencyCode: data.currency.code,
    }
  )

  const goToCheckout = () => {
    openSidebar()
    setSidebarView('CHECKOUT_VIEW')
  }

  return (
    <Container className="grid lg:grid-cols-12 pt-4 gap-20">
      ...
    </Container>
  )
}

Cart.Layout = Layout

debugger

See Also

  1. 쿠…sal: [컴][웹] next.js commerce + vendure 서버 실행

Reference

  1. commerce/new-provider.md at main · vercel/commerce · GitHub
  2. Debugging with VS Code · Discussion #788 · vercel/commerce · GitHub

[컴][웹] gatsby plugin 들 일부 사용법

 

개츠비 / 게츠비 / SSG

gatsby plugin 들 일부 사용법

테스트로 몇가지 해본 사항을 추후에 참고하기 위해 적었다.

npm i gatsby-transformer-sharp

GatsbyImagecomponent 를 사용하려면, npm i gatsby-transformer-sharp 를 해야 한다. 그리고 gatsby-config.ts 에 아래처럼 추가해 준다.

이 plugin 이 image 를 받아서 여러 size 와 포맷으로 만들어준다. 그리고 해당하는 publid url 을 제공해준다.(?)

gatsby-transformer-sharp 를 설치하는 경우 gatsby-plugin-sharp도 같이 설치해줘야 하는 듯 하다. 설치하지 않으면, build 시점에 gatsby-plugin-shart 설정이 잘못됐다는 error 가 보인다.

// gatsby-config.ts
module.exports = {
    ...
    plugins: [
        ...
        `gatsby-transformer-sharp`,
        ...

npm i gatsby-plugin-sharp

Sharp image processing libraray 위에 만들어진 여러 이미지 처리 함수들을 노출한다. 다른 Gatsby 플러그인에서 일반적으로 사용하는 low-level helper 플러그인이다. 일반적으로 직접 사용해서는 안 된다. 그러나 very custom image processing을 수행하는 경우 유용할 수 있다.

// gatsby-config.ts
module.exports = {
    ...
    plugins: [
        ...
        `gatsby-plugin-sharp`,
        ...

npm i gatsby-plugin-image

gatsby-plugin-image 는 유저의 screen size 와 pixel density 를 보고 가장 최적의 miage size 와 format 을 정해서 전달해준다.

npm i gatsby-source-filesystem

npm i gatsby-source-filesystemcreateResolvers 에서 image file 에 대한 property 를 만들때 쓰였다.

// gatsby-config.ts
module.exports = {
    ...
    plugins: [
        {
            resolve: `gatsby-source-filesystem`,
            options: {
                name: `images`,
                path: `${__dirname}/src/images`,
            },
        },
        ...

npm i gatsby-source-graphql

다음링크처럼, gatsby 에서 여러가지의 source-plugin 들을 제공하는데, 여기에 원하는 source-plugin 이 없다면, gatsby-source-graphql을 사용해야 한다.

npm run develop

+----------------------------+     +------------------+
|                            |     |                  |
| server which serves gatsby |<--> | headless server  |
|                            |     |                  |
+----------------------------+     +------------------+
      |
      V
    +---------+
    | Web     |
    | browser |
    +---------+

gatsby-node.ts

import type { GatsbyNode } from "gatsby"
import path from "path";

// Log out information after a build is done
exports.onPostBuild = ({ reporter }) => {
  reporter.info(`Your Gatsby site has been built!`)
}
// Create blog pages dynamically
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const collections = await graphql(GET_COLLECTIONS)
  console.log(collections)
}

const GET_COLLECTIONS = /* GraphQL */ `
  query {
    vendure {
      collections {
        items {
          id
          name
          description
          slug
          breadcrumbs {
            id
            name
            slug
          }
          featuredAsset {
            id
            preview
            imageFile {
              childImageSharp {
                gatsbyImageData(width: 300, height: 300, quality: 85)
              }
            }
          }
          parent {
            id
            name
          }
        }
      }
    }
  }
`

[컴] 한국 금융 회사 보안 솔루션 문제

은행/ 증권 / 시스템 / 보안 / 해킹 / 금융 보안

한국 금융 회사 보안 솔루션 문제

Adblock Plus로 유명한 독일의 개발자 블라디미르 팔란트(Wladimir Palant)의 글

다 읽기 귀찮으면, “한국의 금융보안: 중간 결론”" 만 읽어도 충분하다.

이정도 수준인데도 큰일 없는 것 보면, 확실히 보안은 애매한 것 같다.

우리 금융회사 시스템은 점차 바뀌어야 할 시점인듯 싶다.

windows의 인증서 관리 콘솔

우리나라 보안업체의 무지한 대답

  1. 보안 취약점 저격 당한 국내 보안업계 “국내 환경 이해 부족” - 군사 마이너 갤러리, 2023-01-16

팔란트는 해당 취약점을 2022년 10월 한국인터넷진흥원(KISA) 인터넷보호나라(KRcert)에 먼저 신고했다. 이번에 그는 라온시큐어와 직접 연락하고자 했지만 연락 수단이 전화번호 외에는 없었다고 밝혔다.

이 같은 언급에 라온시큐어는 12일 이뉴스투데이와 통화에서 다른 의견을 제시했다. 라온시큐어 관계자는 “지난해 KISA로부터 전달받은 내용을 바탕으로 해당 취약점을 보완하는 패치를 개발 완료했다. 하지만 이용사 일정에 맞춰 적용해야 해서 아직 배포하지 못했다”고 해명했다.

이어 그는 “솔루션 취약점에 대한 공유는 솔루션을 발전시킬 수 있어 바람직하다”며 “그러나 이번 건(취약점 지적)은 국내 보안 시장 환경자체를 충분히 이해하지 못했다고 본다”고 반박했다.

그는 “키보드 보안은 호환성이나 시스템 레벨 접근과 같은 권한이 필요한 특이상황으로 C언어를 사용할 이유가 있다”며 “개발사가 환경이나 특성에 맞게 언어를 선택해 개발하고 있고, C++이 C보다 더 좋다고 해서 무조건 변경해야 하는 것은 아니다”라고 말했다. 건축 양식이 각 나라 환경에 맞게 발전하듯 보안 프로그램도 한국 상황에 맞게 만들어지고 있다는 설명이다.

라온시큐어에 따르면 PC로 은행 업무를 볼 때 설치하는 보안프로그램은 서로 연계가 돼, 하나의 보안 프로그램이 해킹의 위험에 노출되더라도 (다른 프로그램 도움을 받아) 방어할 수 있다. PC로 은행 업무를 볼 때 설치하는 여러 보안 프로그램이 각자 담당 영역을 나눠 해킹 위협으로부터 방어하는데, 이것이 은행의 보안 대책이라는 설명이다.

라온시큐어 관계자는 “(팔란트가) 국내 상황을 충분히 이해하지 못한 상태에서 당장 개발 언어를 바꿔야 안전하다고 말하는 것은 단편적인 부분만 바라본 것”이라고 주장했다.

그는 “라온시큐어 내부 방침으로 KISA와 공식적인 루트를 통해 일을 진행한다”며 “취약점이 밝혀지면 KISA와 긴밀하게 협의해 개발 일정을 지속적으로 보고하며 진행하고, 이번에도 그 절차를 밟았다”고 이야기했다.

See Also

  1. 보안공지 > 알림마당 : KISA 인터넷 보호나라&KrCERT
  2. 北 해커, KT 금융보안기업 이니텍 해킹··· 국정원·KISA가 적발
  3. 北 해커, KT 금융보안기업 이니텍 해킹··· 국정원·KISA가 적발 : 클리앙
  4. "해킹 강국 북한"…美 해킹대회 1~4위 '북한 대학생', 2023-07-07

[컴][db] insert 문 하나로 여러 값을 insert 하는 경우 LAST_INSERT_ID() 값

 

mysql / mariadb / 왜 last_insert_id 값이 다른지 / 큰지 / 너무 크다/ too higher / 왜 높게 나오는가 / 왜 auto_increment 값으로.

insert 문 하나로 여러 값을 insert 하는 경우 LAST_INSERT_ID()

from: MySQL :: MySQL 8.0 Reference Manual :: 12.16 Information Functions

Important

If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only. The reason for this is to make it possible to reproduce easily the same INSERT statement against some other server.

하나의 INSERT 문을 사용하여 여러 행을 삽입하는 경우 LAST_INSERT_ID()는 ’처음 삽입된 행에 대해 생성된 값’을 반환한다. 그 이유는 다른 서버에 대해 동일한 INSERT 문을 쉽게 재현할 수 있도록 하기 위해서다.

다음처럼 한번에 여러값을 insert 하는 경우가 있다고 가정하자. mytable 은 empty 이다.

이때, 아래 insert 문으로 인해 10개가 insert 된다고 하면, LAST_INSERT_ID()는 1 을 return 해준다.

INSERT mytable (
  name
)
SELECT name
FROM product
WHERE id > 0
;

SELECT LAST_INSERT_ID();

마지막 id 를 구하는 법

코드로 이것을 푼다면, insert 이후 return 되는 insert 된 row 의 개수를 가지고, LAST_INSERT_ID 의 값에 더해서 마지막 값을 구하면 된다. 식으로 나타내면 다음과 같다.

last_insert_id = LAST_INSERT_ID() + count_of_the_inserted_rows - 1

[컴][웹] gatsby 프로젝트 생성하고 page 만들기

게츠비 / gatsbyjs / 개츠비 /

gatsby 프로젝트 생성하고 page 만들기

npm init gatsby -ts로 시작하기 (typescript)


npm i gatsby-cli
npm init gatsby -ts

d:\a\prog\sashow\gatsby-inint\my-gatsby-site2>npm init gatsby -ts
create-gatsby version 3.6.0
...
This command will generate a new Gatsby site for you in d:\a\prog\sashow\gatsby-inint\my-gatsby-site2 with the setup you select. Let's answer some questions:


What would you like to call your site?
√ · my-site-test
What would you like to name the folder where your site will be created?
√ my-gatsby-site2/ my-site-test
√ Will you be using JavaScript or TypeScript?
· TypeScript
√ Will you be using a CMS?
· No (or I'll add it later)
√ Would you like to install a styling system?
· No (or I'll add it later)
√ Would you like to install additional features with other plugins?No items were selected

npm run develop

이제 http://localhost:8000 으로 접속할 수 있다.

typescript를 쓸때 제약사항들:

gasby new 로 생성

npm i gatsby-cli
node_modules\.bin\gatsby.cmd new my-gatsby-site

my-gatsby-site
node_modules\.bin\gatsby.cmd init

npx gatsby new my-gatsby-site

위 command 로 생성을 하면, 아래처럼 파일이 만들어진다.(gatsby 5.6.1)

src\
    - components\
        - header.js
        - index.module.css
        - layout.css
        - layout.js
        - seo.js
    - images\
        - example.png
        - gatsby-icon.png
    - pages\
        - 404.js
        - index.js
        - page-2.js
        - using-ssr.js
        - using-typescript.tsx
    - templates\ 
        - using-dsg.js
.gitignore
.prettierignore
.prettierrc
gatsby-browser.js
gatsby-config.js
gatsby-node.js
gatsby-ssr.js
LICENSE
package.json
package-lock.json
README.md

gatsby develop을 하면 실행된다.

node_modules\.bin\gatsby.cmd develop

이러면 /public 폴더에 static page 들이 만들어진다.

page 만들기

여기 를 보면 된다.

src/pages/about.tsx 를 만들면 된다. 그러면 이것은 http://localhost:8000/about 으로 가서 접근할 수 있다.

pages folder 내에 있는 page 에서 Head 를 export 하면 자동으로 head tag 에 넣어준다.(참고)

// about.tsx 예시
import * as React from 'react'

const AboutPage = () => {
  return (
    <main>
      <h1>About Me</h1>
      <p>Hi there! I'm the proud creator of this site, which I built with Gatsby.</p>
    </main>
  )
}

// pages folder 내에 있는 page 에서 Head 를 export 하면 자동으로 head tag 에 넣어준다.
export const Head = () => <title>About Me</title>

export default AboutPage

gatsby 에 대한 짧은 생각

gatsby 로 page 에 원하는 .js/ts 를 만들면 된다. 그러면, 결국은 각 page 로 나눠진 react 를 만들 수 있다.

여기에 더해, 쇼핑몰 같은 homepage 를 만든다고 하면, 특정 상품마다, url 이 다르고, page 가 있다. 이런 경우는 각 page를 만드는 것이 오래 걸릴 수 밖에 없고, 그것을 수동으로 하기엔 양이 너무 많아진다.

즉 이것은 이전에 서버단에 있던 template engine 같은 것들을 이용할 수 있다.

그런데, 이것을 굳이 template page 를 사용하고 싶지 않다. 그리고 template engine 도 써야하고, react library 도 써야 한다. 이것이 오히려 복잡하다는 느낌을 준다.

이것을 미리 build 시점에 만들어서 serve를 하게 되면, 우리는 react 의 이점은 누리면서, 굳이 template engine 을 사용하지 않아도 된다.

Reference

  1. Part 1: Create and Deploy Your First Gatsby Site | Gatsby

[컴] keyboard 로 열려있는 app navigation

 

navigate / opening app / switch / task switch

keyboard 로 열려있는 app navigation

다음 2개의 app 을 chatgpt 에서 추천받았다. 직접 써본 소감은 Switcheroo 가 좀 더 잘 동작하는 느낌이다.

“Alt-Tab Terminator” 는 alt+tab 키를 대체한 이후에, 특정 앱에서 alt+tab 키를 해도 동작하지 않았다.

다만 메모리 사용량은 “Alt-Tab Terminator”이 작다. 이건 이해가 잘 안가지만, 대략 12 MB 정도 찍힌다. switcheroo 는 몇번 사용하니 40 MB 가 넘어간다.

개인적으로 ram 을 아끼자는 주의라서 둘다 상시 쓸것 같진 않으나, 굳이 써야한다면, 나에겐 switcheroo 가 더 맞는 듯 싶다.

  1. kvakulo/Switcheroo: The humble incremental-search task switcher for Windows
  2. Alt-Tab Terminator - Best Alt-Tab Replacement for Windows 11/10 with Search, Live Previews and App Cloud - NTWind Software

추가

그 외 github 의 검색으로 다음 2개를 찾았다. 가장 괜찮은 것은 WindowSwitcher 인듯 싶다