How To Setup OAuth Clients to Connect Your Oracle Cloud Autonomous Databases via REST

Oracle Cloud provides you about 40G always free Autonomous JSON Database. That's a lot for your personal learning or blog. Let's find a way to utilize the free space in your web application. This is a step by step to set up a OAuth Client to connect your Oracle Cloud Autonomous Databases.

Create a user account

ADMIN is the default user and it has the administrator permission to your database. You don't want to your application use ADMIN user to connect. It is recommended to create a separate user per web application.

As the ADMIN user, access Database Actions and create a user with the required privileges.



Remember select "UNLIMITED" as Quota on table space DATA if you are not sure the quota size of your JSON document.

Enable REST for the new created user

Switch Authorization required on for security concern

Sign out as the ADMIN user and Sign in to Database Actions as the new user that is setting up to use OAuth authentication.


Create OAuth Client

input client information

Grant Required Roles
Grant Privileges
You just created a new OAuth Client, you will get a client id and secret.

References



How to custom storage adapters to make your self-hosted Ghost instance filesystem completely external?

I set up my self-hosted Ghost on a free Google Compute Engine(a E2 micro GCP VM instance) several years ago.

The free disk after running a Ghost on the vm is only about 6G left, while

Ghost uses local file storage by default

In order to save the free space, I would like to seek a way to save images into external storage.

The above code section is based on this Ghost source commit.

After dive deep into Ghost open source, you can change the above /images/upload implementation and save the file to any external storages such as AWS s3.

Or you can follow this official config guide: https://ghost.org/docs/config/#creating-a-custom-storage-adapter

You can refer to this widely tested AWS s3 adapter.


My custom idea: try to use Oracle free 40G database to save images

I always like free storage. Oracle JSON database can give you 2 instances, 20G each.
In a word, Oracle give you 40G free database storage.
I am thinking custom the upload endpoint's implementation and save the image files into Oracle JSON database.

POST http://localhost:2368/ghost/api/admin/images/upload/


The response will be like below:
{"images":[{"url":"http://localhost:2368/api/admin/images/dbx/idx","ref":null}]}
dbx the Oracle json database instance(since Oracle gives 2 free instances).
idx the json document unique id saved into Oracle json database.

We need to provide a new endpoint to parse the above response url.
Since we save it in JSON format, while browser expects an image source url to return an image binary.

This is just a proposal, I will share the implementation once done.


I implemented the custom storage adapter and let it open source. See this post to find how I build up the storage adapter.






set up jest for your typescript project and how to import txt files in your unit tests

 

Getting Started

These instructions will get you setup to use ts-jest in your project. For more detailed documentation, please check online documentation.

using npmusing yarn
Prerequisitesnpm i -D jest typescriptyarn add --dev jest typescript
Installingnpm i -D ts-jest @types/jestyarn add --dev ts-jest @types/jest
Creating confignpx ts-jest config:inityarn ts-jest config:init
Running testsnpm t or npx jestyarn test or yarn jest


to import txt file as string, via jest-raw-loader

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
"transform": {
"\\.txt$": "jest-raw-loader"
}
};

or follow https://nextjs.org/docs/testing if you are using next.js


https://www.npmjs.com/package/jest-raw-loader

https://github.com/kulshekhar/ts-jest

https://jestjs.io/zh-Hans/docs/getting-started

https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object




Import txt files as string into your next.js App

 import file from './xxx.txt'

Webpack 5 has 'Asset Modules' to allow you to import assets without configuring loaders now.

Next.js use Webpack 5 internally, so we can use 'source assets' to import txt files as strings.

Two steps to let you be able to import a txt file as a string.

custom Webpack config for next.js


config.module.rules.push({
test: /\.txt$/i,
type: 'asset/source'
})

declare txt as a module for typescript

Wildcard module declarations can be used to cover these cases.

declare module '*.txt' {
const content: string;
export default content;
}

example

import t1 from './1.txt'
console.log(t1)

output

event - compiled successfully
离开罪之路的人蒙祝福,
他不去随从恶人的计谋,
他不会站在罪人的道路上,
也不去坐好讥笑人的座位,
他喜爱的是耶和华律法,
昼夜默诵的也是他律法。

The full commit to enabling import txt files in your next.js app


references

How to Internationalizing your Flutter apps ?


First Reading:


Steps:

1. add flutter_localizations dependencies into pubspec.yaml

dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter

2. add localizationsDelegates and supportedLocales into MaterialApp

Applocalizations.delegate is your app-specific localization delegate.
will be introduced in next step.

Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale.fromSubtags(languageCode: 'zh'), // generic Chinese 'zh'
const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hans'), // generic simplified Chinese 'zh_Hans'
const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant'), // generic traditional Chinese 'zh_Hant'
const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hans',
countryCode: 'CN'), // 'zh_Hans_CN'
const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant',
countryCode: 'TW'), // 'zh_Hant_TW'
const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant',
countryCode: 'HK'), // 'zh_Hant_HK'
const Locale('en', ''),
],

3. Defining your own class for the app's localized resources

import 'package:flutter/material.dart';

import 'app_localizations_delegate.dart';

class AppLocalizations {
AppLocalizations(this.locale);

final Locale locale;

static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}

static Map<String, Map<String, String>> _localizedValues = {
'zh': {
'appTitle': '海德堡要理问答',
},
'en': {
'appTitle': 'The Heidelberg Catechism',
},
};

String get appTitle {
return _localizedValues[locale.languageCode]['appTitle'];
}

static const LocalizationsDelegate<AppLocalizations> delegate =
AppLocalizationsDelegate();
}


import 'package:TheHeidelbergCatechism/i18n/app_localizations.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const AppLocalizationsDelegate();

@override
bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);

@override
Future<AppLocalizations> load(Locale locale) {
print(locale.languageCode);
return SynchronousFuture<AppLocalizations>(AppLocalizations(locale));
}

@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}

4. Use AppLocalizations

@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(AppLocalizations.of(context).appTitle),
),

Demo:


fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...