Disable the master and then you enable “anywhere” in Security & Privacy.
sudo spctl --master-disable
Regenerate the signatures for this application.
sudo codesign --sign - --force --deep /your/application-path.app
Disable the master and then you enable “anywhere” in Security & Privacy.
sudo spctl --master-disable
Regenerate the signatures for this application.
sudo codesign --sign - --force --deep /your/application-path.app
Found a nice and tidy way to add custom headers to the rewrites proxy if you know next.config.js well.
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export const config = {
matcher: '/product/:path',
};
// Proxies /product/:id to https://my-proxied-site.com/product/:id
export function middleware(request: NextRequest) {
const requestHeaders = new Headers(request.headers);
requestHeaders.set('Authorization', 'Bearer ******');
// Extract product id from pathname
const [, , id] = request.nextUrl.pathname.split('/');
request.nextUrl.href = `https://vercel.com/product/${id}`;
return NextResponse.rewrite(request.nextUrl, {
request: {
headers: requestHeaders,
},
});
}
A idea from Github: https://github.com/vercel/next.js/discussions/19078
An example of a Next.js app that uses React Query for server-side data fetching and client-side caching:
import { GetServerSideProps } from 'next';
import { QueryClient, QueryClientProvider, useQuery } from 'react-query';
import { dehydrate } from 'react-query/hydration';
type Post = {
id: number;
title: string;
body: string;
};
type PageProps = {
posts: Post[];
};
const fetchPosts = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
return data;
};
const Posts = () => {
const { data: posts } = useQuery<Post[]>('posts', fetchPosts);
return (
<div>
{posts.map((post) => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</div>
))}
</div>
);
};
export const getServerSideProps: GetServerSideProps<PageProps> = async () => {
const queryClient = new QueryClient();
await queryClient.prefetchQuery('posts', fetchPosts);
return {
props: {
posts: dehydrate(queryClient),
},
};
};
export default function Home(props: PageProps) {
return (
<QueryClientProvider client={new QueryClient()}>
<Posts />
</QueryClientProvider>
);
}
This example demonstrates how to use the useQuery hook and QueryClient to fetch data from an API. We also use the dehydrate function to serialize the data in the query cache and pass it to the client for hydration.
In the getServerSideProps function, we prefetch the data using queryClient.prefetchQuery and pass the serialized data to the page component via the props object.
To render the component on the client, we use QueryClientProvider to provide a new QueryClient instance.
With this setup, the data will be fetched and cached on the server, and then hydrated on the client, allowing for smooth client-side rendering with minimal data fetching.
Note that this example uses the jsonplaceholder API for demonstration purposes only. In a real application, you would replace the API URL and data fetching function with your own API endpoint and data fetching logic.
Hydrating the QueryClient with server-side pre-fetched data is a strategy that can be used to improve the performance of your application and reduce the load on your API. This technique can be particularly useful in scenarios where you are using server-side rendering, have frequently changing data, or are using optimistic updates.
When using server-side rendering (SSR), hydrating the QueryClient with server-side pre-fetched data is essential. This strategy can help improve the performance of your application and reduce the number of requests to your API. By reusing the pre-fetched data on the client-side, you can avoid making additional requests to the API, which improves the perceived performance of your application. With this technique, you can ensure that your application is faster and more responsive, giving your users a better experience.
If you have frequently changing data that needs to be fetched on every request, hydrating the QueryClient with server-side pre-fetched data can help ensure that the data is up-to-date and accurate. By pre-fetching the data on the server-side, you can avoid the latency of making requests to the API on the client-side. This technique can help improve the reliability of your application and reduce the likelihood of errors occurring due to stale data (Outdated data).
When using optimistic updates, hydrating the QueryClient with server-side pre-fetched data can be extremely useful. This strategy can help ensure that the updated data is available immediately after the update. This can reduce the likelihood of inconsistencies or flickering in your application, which can be disruptive to the user experience.
Overall, hydrating the QueryClient with server-side pre-fetched data is a powerful tool that can help improve the performance and reliability of your application while reducing the load on your API. By taking advantage of this feature provided by React Query and Next.js, you can ensure that your application is fast, responsive, and reliable, giving your users the best possible experience.
Next.js is a popular React framework for building server-side rendered web applications. It provides a simple and intuitive API for handling server-side rendering, static site generation, and dynamic routing. React Query, on the other hand, is a powerful data fetching and caching library for React applications. In this blog post, we will explore how Next.js and React Query can work together to create performant and efficient web applications.
Next.js makes it easy to build server-side rendered applications using React. With Next.js, you can create pages that are pre-rendered at build time, and pages that are rendered on the server on-demand. This allows your web application to respond quickly to user requests, without sacrificing the benefits of React’s component-based architecture.
React Query is a data fetching and caching library that simplifies the process of retrieving data from APIs. It provides a simple and intuitive API for fetching data, caching it, and managing the state of your application. React Query also includes built-in support for error handling, pagination, and caching.
By combining Next.js and React Query, you can create web applications that are both fast and efficient. Next.js provides a powerful server-side rendering API, allowing you to pre-render pages and improve performance. React Query provides a simple and efficient way to fetch and manage data, improving the overall user experience.
One of the key benefits of using Next.js with React Query is the ability to prefetch data. Next.js includes a feature called “automatic static optimization” that allows you to prefetch data for static pages. By using React Query to fetch this data, you can ensure that your pages load quickly and efficiently, without any additional network requests.
Another benefit of using Next.js with React Query is improved error handling. React Query includes built-in support for handling errors, allowing you to easily manage and display error messages to users. This can be particularly useful when building complex web applications that require data fetching from multiple APIs.
In addition to server-side rendering, Next.js also supports static site generation. This allows you to generate HTML files for your pages at build time, which can then be served directly from a CDN. Static site generation can significantly improve the performance of your web application, as it eliminates the need to dynamically generate pages on the server.
With Next.js and React Query, you can take advantage of static site generation to further improve the performance of your application. By prefetching data at build time using React Query, you can ensure that your pages load quickly and efficiently, even when served from a static file.
In addition to server-side rendering and static site generation, Next.js also supports client-side rendering. This allows you to create dynamic web applications that are rendered entirely in the browser. With client-side rendering, you can provide a more responsive and interactive user experience, without sacrificing the benefits of server-side rendering.
React Query is well-suited for client-side rendering, as it provides a simple and efficient way to fetch and cache data from APIs. By using React Query with Next.js, you can create web applications that are both fast and responsive, with minimal network requests and efficient data caching.
In conclusion, Next.js and React Query are a powerful combination for building web applications that are both fast and efficient. With support for server-side rendering, static site generation, and client-side rendering, Next.js provides a flexible and intuitive API for building performant web applications. React Query simplifies the process of fetching and caching data, improving the overall user experience. By using these two libraries together, you can create web applications that are fast, responsive, and easy to maintain.
const dateStr = '2023-02-22'
const dateFormat = 'yyyy-MM-dd'
const newDate = format(new Date(dateStr))
const parsedDate = format(parse(dateStr, dateFormat, new Date()))
It’s quite an exciting thing that I found recently. parse
function in date-fns
is doing a kind of “character for-loop” to match the date format that you provided and then adjusting the timezone offset for you. This is why it’s the main reason why the date newDate
and parsedDate
are getting created differently.
function parse(dateString, formatString, referenceDate) {
const formatParts = formatString.split(/[\s-/:]+/);
const dateParts = dateString.split(/[\s-/:]+/);
let year, month, day, hour, minute, second;
for (let i = 0; i < formatParts.length; i++) {
const formatPart = formatParts[i];
const datePart = dateParts[i];
if (formatPart === 'yyyy') {
year = parseInt(datePart, 10);
} else if (formatPart === 'MM') {
month = parseInt(datePart, 10) - 1;
} else if (formatPart === 'dd') {
day = parseInt(datePart, 10);
} else if (formatPart === 'HH') {
hour = parseInt(datePart, 10);
} else if (formatPart === 'mm') {
minute = parseInt(datePart, 10);
} else if (formatPart === 'ss') {
second = parseInt(datePart, 10);
}
}
console.log(year, month, day, hour, minute, second);
const date = new Date(year, month, day, hour, minute, second);
if (referenceDate) {
const timeZoneOffset = referenceDate.getTimezoneOffset();
const referenceTimestamp = referenceDate.getTime();
return new Date(referenceTimestamp + timeZoneOffset * 60 * 1000);
}
return date;
}
// Working one
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": false,
"removeComments": true,
"strict": true,
"target": "es6"
},
"include": ["src"],
"exclude": ["node_modules"]
}
// Broken one
{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./src",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": false,
"removeComments": true,
"strict": true,
"target": "es6"
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Something interesting that I found. Be careful when you are “playing” with the param baseUrl
and include
. It might show the message Compiling with Typescript…
but it’s not compiling anything because you are in the folder with a path like ./src/src
.
1. Login with the command below.
ipatool auth login -e [email protected] -p YourPassword.123
2. Search the app meta that you want to download.
ipatool search microsoft authenticator
//9:52AM INF apps=[{"bundleID":"com.microsoft.azureauthenticator","id":983156458,"name":"Microsoft Authenticator","price":0,"version":"6.7.3"},{"bundleID":"com.google.Authenticator","id":388497605,"name":"Google Authenticator","price":0,"version":"3.4.0"},{"bundleID":"me.mattrubin.authenticator","id":766157276,"name":"Authenticator","price":0,"version":"2.1.2"},{"bundleID":"com.salesforce.authenticator1","id":782057975,"name":"Salesforce Authenticator","price":0,"version":"3.11.1"},{"bundleID":"com.2stable.2fa","id":1538761576,"name":"Authenticator App","price":0,"version":"3.18.1"}] count=5
3. Download the app with the bundleID
by using –bundle-identifier and specifying the path for saving the IPA file with --output /your-path/MicrosoftAuth.ipa
ipatool download --bundle-identifier com.microsoft.azureauthenticator --output /your-path/MicrosoftAuth.ipa
#arch to x86
function archx86 {
if [ $(arch) = "arm64" ];
then
exec arch -x86_64 $SHELL
fi
}
#arch to arm
function archarm {
if [ $(arch) = "i386" ];
then
exec arch -arm64 $SHELL
fi
}