profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/theianjones/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
Ian Jones theianjones egghead.io Fairfax, VA https://ianjones.us/ Building things on the internet 👨🏼‍💻

MaggieAppleton/digital-gardeners 1608

Resources, links, projects, and ideas for gardeners tending their digital notes on the public interwebs

dayhaysoos/use-shopping-cart 645

Shopping cart state and logic for Stripe

eggheadio/gatsby-theme-egghead-blog 18

This is a theme version of our gatsby-starter-egghead-blog.

eggheadio/bitmovin-player-ui 1

The Bitmovin Adaptive Streaming Player UI

startedlucydsl/liblucy

started time in a day

startedChrisShank/xrouter

started time in 11 days

issue commentstatelyai/xstate

*From utility types returning `never`

Oddly enough, when you add an actions object that is non-empty, it resolves the issue.

I forked that code sandbox here: https://codesandbox.io/s/exciting-chatterjee-yhxb2?file=/src/index.ts

waspeer

comment created time in 15 days

startedcurityio/pkce-javascript-example

started time in a month

issue commentromkatv/gitstatus

gitstatus failed to initialize

this did it. thanks!

— Ian Jones

--- original message --- On August 9, 2021, 11:29 AM EDT @***. wrote:

You need to update prezto.

You are receiving this because you authored the thread.

Reply to this email directly, view it on GitHub, or unsubscribe. --- end of original message ---

theianjones

comment created time in a month

issue openedromkatv/gitstatus

gitstatus failed to initialize

