const util = require('util');
function d(...args) {
if (typeof (console) !== 'undefined') {
console.log('[Logging]', util.format(...args));
}
}
nodejs node.js console.log util.format ...args for logging log
For logging mulit args with "%O"
[轉]網站使用體驗三大核心指標 – LCP, FID, CLS
https://www.darrenhuang.com/core-web-vitals-lcp-fid-cls.html?fbclid=IwAR2-n-h0j-BR73sD4Vsino1ObtjDyVe3xkhNcs7xmtcn14Kk84rWO-06lPs
瀏覽器插件
這是官方出的Chrome挿件,能夠在瀏覽時即時回報該網頁的LCP, FID, CLS。
nodejs express cache redis
https://sematext.com/blog/expressjs-best-practices/
const express = require('express')
const app = express()
const redis = require('redis')
const redisClient = redis.createClient(6379)
async function getSomethingFromDatabase (req, res, next) {
try {
const { id } = req.params;
const data = await database.query()
// Set data to Redis
redisClient.setex(id, 3600, JSON.stringify(data))
res.status(200).send(data)
} catch (err) {
console.error(err)
res.status(500)
}
}
function cache (req, res, next) {
const { id } = req.params
redisClient.get(id, (err, data) => {
if (err) {
return res.status(500).send(err)
}
// If data exists return the cached value
if (data != null) {
return res.status(200).send(data)
}
// If data does not exist, proceed to the getSomethingFromDatabase function
next()
})
}
app.get('/data/:id', cache, getSomethingFromDatabase)
app.listen(3000, () => console.log(`Server running on Port ${port}`))
vs code 無法使用eslint
In personal setting.json for vs code
"eslint.workingDirectories": [
{ "mode": "auto" }
],
Promise.all map
const arr = {};
await Promise.all(
UsersQuery.map(async function (data) {
const city = await db.sequelize.query(`
select * from city
`,
type: db.sequelize.QueryTypes.SELECT
});
arr[data.user_id] = city[0].name;
})
}
UsersQuery.forEach(async function (data, index) {
this[index].name = arr[data.user_id];
}, UsersQuery);
sqlmap
docker https://hub.docker.com/r/googlesky/sqlmap
執行指令:
docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap -h
GET
docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap --url='https://test.com/date=2020-04-01' --level=5 --risk=3
POST & header token
docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap --url='http://oo.xx.oo.xx:5000/user/info' --headers='Authorization: bearer eyJhbGcoooooxxxxxoooooxx......' --data='{id: "u123"}' --level=5 --risk=3
nodejs moment moment-timezone
Use express, moment, moment-timezone
Server timezone 0
Client time zone +8
Server run result:
Client run result:
const moment = require('moment-timezone');
app.get('/moment', (req, res) => {
const datestr = '2020-07-01';
res.status(200).json({
local_offset: moment(datestr).utc(),
local_unix: moment(datestr).unix(),
zone0_unix: moment(datestr).zone(0).unix(),
zone8_unix: moment(datestr).zone(8).unix(),
timezone0_unix: moment.tz(datestr, 'GMT').unix(),
timezone8_unix: moment.tz(datestr, 'Asia/Taipei').unix(),
});
});
// No use, just for keep
function dateForTimezone(offset, d) {
// Copy date if supplied or use current
d = d? new Date(+d) : new Date();
// Use supplied offset or system
offset = offset || -d.getTimezoneOffset();
// Prepare offset values
var offSign = offset < 0? '-' : '+';
offset = Math.abs(offset);
var offHours = ('0' + (offset/60 | 0)).slice(-2);
var offMins = ('0' + (offset % 60)).slice(-2);
// Apply offset to d
d.setUTCMinutes(d.getUTCMinutes() - offset);
return offSign + offHours + ':' + offMins;
// Return formatted string
return d.getUTCFullYear() +
'-' + ('0' + (d.getUTCMonth()+1)).slice(-2) +
'-' + ('0' + d.getUTCDate()).slice(-2) +
'T' + ('0' + d.getUTCHours()).slice(-2) +
':' + ('0' + d.getUTCMinutes()).slice(-2) +
':' + ('0' + d.getUTCSeconds()).slice(-2) +
'.' + ('000' + d.getUTCMilliseconds()).slice(-3) +
offSign + offHours + ':' + offMins;
}
IMPORT
Server timezone 0
Client time zone +8
Server run result:
{
"local_offset": "2020-06-30T16:00:00.000Z",
"local_unix": 1593532800,
"zone0_unix": 1593532800,
"zone8_unix": 1593532800,
"timezone0_unix": 1593561600,
"timezone8_unix": 1593532800
}
Client run result:
{
"local_offset": "2020-07-01T00:00:00.000Z",
"local_unix": 1593561600,
"zone0_unix": 1593561600,
"zone8_unix": 1593561600,
"timezone0_unix": 1593561600,
"timezone8_unix": 1593532800
}
Conclusion
moment().zone().unix() Auto fix zone / utc
moment("").tz("GMT").unix() Auto fix zone / utc
moment().tz("", "GMT").unix() No auto fix zone / utc
typeorm connection
const typeorm = require("typeorm");
const connectionManager = require("typeorm").getConnectionManager();
//const connectionManager = typeorm.getConnectionManager();
const connected = connectionManager.has("default");
if(!connected){
// ? load connection options from ormconfig or environment
//const connectionOptions = await getConnectionOptions();
connectionManager.create({
//name: "default",
type: "mysql",
// "extra": {
// "socketPath": "/cloudsql/ooxxooxx"
// },
host: "oo.xx.oo.xx",
port: 3306,
username: "root",
password: "ooxxooxx",
database: "ooxxdb",
synchronize: false,
logging: true, // this.env === 'dev' ? true : false
ssl: SSL,
keepConnectionAlive: false,
});
}
try {
db = connectionManager.get();
if(!connected){
await db.connect();
console.log('connect .... OK!');
}
}catch(error) {
console.log("TypeORM Error: ", error);
};
var ranks = await db.query("select * from users");
Sequelize 基本認識
# Sequelize 基本認識
## 1. Timestamps
https://sequelize.org/v5/manual/models-definition.html#timestamps
## 2. Database synchronization
https://sequelize.org/v5/manual/models-definition.html#database-synchronization
建議不要直接使用於正式環境,應該在測試建立後,取得對應 sql 碼後,在正式上線時,手動更新正式 DB 資料結構
**2.1** 使用 sync 建立的 table name 會加上 s
**2.2** 正常情況下,對 table 操作盡可能還是已手動為主,雖然 Sequelize 有提供一些操作,但減少使用比較安全,當手動操作完畢後,應該把 raw sql 匯出備份,正式上線時,再手動更新
## 3. Modeling a table 建立
https://sequelize.org/v5/manual/getting-started.html
```
const Model = Sequelize.Model;
class User extends Model {}
User.init({
```
建議使用
```
sequelize.define:'user', {
// attributes
firstName: {
```
原因,看起來簡單多了
3.1 Model 操作
https://sequelize.org/v5/manual/models-usage.html
## 4. Raw queries
https://sequelize.org/v5/manual/raw-queries.html
基本當join比較複雜建議使用,因為清楚、效率可控,或更複雜的 sub sql 都可以進行,避免 ORM 處理不當,造成效能大幅下降
**4.1** 回傳是 [results, metadata]
**4.2** 有使用參數情況下,務必使用 Replacements 千萬不要直接raw sql + 參數
## 1. Timestamps
https://sequelize.org/v5/manual/models-definition.html#timestamps
## 2. Database synchronization
https://sequelize.org/v5/manual/models-definition.html#database-synchronization
建議不要直接使用於正式環境,應該在測試建立後,取得對應 sql 碼後,在正式上線時,手動更新正式 DB 資料結構
**2.1** 使用 sync 建立的 table name 會加上 s
**2.2** 正常情況下,對 table 操作盡可能還是已手動為主,雖然 Sequelize 有提供一些操作,但減少使用比較安全,當手動操作完畢後,應該把 raw sql 匯出備份,正式上線時,再手動更新
## 3. Modeling a table 建立
https://sequelize.org/v5/manual/getting-started.html
```
const Model = Sequelize.Model;
class User extends Model {}
User.init({
```
建議使用
```
sequelize.define:'user', {
// attributes
firstName: {
```
原因,看起來簡單多了
3.1 Model 操作
https://sequelize.org/v5/manual/models-usage.html
## 4. Raw queries
https://sequelize.org/v5/manual/raw-queries.html
基本當join比較複雜建議使用,因為清楚、效率可控,或更複雜的 sub sql 都可以進行,避免 ORM 處理不當,造成效能大幅下降
**4.1** 回傳是 [results, metadata]
**4.2** 有使用參數情況下,務必使用 Replacements 千萬不要直接raw sql + 參數
西方式傲慢
西方式傲慢 https://youtu.be/-3lqr6Ys_zQ?t=697
中國為西方贏得時間,西方卻浪費了它 張彥
https://cn.nytimes.com/opinion/20200314/china-response-china/zh-hant/
普立茲獎 張彥
https://zh.wikipedia.org/zh-tw/%E5%BC%A0%E5%BD%A6_(%E7%BE%8E%E5%9B%BD%E8%AE%B0%E8%80%85)
連 柳葉刀的主編 中國傳遞了非常清淅的訊息,可是我們浪費了整整2個月
https://news.sina.com.tw/article/20200401/34733366.html
https://www.facebook.com/watch/?v=538201007134058
中國為西方贏得時間,西方卻浪費了它 張彥
https://cn.nytimes.com/opinion/20200314/china-response-china/zh-hant/
普立茲獎 張彥
https://zh.wikipedia.org/zh-tw/%E5%BC%A0%E5%BD%A6_(%E7%BE%8E%E5%9B%BD%E8%AE%B0%E8%80%85)
連 柳葉刀的主編 中國傳遞了非常清淅的訊息,可是我們浪費了整整2個月
https://news.sina.com.tw/article/20200401/34733366.html
https://www.facebook.com/watch/?v=538201007134058
[轉]Go 交叉編譯
https://ithelp.ithome.com.tw/articles/10225188
在Windows上編譯
To MacOs
To Linux
To Windows ???
在Linux上編譯
在Windows上編譯
To MacOs
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go
To Linux
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go
To Windows ???
go build main.go
在Linux上編譯
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
javascript firestore object sort
const bookListsQuery = await modules.firestore.collection('books')
.get();
const sortedObj = Object.values(bookListsQuery.docs).sort(function(a, b){
console.log('a %s b %s', a.data().order, b.data().order)
return Number(a.data().order) > Number(b.data().order);
});
sortedObj.forEach(function(doc){
console.log(doc.data())
});
other way
object use map to array, then it sorted.
const bookListsQuery = await modules.firestore.collection('books')
.get();
const sortedArr = bookListsQuery.docs.map(function (doc) { // 轉換成array
return doc.data()
});
sortedArr.sort(function compare(a, b) {
return a.order > b.order; // 升 小->大
});
sortedArr.forEach(function(data){
console.log(data.data())
})
==========
Sorting multiple object properties with JavaScript
https://bithacker.dev/javascript-object-multi-property-sort
let students = [{
firstName: 'John',
lastName: 'Appletree',
grade: 12
},{
firstName: 'Mighty',
lastName: 'Peachtree',
grade: 10
},{
firstName: 'Kim',
lastName: 'Appletree',
grade: 11
},{
firstName: 'Shooter',
lastName: 'Appletree',
grade: 12
}];
let sortBy = [{
prop:'grade',
direction: -1
},{
prop:'lastName',
direction: 1
}];
array.sort(function(a,b){
let i = 0, result = 0;
while(i < sortBy.length && result === 0) {
result = sortBy[i].direction*(a[ sortBy[i].prop ].toString() < b[ sortBy[i].prop ].toString() ? -1 : (a[ sortBy[i].prop ].toString() > b[ sortBy[i].prop ].toString() ? 1 : 0));
i++;
}
return result;
})
fb 中研院研究出快篩試劑
漂亮的諧音 https://www.youtube.com/channel/UCRSmPITY7izy2F1INKMEf2g
13 小時前
中研院研究出快篩試劑,
綠媒大肆吹捧,
817們高潮連連,
綠媒說根本是大陸搶了台灣的研究功勞,
結果人家那是2月的事,
如何搶台灣3月研發出來的成果功勞?
(原來中國有坐時光機穿越未來,
抄襲台灣研究成果的能力啊)
。。。
接著衛福部被抓包,
2月就核准進口大陸快篩試劑,
但衛福部辯解說進口的是抗體試劑,
中研院研發的是抗原試劑,
(既然兩者快篩試劑不同,
那白痴綠媒說大陸搶了台灣研究功勞,
這是什麼毛病?
反正只要政治正確,
造謠就沒問題是嘛!?)
。。。
那中研院的快篩試劑何時可量產?
中研院長回覆說:
『此一問題「難以回答」。
做試劑不能為了趕進度忽略靈敏性與準確度。
而快篩何時人體試驗、量產,
都必須與衛福部、廠商密切合作,
時間難以預估。
「即使今年用不上,
也必須為未來的疫情做準備。」』
。。。
所以817在高潮一個,
根本還無法真正問世的東西。
台灣現在就是腦殘當道啊!
13 小時前
中研院研究出快篩試劑,
綠媒大肆吹捧,
817們高潮連連,
綠媒說根本是大陸搶了台灣的研究功勞,
結果人家那是2月的事,
如何搶台灣3月研發出來的成果功勞?
(原來中國有坐時光機穿越未來,
抄襲台灣研究成果的能力啊)
。。。
接著衛福部被抓包,
2月就核准進口大陸快篩試劑,
但衛福部辯解說進口的是抗體試劑,
中研院研發的是抗原試劑,
(既然兩者快篩試劑不同,
那白痴綠媒說大陸搶了台灣研究功勞,
這是什麼毛病?
反正只要政治正確,
造謠就沒問題是嘛!?)
。。。
那中研院的快篩試劑何時可量產?
中研院長回覆說:
『此一問題「難以回答」。
做試劑不能為了趕進度忽略靈敏性與準確度。
而快篩何時人體試驗、量產,
都必須與衛福部、廠商密切合作,
時間難以預估。
「即使今年用不上,
也必須為未來的疫情做準備。」』
。。。
所以817在高潮一個,
根本還無法真正問世的東西。
台灣現在就是腦殘當道啊!
[轉]Keep your promises when using Cloud Functions for Firebase!
https://firebase.googleblog.com/2017/06/keep-your-promises-when-using-cloud.html?fbclid=IwAR2FuvlU2CbwjV-I75q7-WIkJyLHRYT-R3cyleEUWF3Fsq42THMCwZN6by8
==========
https://stackoverflow.com/questions/55430079/promise-all-does-not-wait-for-firestore-query-to-loop
const ref_p1_state = root.child(`player_states/${game_state.p1uid}`)
const ref_p2_state = root.child(`player_states/${game_state.p2uid}`)
const pr_update_p1 = ref_p1_state.update(update_p1)
const pr_update_p2 = ref_p2_state.update(update_p2)
return Promise.all([pr_update_p1, pr_update_p2])
==========
https://stackoverflow.com/questions/55430079/promise-all-does-not-wait-for-firestore-query-to-loop
nodexjs expressjs ajv apidoc converter generator restclient curl postman
ajv schema to apidoc schema
https://github.com/willfarrell/apidoc-plugin-schema
required can't product doc.
converter
https://github.com/apidoc/apidoc#converter
to swagger
https://github.com/fsbahman/apidoc-swagger
postman collection to apidoc
https://github.com/bonzzy/docmaster
RestClient -> curl -> postman
https://github.com/willfarrell/apidoc-plugin-schema
required can't product doc.
converter
https://github.com/apidoc/apidoc#converter
to swagger
https://github.com/fsbahman/apidoc-swagger
postman collection to apidoc
https://github.com/bonzzy/docmaster
RestClient -> curl -> postman
promise.all error catch
https://stackoverflow.com/questions/30362733/handling-errors-in-promise-all
Alternately, if you have a case where you don't particularly care about the values of the resolved promises when there is one failure but you still want them to have run, you could do something like this which will resolve with the promises as normal when they all succeed and reject with the failed promises when any of them fail:
Promise.all(state.routes.map(function(route) {
return route.handler.promiseHandler().catch(function(err) {
return err;
});
}))
.then(function(arrayOfValuesOrErrors) {
// handling of my array containing values and/or errors.
})
.catch(function(err) {
console.log(err.message); // some coding error in handling happened
});
Alternately, if you have a case where you don't particularly care about the values of the resolved promises when there is one failure but you still want them to have run, you could do something like this which will resolve with the promises as normal when they all succeed and reject with the failed promises when any of them fail:
function promiseNoReallyAll (promises) {
return new Promise(
async (resolve, reject) => {
const failedPromises = []
const successfulPromises = await Promise.all(
promises.map(
promise => promise.catch(error => {
failedPromises.push(error)
})
)
)
if (failedPromises.length) {
reject(failedPromises)
} else {
resolve(successfulPromises)
}
}
)
}
訂閱:
文章 (Atom)