Contentful Management API (CMA) how to upload references

This is not documented. If it is, please show me where.

To upload a reference field, ensure the reference already exists, and upload an object containing the sys key whose value is an object containing type linkType and id

Example: you have an Entry with id: MY_PARENT_ID with a MY_REFERENCES field.

this.managementClient
      .getSpace(this.config.space_id)
      .then((space) => space.getEnvironment(this.config.environment));
      .then((environment) => environment.getEntry("MY_PARENT_ID"))
      .then((entry) => {
        entry.fields = {
          ...entry.fields,
          MY_REFERENCES: { // replace with your own multi reference field
            "en-US": [
              {
                sys: {
                  type: "Link",
                  linkType: "Entry",
                  id: "my_reference_id"
                },
              },
              // ...repeat as needed
            ],

docker-machine can’t connect to droplet

docker-machine ls outputs: Unable to query docker version: Cannot connect to the docker engine endpoint

Apparently it’s a problem with the latest docker engine version, and you can specify an override to docker-machine via --engine-install-url

There are various versions available here: https://github.com/rancher/install-docker, and this company/repo seems to be verified by docker.

Source: https://www.digitalocean.com/community/questions/unable-to-verify-the-docker-daemon-is-listening @sithembisok

I also had the same problem with Linode so it’s probably an issue on any host. The solution comment above is quite old, so I imagine a lot of folks in the entire ecosystem are having issues. The low visibility and lack of fix on the latest version kind of struck me as odd.

Here’s my Digital Ocean command:

docker-machine create \
        -d digitalocean `# driver` \
        --digitalocean-access-token your-token `# ` \
        --digitalocean-image ubuntu-20-04-x64 `# LTS release` \
        --digitalocean-region sfo3 `# region` \
        --digitalocean-backups=false `# backups` \
        --engine-install-url "https://releases.rancher.com/install-docker/19.03.9.sh" `# use older docker engine; current broken ` \
        default `# machine name`

ERR_UNHANDLED_REJECTION Unexpected token: punc (.) terser

I’m getting a prod only build error that wasn’t very helpful with no line numbers and an error thrown deep in terser.

This error for me turned out to be unsupported handling of the new Optional Chaining operator (foo?.) — make sure if you’re using it your bundler configurations are handling said feature.

In my case I’m using a node environment set up by what looks like a Contentful UI Extension starter app, so I don’t want to modify any build configurations. I just removed it and moved on.

Docker Compose Up (v2) – “Can’t separate key from value”

If you’re trying to use docker compose up and have enabled docker compose v2 in the Docker client, have no trouble using docker-compose up , but get the error “Can’t separate key from value”, then see if your .env file contains any unsupported scripting.

In my case, I had some bash scripting in my .env file from years ago when I used autoenv to activate some local state upon cding into the directory.

Seems like the old docker-compose didn’t mind, but docker compose does. Deleted the scripting and I’m good to go.

Generally speaking when you get this error, review your env files.

M1 Mac Install Python 3.3.7

Installing legacy pythons is _hard_

I think that the trick to installing 3.3.7 is to have homebrew temporarily remove the openssl@1.1 library by entering brew uninstall openssl

Now, install pyenv with the target version, with all the compiler flags for zlib, bzip2 etc., and the arch detect patch.

brew uninstall --ignore-dependencies openssl@1.1

CPPFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" 

LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib"

pyenv install --patch 3.3.7 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch)

This should force the installer to install the applicable (old) openssl == 1.0.2k and successfully complete.

Reinstall openssl@1.1 when complete.

Other things of note:

type in which python if it’s not the pyenv shim, add export PATH="$HOME/.pyenv/shims:$PATH" to your .zshrc

Top post here is also useful for a step by step forced Rosetta brew install that’s comprehensive https://stackoverflow.com/questions/65349982/issues-installing-python-3-x-via-pyenv

I’m still struggling to get a pyenv virtualenvwrapper pip install to appear from the local python.

More to come…

React Three Fiber Set Default Camera

To set the default camera in 2021+, use state.set exposed from useThree. Note that `setDefaultCamera` does not exist anymore, and every reference would use that.

“setDefaultCamera is not a function”

Instead, use the following:


const Camera = (props) => {
  const ref = useRef();
  const set = useThree((state) => state.set);
  useEffect(() => void set({ camera: ref.current }), []);
  useFrame(() => ref.current.updateMatrixWorld());
  return <perspectiveCamera ref={ref} {...props} />;
};

React three fiber docs (they are hard to find): https://docs.pmnd.rs/react-three-fiber/API/objects

Redux Toolkit – Solving Circular Action Dependencies

The singular struggle I have with Redux toolkit is that so much happens in the createSlice function that needing to deviating from it a little feels like a whole new pattern to adopt.

It’s crystal clear how to write the foundation, but the hallmarks of a great pattern are that you know exactly how to / where to place every type of exception you run into long term.

Say we have a simple createSlice function:

const doSomething = CaseReducer = (state, action) => {
    state.didSomething = true
}
const slice = createSlice({
  name: 'mySlice',
  reducers: { doSomething }
})

// some-other-file
slice.actions.doSomething()

If in the future, imagine this slice relies on an action from another slice (say a detail page needs to update the list page content) and we end up with a circular import. slice A imports slice B and slice B imports slice A.

How do we convert a slice action out of the helper and into its own file?

// my-shared-action.ts
// move the shared action to its own file. You will need to create its action and reducer which createSlice did automatically
const doSomething = createAction(
  "mySlice/doSomething",
  (myArg) => ({payload: myArg}) 
)
const doSomethingReducer: <CaseReducer> = (state, action) => {
  state.didSomething = true
}

// sliceA.ts
const slice = createSlice({
  name: 'mySlice',
  reducers: { },
  extraReducers: (builder) => {
    builder.addCase(doSomething.toString(), doSomethingReducer)  
  }
})

// sliceB.ts
const slice = createSlice({
  name: 'mySliceB',
  reducers: { },
  extraReducers: (builder) => {
    builder.addCase(doSomething.toString(), doSomethingReducer)  
  }
})

See we convert the createSlice action+reducer into one created from scratch in another file my-shared-action.ts using createAction and a plain reducer function.

We then import that action/reducer into two different slices, and register their reducers in their respective extraReducers properties.

Redux Toolkit TypeScript createSlice Reducers in Different File

If you want to define your reducers in a separate file from you createSlice function and type it correctly, you need to type your state manually which was previously handled by createSlice.

We will need to create 2 files: one for your slice state type (to prevent future circular import issues), and one for your new reducer functions.

// slice.type.ts 
export type MySliceState {
   foo: string
}

Now we’ll make a reducer object in another file

// reducers.ts
import { CaseReducer } from "@reduxjs/toolkit";
import { MySliceState} from "./slice.type.ts";

const doSomething : CaseReducer<MySliceState> = (state, 
action:PayloadAction<{foo: string}>) => {
       // state is now typed to MySliceState
  }
export myReducers = {
  doSomething,
}
// mySlice.ts
export const photosSlice = createSlice({
  name: "mySlice",
  initialState: {} as MySliceState,
  reducers: {
    ...myReducers,
  },

M1 Mac / Legacy Python 2.7 Project Setup

I ran into a bunch of roadblocks on this one around virtual environments.

  • Create Rosetta terminal
  • Install homebrew
  • brew install pyenv
  • pyenv install –patch 2.7.16 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch)
  • the above patch was critical to prevent a zlib issue
  • next, the virtual env was non straight forward to get working
  • pyenv local 2.7.16
  • brew install pyenv-virtualenvwrapper
  • export PYENV_VIRTUALENVWRAPPER_PREFER_PYVENV=”true”
  • pyenv virtualenvwrapper
  • mkvirtualenv/workon <venv>