Heres the stack trace and error message:


  The content of /private/var/folders/q7/8wtn2xvs2xd52q26kwbhdhxc0000gn/T/gitstatus.POWERLEVEL9K.501.58634.1628519691.xtrace.log (gitstatus_start xtrace):

    +(anon):7> ((  ! _GITSTATUS_STATE_POWERLEVEL9K  ))
    +(anon):8> [[ -r /proc/version ]]
    +(anon):11> print -rn
    +(anon):12> zsystem flock -f lock_fd /private/var/folders/q7/8wtn2xvs2xd52q26kwbhdhxc0000gn/T/gitstatus.POWERLEVEL9K.501.58634.1628519691.lock
    +(anon):13> [[ 14 == <1-> ]]
    +(anon):15> typeset -gi '_GITSTATUS_LOCK_FD_POWERLEVEL9K=lock_fd'
    +(anon):18> '(anon)' /dev/fd/20
    +(anon):1> typeset -gi 'GITSTATUS_DAEMON_PID_POWERLEVEL9K=59072'
    +(anon):2> sysopen -r -o cloexec -u resp_fd -- /dev/fd/20
    +(anon):3> [[ 22 == <1-> ]]
    +(anon):4> typeset -gi '_GITSTATUS_RESP_FD_POWERLEVEL9K=resp_fd'
    +(anon):119> typeset -gi '_GITSTATUS_STATE_POWERLEVEL9K=1'
    +(anon):122> ((  ! async  ))
    +(anon):123> ((  _GITSTATUS_CLIENT_PID_POWERLEVEL9K == sysparams[pid]  ))
    +(anon):125> local pgid
    +(anon):126> ((  0 < 20  ))
    +(anon):127> [[ -t 22 ]]
    +(anon):128> sysread -s 20 -t 5.0000000000 -i 22 'pgid[$#pgid+1]'
    +(anon):128> return
                         ^ this command failed (5)

  The content of /private/var/folders/q7/8wtn2xvs2xd52q26kwbhdhxc0000gn/T/gitstatus.POWERLEVEL9K.501.58634.1628519691.daemon.log (gitstatus daemon log):

    +(anon):20> local pgid=59072
    +(anon):21> [[ 59072 == <1-> ]]
    +(anon):103> ((  lock_fd == -1  ))
    +(anon):25> trap '' PIPE
    +(anon):27> [[ -z '' ]]
    +(anon):28> local kernel
    +(anon):106> zsystem flock -- /private/var/folders/q7/8wtn2xvs2xd52q26kwbhdhxc0000gn/T/gitstatus.POWERLEVEL9K.501.58634.1628519691.lock
    +(anon):29> kernel=+(anon):29> uname -s
    +(anon):29> kernel=darwin 
    +(anon):30> [[ -n darwin ]]
    +(anon):33> [[ '' == /* ]]
    +(anon):35> ((  0  ))
    +(anon):37> [[ -n '' ]]
    +(anon):40> local -aU os
    +(anon):41> case darwin (linux)
    +(anon):41> case darwin (cygwin_nt-*)
    +(anon):41> case darwin (mingw | msys)
    +(anon):41> case darwin (*)
    +(anon):49> os=( darwin ) 
    +(anon):51> local arch
    +(anon):52> arch=+(anon):52> uname -m
    +(anon):52> arch=arm64 
    +(anon):53> [[ -n arm64 ]]
    +(anon):54> local daemons=( /Users/ianjones/.zprezto/modules/prompt/external/powerlevel10k/gitstatus/usrbin/gitstatusd-darwin-arm64 /Users/ianjones/.zprezto/modules/prompt/external/powerlevel10k/gitstatus/usrbin/gitstatusd-darwin-arm64-static /Users/ianjones/.zprezto/modules/prompt/external/powerlevel10k/gitstatus/bin/gitstatusd-darwin-arm64 /Users/ianjones/.zprezto/modules/prompt/external/powerlevel10k/gitstatus/bin/gitstatusd-darwin-arm64-static )
    +(anon):58> local files=( )
    +(anon):59> daemons=( ) 
    +(anon):61> ((  stderr_fd && 0 != 0  ))
    +(anon):71> ((  0  ))
    +(anon):71> return
    +(anon):98> local -i ret=1
    +(anon):99> kill -- -59072

  Your system information:

    zsh:      5.8
    uname -a: Darwin MacBook-Pro.local 20.6.0 Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:27 PDT 2021; root:xnu-7195.141.2~5/RELEASE_ARM64_T8101 arm64```

created time in a month

issue commentjohnlindquist/kit

Cant open kit("chrome")

Oh, good to know. I missed that update somewhere. Thanks!

— Ian Jones

--- original message --- On July 24, 2021, 2:32 PM EDT @***. wrote:

Those "kit libs" haven't existed for a few months now. They're all just global.

You are receiving this because you authored the thread.

Reply to this email directly, view it on GitHub, or unsubscribe. --- end of original message ---

theianjones

comment created time in 2 months

issue openedjohnlindquist/kit

Cant open kit("chrome")

Im getting this error when I run a script that depends on kit("chrome")

Cannot find module '/Users/ianjones/.kit/lib/chrome.js' imported from /Users/ianjones/.kit/api/kit.js Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/ianjones/.kit/lib/chrome.js' imported from /Users/ianjones/.kit/api/kit.js at new NodeError (node:internal/errors:329:5) at finalizeResolution (node:internal/modules/esm/resolve:323:11) at moduleResolve (node:internal/modules/esm/resolve:758:10) at Loader.defaultResolve [as _resolve] (node:internal/modules/esm/resolve:869:11) at Loader.resolve (node:internal/modules/esm/loader:86:40) at Loader.getModuleJob (node:internal/modules/esm/loader:230:28) at Loader.import (node:internal/modules/esm/loader:165:28) at importModuleDynamically (node:internal/modules/esm/translators:116:35) at exports.importModuleDynamicallyCallback (node:internal/process/esm_loader:30:14) at global.attemptImport (file:///Users/ianjones/.kit/api/kit.js:51:45)

Im on Kit version 1.3.0-beta.34.

I have a feeling something is wrong with the .kit i have but I'm not sure how to resolve the issue.

created time in 2 months

PullRequestReviewEvent
MemberEvent

push eventskillrecordings/next-skill-product-starter

Ian Jones

commit sha bc9e630db9969ccbf766d06d4a34ebe7356e6731

Viewer machine (#6) * add ability to load a stripe price id * add stripe prices serverless function * add comments to api/stripe/prices * move machine creation out of function * add comments to machine * refactor machine to /machines/commerce * add tests for getPriceParams and getStripeCheckoutParams * resolve absolute imports in tests * add tests for price fetcher * test checkout session fetcher * add initial tests for machine * fix the types * add typed viewer machine * refactor utils into their own file * update current user lambda to use dev access token * add tests for getAccessToken * add bulk purchase reset fix * move auth instantiation into utils * remove console.log * another console.log * use axios with interceptor * use viewer machine in context * implement request login in viewer machine * remove console.log * get logging in actually working * add refresh viewer to context * conditionally call function

view details

push time in 2 months

delete branch skillrecordings/next-skill-product-starter

delete branch : ij/viewer-machine

delete time in 2 months

PR merged skillrecordings/next-skill-product-starter

Reviewers
Viewer machine

This is branched off of #5

binocular

+1648 -1919

1 comment

18 changed files

theianjones

pr closed time in 2 months

push eventskillrecordings/next-skill-product-starter

Ian Jones

commit sha 723448eb040dc0a8efeb013b695d9b4747a81971

conditionally call function

view details

push time in 2 months

push eventskillrecordings/next-skill-product-starter

Ian Jones

commit sha ee3dbc0ff3b3175e45419ca5ac85a6dad6b6d056

Merge pull request #5 from skillrecordings/ij/document-commerce-machine Document and initial tests for Commerce Machine

view details

Ian Jones

commit sha 21b0e238ee3df2611dfe22d5ed3a6ccec56779ee

Merge branch 'main' of github.com:skillrecordings/next-skill-product-starter into ij/viewer-machine

view details

Ian Jones

commit sha 9f45c6136f9dd80558b077940d07b9ea5bec3782

add refresh viewer to context

view details

push time in 2 months

delete branch skillrecordings/next-skill-product-starter

delete branch : ij/document-commerce-machine

delete time in 2 months

push eventskillrecordings/next-skill-product-starter

Ian Jones

commit sha ee3dbc0ff3b3175e45419ca5ac85a6dad6b6d056

Merge pull request #5 from skillrecordings/ij/document-commerce-machine Document and initial tests for Commerce Machine

view details

push time in 2 months

push eventskillrecordings/next-skill-product-starter

Ian Jones

commit sha ffa17a5364173d400d890af96c8cc994afe1b062

comment about commerce machine design

view details

Ian Jones

commit sha d478f431146e3c3d4d540237ebd55100012db764

pass site in top level

view details

Ian Jones

commit sha 5f938a4e0670cf0c7de4b9fb5e00de10cf4e712f

fix tests failing because of site

view details

Ian Jones

commit sha 3ee677c80c457fa87ab529d3b67e6d2010eae3ad

make tests a little cleaner

view details

push time in 2 months

PR opened skillrecordings/next-skill-product-starter

Viewer machine

This is branched off of #5

binocular

+1793 -696

0 comment

28 changed files

pr created time in 2 months

create barnchskillrecordings/next-skill-product-starter

branch : ij/viewer-machine

created branch time in 2 months

push eventskillrecordings/next-skill-product-starter

Ian Jones

commit sha ce0fe43f7fcc3b8919eabdae4e45f368bf296795

fix the types

view details

push time in 2 months

startedalyssaxuu/flowy

started time in 2 months

Pull request review commentskillrecordings/next-skill-product-starter

Document and initial tests for Commerce Machine

+import {rest} from 'msw'+import {setupServer} from 'msw/node'+import {+  getPriceParams,+  getStripeCheckoutParams,+  priceFetcher,+  eggheadPriceCheckUrl,+  stripePriceCheckUrl,+  stripeCheckoutSessionUrl,+  checkoutSessionFetcher,

priceFetcher and checkoutSessionFetcher are both services the commerce machine uses and they have logic related to fetching a stripe price vs a egghead sellable price.

theianjones

comment created time in 2 months

Pull request review commentskillrecordings/next-skill-product-starter

Document and initial tests for Commerce Machine

 // used for __tests__/testing-library.js // learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom/extend-expect'+import dotenv from 'dotenv'+dotenv.config({path: './.env.test'})

load test env in the enviroment

theianjones

comment created time in 2 months

Pull request review commentskillrecordings/next-skill-product-starter

Document and initial tests for Commerce Machine

+import {rest} from 'msw'+import {setupServer} from 'msw/node'+import {interpret} from 'xstate'+import {SellableResource} from '@types'+import commerceMachine from '../'+import {+  CommerceMachineContext,+  eggheadPriceCheckUrl,+  stripeCheckoutSessionUrl,+} from '../utils'+const sellableData: SellableResource[] = require('../../../../data/bundles.development.json')++const sellable = sellableData[0]++const defaultContext = {+  sellable,+  upgradeFromSellable: null,+  bulk: false,+  quantity: 1,+  stripePriceId: undefined,+} as CommerceMachineContext++const response200 = [+  {+    full_price: 123.45,+    price: 123.45,+    slug: 'just-javascript-56c83b7b',+    url: 'http://app.egghead.af:5000/api/v1/playlists/just-javascript-56c83b7b',+  },+]+const server = setupServer(+  rest.post(eggheadPriceCheckUrl, (req, res, ctx) => {+    return res(ctx.json(response200))+  }),+  rest.post(stripeCheckoutSessionUrl, (req, res, ctx) => {+    return res(ctx.json({id: 'test_checkout_session_id'}))+  }),+)

with mock service worker, you can mock specific end points so your code can just run

theianjones

comment created time in 2 months

Pull request review commentskillrecordings/next-skill-product-starter

Document and initial tests for Commerce Machine

+import {rest} from 'msw'+import {setupServer} from 'msw/node'+import {+  getPriceParams,+  getStripeCheckoutParams,+  priceFetcher,+  eggheadPriceCheckUrl,+  stripePriceCheckUrl,+  stripeCheckoutSessionUrl,+  checkoutSessionFetcher,+} from '../utils'++const getContext = (options: any = {}) => {+  const defaultContext = {+    sellable: null,+    upgradeFromSellable: null,+    bulk: false,+    quantity: 1,+    stripePriceId: undefined,+  }++  return {...defaultContext, ...options}+}++describe('getPriceParams', () => {+  it('returns the stripe price id as {id}', () => {+    const machineContext = getContext({stripePriceId: 'abc123', sellable: {}})+    const params = getPriceParams(machineContext)+    expect(params).toStrictEqual({id: 'abc123'})+  })++  it('errors when sellable is null', () => {+    const machineContext = getContext()+    expect(() => getPriceParams(machineContext)).toThrow()+  })++  it('returns sellable params', () => {+    const contextOverride = {+      quantity: 1,+      sellable: {id: 'abc123', type: 'type', site: 'site'},+    }+    const machineContext = getContext(contextOverride)+    const params = getPriceParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.id,+          site: contextOverride.sellable.site,+        },+      ],+      site: contextOverride.sellable.site,+    })+  })++  it('returns sellable params with applied coupon', () => {+    const contextOverride = {+      quantity: 1,+      sellable: {id: 'abc123', type: 'type', site: 'site'},+      appliedCoupon: 'coupon',+    }+    const machineContext = getContext(contextOverride)+    const params = getPriceParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.id,+          site: contextOverride.sellable.site,+        },+      ],+      site: contextOverride.sellable.site,+      code: contextOverride.appliedCoupon,+    })+  })++  it('returns sellable params with an upgradeFromSellable', () => {+    const contextOverride = {+      quantity: 1,+      sellable: {id: 'abc123', type: 'type', site: 'site'},+      upgradeFromSellable: {+        slug: 'upgrade',+        type: 'type',+      },+    }+    const machineContext = getContext(contextOverride)+    const params = getPriceParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.id,+          site: contextOverride.sellable.site,+          upgrade_from_sellable_id: contextOverride.upgradeFromSellable.slug,+          upgrade_from_sellable: contextOverride.upgradeFromSellable.type,+        },+      ],+      site: contextOverride.sellable.site,+    })+  })+})++describe('getStripeCheckoutParams', () => {+  it('returns the stripe price id as {stripe_price_id}', () => {+    const machineContext = getContext({stripePriceId: 'abc123', sellable: {}})+    const params = getStripeCheckoutParams(machineContext)+    expect(params).toStrictEqual({stripe_price_id: 'abc123', quantity: 1})+  })++  it('errors when sellable is null', () => {+    const machineContext = getContext()+    expect(() => getStripeCheckoutParams(machineContext)).toThrow()+  })++  it('returns sellable params', () => {+    const contextOverride = {+      quantity: 1,+      sellable: {slug: 'abc123', type: 'type', site: 'site'},+    }+    const machineContext = getContext(contextOverride)+    const params = getStripeCheckoutParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.slug,+          site: contextOverride.sellable.site,+        },+      ],+    })+  })++  it('returns sellable params with applied coupon', () => {+    const contextOverride = {+      quantity: 1,+      sellable: {slug: 'abc123', type: 'type', site: 'site'},+      appliedCoupon: 'coupon',+    }+    const machineContext = getContext(contextOverride)+    const params = getStripeCheckoutParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.slug,+          site: contextOverride.sellable.site,+        },+      ],+      code: contextOverride.appliedCoupon,+    })+  })++  it('returns sellable params with an upgradeFromSellable', () => {+    const contextOverride = {+      quantity: 1,+      sellable: {slug: 'abc123', type: 'type', site: 'site'},+      upgradeFromSellable: {+        slug: 'upgrade',+        type: 'type',+      },+    }+    const machineContext = getContext(contextOverride)+    const params = getStripeCheckoutParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.slug,+          site: contextOverride.sellable.site,+          upgrade_from_sellable_id: contextOverride.upgradeFromSellable.slug,+          upgrade_from_sellable: contextOverride.upgradeFromSellable.type,+        },+      ],+    })+  })++  it('returns sellable params with bulk purchase', () => {+    const contextOverride = {+      quantity: 2,+      bulk: true,+      sellable: {slug: 'abc123', type: 'type', site: 'site'},+      upgradeFromSellable: {+        slug: 'upgrade',+        type: 'type',+      },+    }+    const machineContext = getContext(contextOverride)+    const params = getStripeCheckoutParams(machineContext)+    expect(params).toStrictEqual({+      sellables: [+        {+          bulk: contextOverride.bulk,+          quantity: contextOverride.quantity,+          sellable: contextOverride.sellable.type,+          sellable_id: contextOverride.sellable.slug,+          site: contextOverride.sellable.site,+          upgrade_from_sellable_id: contextOverride.upgradeFromSellable.slug,+          upgrade_from_sellable: contextOverride.upgradeFromSellable.type,+        },+      ],+    })+  })+})++describe('priceFetcher', () => {+  const server = setupServer(+    rest.get(stripePriceCheckUrl, (req, res, ctx) => {+      return res(ctx.json({stripeCalled: true}))+    }),+    rest.post(eggheadPriceCheckUrl, (req, res, ctx) => {+      return res(ctx.json({egghead: true}))+    }),+  )++  beforeAll(() => server.listen())+  afterAll(() => server.close())+  it('sends stripe price id request to serverless endpoint', async () => {+    const machineContext = getContext({stripePriceId: 'abc123', sellable: {}})+    const priceResult = await priceFetcher(machineContext)++    expect(priceResult.stripeCalled).toEqual(true)+  })++  it('sends sellable price request to egghead endpoint', async () => {+    const contextOverride = {+      quantity: 1,+      sellable: {id: 'abc123', type: 'type', site: 'site'},+    }+    const machineContext = getContext(contextOverride)+    const priceResult = await priceFetcher(machineContext)++    expect(priceResult.egghead).toEqual(true)+  })+})+describe('checkoutSessionFetcher', () => {+  console.log(stripeCheckoutSessionUrl)
theianjones

comment created time in 2 months

Pull request review commentskillrecordings/next-skill-product-starter

Document and initial tests for Commerce Machine

+import {rest} from 'msw'+import {setupServer} from 'msw/node'+import {interpret} from 'xstate'+import {SellableResource} from '@types'+import commerceMachine from '../'+import {+  CommerceMachineContext,+  eggheadPriceCheckUrl,+  stripeCheckoutSessionUrl,+} from '../utils'+const sellableData: SellableResource[] = require('../../../../data/bundles.development.json')++const sellable = sellableData[0]++const defaultContext = {+  sellable,+  upgradeFromSellable: null,+  bulk: false,+  quantity: 1,+  stripePriceId: undefined,+} as CommerceMachineContext++const response200 = [+  {+    full_price: 123.45,+    price: 123.45,+    slug: 'just-javascript-56c83b7b',+    url: 'http://app.egghead.af:5000/api/v1/playlists/just-javascript-56c83b7b',+  },+]+const server = setupServer(+  rest.post(eggheadPriceCheckUrl, (req, res, ctx) => {+    return res(ctx.json(response200))+  }),+  rest.post(stripeCheckoutSessionUrl, (req, res, ctx) => {+    return res(ctx.json({id: 'test_checkout_session_id'}))+  }),+)+const realLocation = window.location+afterEach(() => {+  window.location = realLocation+})+beforeAll(() => server.listen())+afterAll(() => server.close())++it('transitions immediately to fetching price', () => {+  const service = interpret(commerceMachine.withContext(defaultContext))+  service.start()+  expect(service.state.value).toBe('fetchingPrice')+})++it('applies a coupon from the coupon search param', (done) => {+  Reflect.deleteProperty(window, 'location')+  window.location = {+    ...realLocation,+    href: 'https://www.example.com?coupon=abc123',+    search: '?coupon=abc123',+  }+  const service = interpret(commerceMachine.withContext(defaultContext))++  service.onTransition((state) => {+    if (state.matches('fetchingPrice')) {+      expect(state.context.appliedCoupon).toBe('abc123')+      done()+    }+  })+  service.start()+})++it('loads the price of the sellable', (done) => {+  const service = interpret(commerceMachine.withContext(defaultContext))++  service.onTransition((state) => {+    if (state.matches('priceLoaded')) {+      expect(state.context.price).toStrictEqual(response200[0])+      done()+    }+  })+  service.start()+})++it('starts stripe checkout on event', (done) => {+  let sentToCheckout = false+  const service = interpret(+    commerceMachine+      .withConfig({+        actions: {+          sendToCheckout: () => {+            sentToCheckout = true+          },+        },+      })+      .withContext(defaultContext),+  )++  service.onTransition((state) => {+    if (service.state.matches('priceLoaded'))+      service.send({type: 'START_STRIPE_CHECKOUT'})++    if (state.matches('success')) {+      expect(sentToCheckout).toBeTruthy()+      done()+    }+  })++  service.start()+})

this test makes sure we can send the START_STRIPE_CHECKOUT event, which initiates our checkout flow to stripe.

theianjones

comment created time in 2 months

Pull request review commentskillrecordings/next-skill-product-starter

Document and initial tests for Commerce Machine

 module.exports = {   moduleNameMapper: {     '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',   },+  // resolve absolute imports in tests+  // https://stackoverflow.com/questions/50171412/jest-typescript-absolute-paths-baseurl-gives-error-cannot-find-module+  roots: ['src'],+  moduleDirectories: ['node_modules', 'src'],

this lets us resolve absolute imports in tests

theianjones

comment created time in 2 months

PullRequestReviewEvent