{"id":"553f6768-8bf2-4247-ae67-893cc2580b3f","shortId":"5x5BZW","kind":"skill","title":"azure-postgres-ts","tagline":"Connect to Azure Database for PostgreSQL Flexible Server from Node.js/TypeScript using the pg (node-postgres) package.","description":"# Azure PostgreSQL for TypeScript (node-postgres)\n\nConnect to Azure Database for PostgreSQL Flexible Server using the `pg` (node-postgres) package with support for password and Microsoft Entra ID (passwordless) authentication.\n\n## Installation\n\n```bash\nnpm install pg @azure/identity\nnpm install -D @types/pg\n```\n\n## Environment Variables\n\n```bash\n# Required\nAZURE_POSTGRESQL_HOST=<server>.postgres.database.azure.com\nAZURE_POSTGRESQL_DATABASE=<database>\nAZURE_POSTGRESQL_PORT=5432\n\n# For password authentication\nAZURE_POSTGRESQL_USER=<username>\nAZURE_POSTGRESQL_PASSWORD=<password>\n\n# For Entra ID authentication\nAZURE_POSTGRESQL_USER=<entra-user>@<server>   # e.g., user@contoso.com\nAZURE_POSTGRESQL_CLIENTID=<managed-identity-client-id>  # For user-assigned identity\n```\n\n## Authentication\n\n### Option 1: Password Authentication\n\n```typescript\nimport { Client, Pool } from \"pg\";\n\nconst client = new Client({\n  host: process.env.AZURE_POSTGRESQL_HOST,\n  database: process.env.AZURE_POSTGRESQL_DATABASE,\n  user: process.env.AZURE_POSTGRESQL_USER,\n  password: process.env.AZURE_POSTGRESQL_PASSWORD,\n  port: Number(process.env.AZURE_POSTGRESQL_PORT) || 5432,\n  ssl: { rejectUnauthorized: true }  // Required for Azure\n});\n\nawait client.connect();\n```\n\n### Option 2: Microsoft Entra ID (Passwordless) - Recommended\n\n```typescript\nimport { Client, Pool } from \"pg\";\nimport { DefaultAzureCredential } from \"@azure/identity\";\n\n// For system-assigned managed identity\nconst credential = new DefaultAzureCredential();\n\n// For user-assigned managed identity\n// const credential = new DefaultAzureCredential({\n//   managedIdentityClientId: process.env.AZURE_POSTGRESQL_CLIENTID\n// });\n\n// Acquire access token for Azure PostgreSQL\nconst tokenResponse = await credential.getToken(\n  \"https://ossrdbms-aad.database.windows.net/.default\"\n);\n\nconst client = new Client({\n  host: process.env.AZURE_POSTGRESQL_HOST,\n  database: process.env.AZURE_POSTGRESQL_DATABASE,\n  user: process.env.AZURE_POSTGRESQL_USER,  // Entra ID user\n  password: tokenResponse.token,             // Token as password\n  port: Number(process.env.AZURE_POSTGRESQL_PORT) || 5432,\n  ssl: { rejectUnauthorized: true }\n});\n\nawait client.connect();\n```\n\n## Core Workflows\n\n### 1. Single Client Connection\n\n```typescript\nimport { Client } from \"pg\";\n\nconst client = new Client({\n  host: process.env.AZURE_POSTGRESQL_HOST,\n  database: process.env.AZURE_POSTGRESQL_DATABASE,\n  user: process.env.AZURE_POSTGRESQL_USER,\n  password: process.env.AZURE_POSTGRESQL_PASSWORD,\n  port: 5432,\n  ssl: { rejectUnauthorized: true }\n});\n\ntry {\n  await client.connect();\n  \n  const result = await client.query(\"SELECT NOW() as current_time\");\n  console.log(result.rows[0].current_time);\n} finally {\n  await client.end();  // Always close connection\n}\n```\n\n### 2. Connection Pool (Recommended for Production)\n\n```typescript\nimport { Pool } from \"pg\";\n\nconst pool = new Pool({\n  host: process.env.AZURE_POSTGRESQL_HOST,\n  database: process.env.AZURE_POSTGRESQL_DATABASE,\n  user: process.env.AZURE_POSTGRESQL_USER,\n  password: process.env.AZURE_POSTGRESQL_PASSWORD,\n  port: 5432,\n  ssl: { rejectUnauthorized: true },\n  \n  // Pool configuration\n  max: 20,                    // Maximum connections in pool\n  idleTimeoutMillis: 30000,   // Close idle connections after 30s\n  connectionTimeoutMillis: 10000  // Timeout for new connections\n});\n\n// Query using pool (automatically acquires and releases connection)\nconst result = await pool.query(\"SELECT * FROM users WHERE id = $1\", [userId]);\n\n// Explicit checkout for multiple queries\nconst client = await pool.connect();\ntry {\n  const res1 = await client.query(\"SELECT * FROM users\");\n  const res2 = await client.query(\"SELECT * FROM orders\");\n} finally {\n  client.release();  // Return connection to pool\n}\n\n// Cleanup on shutdown\nawait pool.end();\n```\n\n### 3. Parameterized Queries (Prevent SQL Injection)\n\n```typescript\n// ALWAYS use parameterized queries - never concatenate user input\nconst userId = 123;\nconst email = \"user@example.com\";\n\n// Single parameter\nconst result = await pool.query(\n  \"SELECT * FROM users WHERE id = $1\",\n  [userId]\n);\n\n// Multiple parameters\nconst result = await pool.query(\n  \"INSERT INTO users (email, name, created_at) VALUES ($1, $2, NOW()) RETURNING *\",\n  [email, \"John Doe\"]\n);\n\n// Array parameter\nconst ids = [1, 2, 3, 4, 5];\nconst result = await pool.query(\n  \"SELECT * FROM users WHERE id = ANY($1::int[])\",\n  [ids]\n);\n```\n\n### 4. Transactions\n\n```typescript\nconst client = await pool.connect();\n\ntry {\n  await client.query(\"BEGIN\");\n  \n  const userResult = await client.query(\n    \"INSERT INTO users (email) VALUES ($1) RETURNING id\",\n    [\"user@example.com\"]\n  );\n  const userId = userResult.rows[0].id;\n  \n  await client.query(\n    \"INSERT INTO orders (user_id, total) VALUES ($1, $2)\",\n    [userId, 99.99]\n  );\n  \n  await client.query(\"COMMIT\");\n} catch (error) {\n  await client.query(\"ROLLBACK\");\n  throw error;\n} finally {\n  client.release();\n}\n```\n\n### 5. Transaction Helper Function\n\n```typescript\nasync function withTransaction<T>(\n  pool: Pool,\n  fn: (client: PoolClient) => Promise<T>\n): Promise<T> {\n  const client = await pool.connect();\n  try {\n    await client.query(\"BEGIN\");\n    const result = await fn(client);\n    await client.query(\"COMMIT\");\n    return result;\n  } catch (error) {\n    await client.query(\"ROLLBACK\");\n    throw error;\n  } finally {\n    client.release();\n  }\n}\n\n// Usage\nconst order = await withTransaction(pool, async (client) => {\n  const user = await client.query(\n    \"INSERT INTO users (email) VALUES ($1) RETURNING *\",\n    [\"user@example.com\"]\n  );\n  const order = await client.query(\n    \"INSERT INTO orders (user_id, total) VALUES ($1, $2) RETURNING *\",\n    [user.rows[0].id, 99.99]\n  );\n  return order.rows[0];\n});\n```\n\n### 6. Typed Queries with TypeScript\n\n```typescript\nimport { Pool, QueryResult } from \"pg\";\n\ninterface User {\n  id: number;\n  email: string;\n  name: string;\n  created_at: Date;\n}\n\n// Type the query result\nconst result: QueryResult<User> = await pool.query<User>(\n  \"SELECT * FROM users WHERE id = $1\",\n  [userId]\n);\n\nconst user: User | undefined = result.rows[0];\n\n// Type-safe insert\nasync function createUser(\n  pool: Pool,\n  email: string,\n  name: string\n): Promise<User> {\n  const result = await pool.query<User>(\n    \"INSERT INTO users (email, name) VALUES ($1, $2) RETURNING *\",\n    [email, name]\n  );\n  return result.rows[0];\n}\n```\n\n## Pool with Entra ID Token Refresh\n\nFor long-running applications, tokens expire and need refresh:\n\n```typescript\nimport { Pool, PoolConfig } from \"pg\";\nimport { DefaultAzureCredential, AccessToken } from \"@azure/identity\";\n\nclass AzurePostgresPool {\n  private pool: Pool | null = null;\n  private credential: DefaultAzureCredential;\n  private tokenExpiry: Date | null = null;\n  private config: Omit<PoolConfig, \"password\">;\n\n  constructor(config: Omit<PoolConfig, \"password\">) {\n    this.credential = new DefaultAzureCredential();\n    this.config = config;\n  }\n\n  private async getToken(): Promise<string> {\n    const tokenResponse = await this.credential.getToken(\n      \"https://ossrdbms-aad.database.windows.net/.default\"\n    );\n    this.tokenExpiry = new Date(tokenResponse.expiresOnTimestamp);\n    return tokenResponse.token;\n  }\n\n  private isTokenExpired(): boolean {\n    if (!this.tokenExpiry) return true;\n    // Refresh 5 minutes before expiry\n    return new Date() >= new Date(this.tokenExpiry.getTime() - 5 * 60 * 1000);\n  }\n\n  async getPool(): Promise<Pool> {\n    if (this.pool && !this.isTokenExpired()) {\n      return this.pool;\n    }\n\n    // Close existing pool if token expired\n    if (this.pool) {\n      await this.pool.end();\n    }\n\n    const token = await this.getToken();\n    this.pool = new Pool({\n      ...this.config,\n      password: token\n    });\n\n    return this.pool;\n  }\n\n  async query<T>(text: string, params?: any[]): Promise<QueryResult<T>> {\n    const pool = await this.getPool();\n    return pool.query<T>(text, params);\n  }\n\n  async end(): Promise<void> {\n    if (this.pool) {\n      await this.pool.end();\n      this.pool = null;\n    }\n  }\n}\n\n// Usage\nconst azurePool = new AzurePostgresPool({\n  host: process.env.AZURE_POSTGRESQL_HOST!,\n  database: process.env.AZURE_POSTGRESQL_DATABASE!,\n  user: process.env.AZURE_POSTGRESQL_USER!,\n  port: 5432,\n  ssl: { rejectUnauthorized: true },\n  max: 20\n});\n\nconst result = await azurePool.query(\"SELECT NOW()\");\n```\n\n## Error Handling\n\n```typescript\nimport { DatabaseError } from \"pg\";\n\ntry {\n  await pool.query(\"INSERT INTO users (email) VALUES ($1)\", [email]);\n} catch (error) {\n  if (error instanceof DatabaseError) {\n    switch (error.code) {\n      case \"23505\":  // unique_violation\n        console.error(\"Duplicate entry:\", error.detail);\n        break;\n      case \"23503\":  // foreign_key_violation\n        console.error(\"Foreign key constraint failed:\", error.detail);\n        break;\n      case \"42P01\":  // undefined_table\n        console.error(\"Table does not exist:\", error.message);\n        break;\n      case \"28P01\":  // invalid_password\n        console.error(\"Authentication failed\");\n        break;\n      case \"57P03\":  // cannot_connect_now (server starting)\n        console.error(\"Server unavailable, retry later\");\n        break;\n      default:\n        console.error(`PostgreSQL error ${error.code}: ${error.message}`);\n    }\n  }\n  throw error;\n}\n```\n\n## Connection String Format\n\n```typescript\n// Alternative: Use connection string\nconst pool = new Pool({\n  connectionString: `postgres://${user}:${password}@${host}:${port}/${database}?sslmode=require`\n});\n\n// With SSL required (Azure)\nconst connectionString = \n  `postgres://user:password@server.postgres.database.azure.com:5432/mydb?sslmode=require`;\n```\n\n## Pool Events\n\n```typescript\nconst pool = new Pool({ /* config */ });\n\npool.on(\"connect\", (client) => {\n  console.log(\"New client connected to pool\");\n});\n\npool.on(\"acquire\", (client) => {\n  console.log(\"Client checked out from pool\");\n});\n\npool.on(\"release\", (err, client) => {\n  console.log(\"Client returned to pool\");\n});\n\npool.on(\"remove\", (client) => {\n  console.log(\"Client removed from pool\");\n});\n\npool.on(\"error\", (err, client) => {\n  console.error(\"Unexpected pool error:\", err);\n});\n```\n\n## Azure-Specific Configuration\n\n| Setting | Value | Description |\n|---------|-------|-------------|\n| `ssl.rejectUnauthorized` | `true` | Always use SSL for Azure |\n| Default port | `5432` | Standard PostgreSQL port |\n| PgBouncer port | `6432` | Use when PgBouncer enabled |\n| Token scope | `https://ossrdbms-aad.database.windows.net/.default` | Entra ID token scope |\n| Token lifetime | ~1 hour | Refresh before expiry |\n\n## Pool Sizing Guidelines\n\n| Workload | `max` | `idleTimeoutMillis` |\n|----------|-------|---------------------|\n| Light (dev/test) | 5-10 | 30000 |\n| Medium (production) | 20-30 | 30000 |\n| Heavy (high concurrency) | 50-100 | 10000 |\n\n> **Note**: Azure PostgreSQL has connection limits based on SKU. Check your tier's max connections.\n\n## Best Practices\n\n1. **Always use connection pools** for production applications\n2. **Use parameterized queries** - Never concatenate user input\n3. **Always close connections** - Use `try/finally` or connection pools\n4. **Enable SSL** - Required for Azure (`ssl: { rejectUnauthorized: true }`)\n5. **Handle token refresh** - Entra ID tokens expire after ~1 hour\n6. **Set connection timeouts** - Avoid hanging on network issues\n7. **Use transactions** - For multi-statement operations\n8. **Monitor pool metrics** - Track `pool.totalCount`, `pool.idleCount`, `pool.waitingCount`\n9. **Graceful shutdown** - Call `pool.end()` on application termination\n10. **Use TypeScript generics** - Type your query results for safety\n\n## Key Types\n\n```typescript\nimport {\n  Client,\n  Pool,\n  PoolClient,\n  PoolConfig,\n  QueryResult,\n  QueryResultRow,\n  DatabaseError,\n  QueryConfig\n} from \"pg\";\n```\n\n## Reference Links\n\n| Resource | URL |\n|----------|-----|\n| node-postgres Docs | https://node-postgres.com |\n| npm Package | https://www.npmjs.com/package/pg |\n| GitHub Repository | https://github.com/brianc/node-postgres |\n| Azure PostgreSQL Docs | https://learn.microsoft.com/azure/postgresql/flexible-server/ |\n| Passwordless Connection | https://learn.microsoft.com/azure/postgresql/flexible-server/how-to-connect-with-managed-identity |\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["azure","postgres","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-azure-postgres-ts","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/azure-postgres-ts","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34928 github stars · SKILL.md body (12,740 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T18:50:32.960Z","embedding":null,"createdAt":"2026-04-18T21:32:56.584Z","updatedAt":"2026-04-24T18:50:32.960Z","lastSeenAt":"2026-04-24T18:50:32.960Z","tsv":"'-10':1102 '-100':1113 '-30':1107 '/.default':205,768,1081 '/azure/postgresql/flexible-server/':1258 '/azure/postgresql/flexible-server/how-to-connect-with-managed-identity':1263 '/brianc/node-postgres':1252 '/mydb':995 '/package/pg':1247 '/typescript':16 '0':291,515,619,624,668,700 '1':109,243,374,443,459,470,485,508,526,601,615,661,693,896,1088,1132,1175 '10':1210 '1000':795 '10000':352,1114 '123':428 '2':153,300,460,471,527,616,694,1140 '20':339,874,1106 '23503':916 '23505':907 '28p01':939 '3':411,472,1148 '30000':345,1103,1108 '30s':350 '4':473,488,1157 '42p01':928 '5':474,542,783,793,1101,1166 '50':1112 '5432':80,143,235,273,332,869,1066 '57p03':947 '6':625,1177 '60':794 '6432':1072 '7':1186 '8':1194 '9':1202 '99.99':529,621 'access':194 'accesstoken':725 'acquir':193,361,1016 'action':1276 'altern':971 'alway':297,418,1059,1133,1149 'applic':711,1139,1208,1270 'array':466 'ask':1314 'assign':105,172,182 'async':547,590,673,759,796,826,842 'authent':55,83,93,107,111,943 'automat':360 'avoid':1181 'await':150,201,239,278,282,295,367,383,388,395,409,436,449,477,493,496,501,517,530,535,559,562,567,570,577,587,594,606,654,685,764,812,816,836,847,877,889 'azur':2,7,24,33,70,74,77,84,87,94,99,149,197,990,1051,1063,1116,1162,1253 'azure-postgres-t':1 'azure-specif':1050 'azure/identity':61,168,727 'azurepool':853 'azurepool.query':878 'azurepostgrespool':729,855 'base':1121 'bash':57,68 'begin':498,564 'best':1130 'boolean':777 'boundari':1322 'break':914,926,937,945,958 'call':1205 'cannot':948 'case':906,915,927,938,946 'catch':533,575,898 'check':1020,1124 'checkout':377 'clarif':1316 'class':728 'cleanup':406 'clear':1289 'client':114,119,121,161,207,209,245,249,253,255,382,492,553,558,569,591,1008,1011,1017,1019,1027,1029,1035,1037,1044,1224 'client.connect':151,240,279 'client.end':296 'client.query':283,389,396,497,502,518,531,536,563,571,578,595,607 'client.release':401,541,583 'clientid':101,192 'close':298,346,804,1150 'commit':532,572 'concaten':423,1145 'concurr':1111 'config':744,749,757,1005 'configur':337,1053 'connect':5,31,246,299,301,341,348,356,364,403,949,967,973,1007,1012,1119,1129,1135,1151,1155,1179,1260 'connectionstr':979,992 'connectiontimeoutmilli':351 'console.error':910,920,931,942,953,960,1045 'console.log':289,1009,1018,1028,1036 'const':118,175,185,199,206,252,280,311,365,381,386,393,426,429,434,447,468,475,491,499,512,557,565,585,592,604,651,663,683,762,814,834,852,875,975,991,1001 'constraint':923 'constructor':748 'core':241 'creat':456,644 'createus':675 'credenti':176,186,736 'credential.gettoken':202 'criteria':1325 'current':287,292 'd':64 'databas':8,34,76,126,129,214,217,260,263,319,322,860,863,984 'databaseerror':885,903,1230 'date':646,740,771,789,791 'default':959,1064 'defaultazurecredenti':166,178,188,724,737,755 'describ':1277,1293 'descript':1056 'dev/test':1100 'doc':1241,1255 'doe':465 'duplic':911 'e.g':97 'email':430,454,463,506,599,640,678,690,696,894,897 'enabl':1076,1158 'end':843 'entra':52,91,155,222,703,1082,1170 'entri':912 'environ':66,1305 'environment-specif':1304 'err':1026,1043,1049 'error':534,539,576,581,881,899,901,962,966,1042,1048 'error.code':905,963 'error.detail':913,925 'error.message':936,964 'event':999 'execut':1272 'exist':805,935 'expert':1310 'expir':713,809,1173 'expiri':786,1092 'explicit':376 'fail':924,944 'final':294,400,540,582 'flexibl':11,37 'fn':552,568 'foreign':917,921 'format':969 'function':545,548,674 'generic':1213 'getpool':797 'gettoken':760 'github':1248 'github.com':1251 'github.com/brianc/node-postgres':1250 'grace':1203 'guidelin':1095 'handl':882,1167 'hang':1182 'heavi':1109 'helper':544 'high':1110 'host':72,122,125,210,213,256,259,315,318,856,859,982 'hour':1089,1176 'id':53,92,156,223,373,442,469,483,487,510,516,523,612,620,638,660,704,1083,1171 'ident':106,174,184 'idl':347 'idletimeoutmilli':344,1098 'import':113,160,165,248,307,631,718,723,884,1223 'inject':416 'input':425,1147,1319 'insert':451,503,519,596,608,672,687,891 'instal':56,59,63 'instanceof':902 'int':486 'interfac':636 'invalid':940 'issu':1185 'istokenexpir':776 'john':464 'key':918,922,1220 'later':957 'learn.microsoft.com':1257,1262 'learn.microsoft.com/azure/postgresql/flexible-server/':1256 'learn.microsoft.com/azure/postgresql/flexible-server/how-to-connect-with-managed-identity':1261 'lifetim':1087 'light':1099 'limit':1120,1281 'link':1235 'long':709 'long-run':708 'manag':173,183 'managedidentityclientid':189 'match':1290 'max':338,873,1097,1128 'maximum':340 'medium':1104 'metric':1197 'microsoft':51,154 'minut':784 'miss':1327 'monitor':1195 'multi':1191 'multi-stat':1190 'multipl':379,445 'name':455,642,680,691,697 'need':715 'network':1184 'never':422,1144 'new':120,177,187,208,254,313,355,754,770,788,790,819,854,977,1003,1010 'node':21,29,43,1239 'node-postgr':20,28,42,1238 'node-postgres.com':1242 'node.js':15 'node.js/typescript':14 'note':1115 'npm':58,62,1243 'null':733,734,741,742,850 'number':139,231,639 'omit':745,750 'oper':1193 'option':108,152 'order':399,521,586,605,610 'order.rows':623 'ossrdbms-aad.database.windows.net':204,767,1080 'ossrdbms-aad.database.windows.net/.default':203,766,1079 'output':1299 'overview':1280 'packag':23,45,1244 'param':830,841 'paramet':433,446,467 'parameter':412,420,1142 'password':49,82,89,110,134,137,225,229,268,271,327,330,747,752,822,941,981 'password@server.postgres.database.azure.com:5432':994 'passwordless':54,157,1259 'permiss':1320 'pg':19,41,60,117,164,251,310,635,722,887,1233 'pgbouncer':1070,1075 'pool':115,162,302,308,312,314,336,343,359,405,550,551,589,632,676,677,701,719,731,732,806,820,835,976,978,998,1002,1004,1014,1023,1032,1040,1047,1093,1136,1156,1196,1225 'pool.connect':384,494,560 'pool.end':410,1206 'pool.idlecount':1200 'pool.on':1006,1015,1024,1033,1041 'pool.query':368,437,450,478,655,686,839,890 'pool.totalcount':1199 'pool.waitingcount':1201 'poolclient':554,1226 'poolconfig':720,746,751,1227 'port':79,138,142,230,234,272,331,868,983,1065,1069,1071 'postgr':3,22,30,44,1240 'postgres.database.azure.com':73 'postgresql':10,25,36,71,75,78,85,88,95,100,124,128,132,136,141,191,198,212,216,220,233,258,262,266,270,317,321,325,329,858,862,866,961,1068,1117,1254 'practic':1131 'prevent':414 'privat':730,735,738,743,758,775 'process.env.azure':123,127,131,135,140,190,211,215,219,232,257,261,265,269,316,320,324,328,857,861,865 'product':305,1105,1138 'promis':555,556,682,761,798,832,844 'queri':357,380,413,421,627,649,827,1143,1216 'queryconfig':1231 'queryresult':633,653,833,1228 'queryresultrow':1229 'recommend':158,303 'refer':1234 'refresh':706,716,782,1090,1169 'rejectunauthor':145,237,275,334,871,1164 'releas':363,1025 'remov':1034,1038 'repositori':1249 'requir':69,147,986,989,997,1160,1318 'res1':387 'res2':394 'resourc':1236 'result':281,366,435,448,476,566,574,650,652,684,876,1217 'result.rows':290,667,699 'retri':956 'return':402,462,509,573,602,617,622,695,698,773,780,787,802,824,838,1030 'review':1311 'rollback':537,579 'run':710 'safe':671 'safeti':1219,1321 'scope':1078,1085,1292 'select':284,369,390,397,438,479,656,879 'server':12,38,951,954 'set':1054,1178 'shutdown':408,1204 'singl':244,432 'size':1094 'skill':1268,1284 'skill-azure-postgres-ts' 'sku':1123 'source-sickn33' 'specif':1052,1306 'sql':415 'ssl':144,236,274,333,870,988,1061,1159,1163 'ssl.rejectunauthorized':1057 'sslmode':985,996 'standard':1067 'start':952 'statement':1192 'stop':1312 'string':641,643,679,681,829,968,974 'substitut':1302 'success':1324 'support':47 'switch':904 'system':171 'system-assign':170 'tabl':930,932 'task':1288 'termin':1209 'test':1308 'text':828,840 'this.config':756,821 'this.credential':753 'this.credential.gettoken':765 'this.getpool':837 'this.gettoken':817 'this.istokenexpired':801 'this.pool':800,803,811,818,825,846,849 'this.pool.end':813,848 'this.tokenexpiry':769,779 'this.tokenexpiry.gettime':792 'throw':538,580,965 'tier':1126 'time':288,293 'timeout':353,1180 'token':195,227,705,712,808,815,823,1077,1084,1086,1168,1172 'tokenexpiri':739 'tokenrespons':200,763 'tokenresponse.expiresontimestamp':772 'tokenresponse.token':226,774 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'total':524,613 'track':1198 'transact':489,543,1188 'treat':1297 'tri':277,385,495,561,888 'true':146,238,276,335,781,872,1058,1165 'try/finally':1153 'ts':4 'type':626,647,670,1214,1221 'type-saf':669 'types/pg':65 'typescript':27,112,159,247,306,417,490,546,629,630,717,883,970,1000,1212,1222 'unavail':955 'undefin':666,929 'unexpect':1046 'uniqu':908 'url':1237 'usag':584,851 'use':17,39,358,419,972,1060,1073,1134,1141,1152,1187,1211,1266,1282 'user':86,96,104,130,133,181,218,221,224,264,267,323,326,371,392,424,440,453,481,505,522,593,598,611,637,658,664,665,689,864,867,893,980,993,1146 'user-assign':103,180 'user.rows':618 'user@contoso.com':98 'user@example.com':431,511,603 'userid':375,427,444,513,528,662 'userresult':500 'userresult.rows':514 'valid':1307 'valu':458,507,525,600,614,692,895,1055 'variabl':67 'violat':909,919 'withtransact':549,588 'workflow':242,1274 'workload':1096 'www.npmjs.com':1246 'www.npmjs.com/package/pg':1245","prices":[{"id":"e220c5a9-7f97-481f-b9f5-6f8de41574b4","listingId":"553f6768-8bf2-4247-ae67-893cc2580b3f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:32:56.584Z"}],"sources":[{"listingId":"553f6768-8bf2-4247-ae67-893cc2580b3f","source":"github","sourceId":"sickn33/antigravity-awesome-skills/azure-postgres-ts","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/azure-postgres-ts","isPrimary":false,"firstSeenAt":"2026-04-18T21:32:56.584Z","lastSeenAt":"2026-04-24T18:50:32.960Z"}],"details":{"listingId":"553f6768-8bf2-4247-ae67-893cc2580b3f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"azure-postgres-ts","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34928,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-24T06:41:17Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"ead8ff71655cb6341159f2cf49c417523a9126c2","skill_md_path":"skills/azure-postgres-ts/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/azure-postgres-ts"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"azure-postgres-ts","description":"Connect to Azure Database for PostgreSQL Flexible Server from Node.js/TypeScript using the pg (node-postgres) package."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/azure-postgres-ts"},"updatedAt":"2026-04-24T18:50:32.960Z"}}