[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6G99NQ3RMT12RNETJH9CDYS":3,"skill-same:01M6G99NQ3RMT12RNETJH9CDYS":79},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":13,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M6G99NQ3RMT12RNETJH9CDYS","azure-cosmos-ts",null,"Azure Cosmos DB JavaScript\u002FTypeScript SDK (@azure\u002Fcosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: \"Cosmos DB\", \"@azure\u002Fcosmos\", \"CosmosClient\", \"document CRUD\", \"NoSQL queries\", \"bulk operations\", \"partition key\", \"container.items\".","ricardoaevt\u002Fnexus-roms","ricardoaevt","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F164531880?v=4","01M6DGFGSV6CF9AKPHABBREC79","01M6DGFGYNNPJVDFQA05TDPSBN",0,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fazure-cosmos-ts\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"azure","azure cosmos ts","cosmos","use","plane","container management","bulk","triggers","db","bulk operations","document","container","typescript","partition","crud","nosql","data","azure cosmos db","documents","javascript","2026-11-10 10:12:30",false,"---\nname: azure-cosmos-ts\ndescription: |\n  Azure Cosmos DB JavaScript\u002FTypeScript SDK (@azure\u002Fcosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: \"Cosmos DB\", \"@azure\u002Fcosmos\", \"CosmosClient\", \"document CRUD\", \"NoSQL queries\", \"bulk operations\", \"partition key\", \"container.items\".\npackage: \"@azure\u002Fcosmos\"\n---\n\n# @azure\u002Fcosmos (TypeScript\u002FJavaScript)\n\nData plane SDK for Azure Cosmos DB NoSQL API operations — CRUD on documents, queries, bulk operations.\n\n> **⚠️ Data vs Management Plane**\n> - **This SDK (@azure\u002Fcosmos)**: CRUD operations on documents, queries, stored procedures\n> - **Management SDK (@azure\u002Farm-cosmosdb)**: Create accounts, databases, containers via ARM\n\n## Installation\n\n```bash\nnpm install @azure\u002Fcosmos @azure\u002Fidentity\n```\n\n**Current Version**: 4.9.0  \n**Node.js**: >= 20.0.0\n\n## Environment Variables\n\n```bash\nCOSMOS_ENDPOINT=https:\u002F\u002F\u003Caccount>.documents.azure.com:443\u002F\nCOSMOS_DATABASE=\u003Cdatabase-name>\nCOSMOS_CONTAINER=\u003Ccontainer-name>\n# For key-based auth only (prefer AAD)\nCOSMOS_KEY=\u003Caccount-key>\n```\n\n## Authentication\n\n### AAD with DefaultAzureCredential (Recommended)\n\n```typescript\nimport { CosmosClient } from \"@azure\u002Fcosmos\";\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\n\nconst client = new CosmosClient({\n  endpoint: process.env.COSMOS_ENDPOINT!,\n  aadCredentials: new DefaultAzureCredential(),\n});\n```\n\n### Key-Based Authentication\n\n```typescript\nimport { CosmosClient } from \"@azure\u002Fcosmos\";\n\n\u002F\u002F Option 1: Endpoint + Key\nconst client = new CosmosClient({\n  endpoint: process.env.COSMOS_ENDPOINT!,\n  key: process.env.COSMOS_KEY!,\n});\n\n\u002F\u002F Option 2: Connection String\nconst client = new CosmosClient(process.env.COSMOS_CONNECTION_STRING!);\n```\n\n## Resource Hierarchy\n\n```\nCosmosClient\n└── Database\n    └── Container\n        ├── Items (documents)\n        ├── Scripts (stored procedures, triggers, UDFs)\n        └── Conflicts\n```\n\n## Core Operations\n\n### Database & Container Setup\n\n```typescript\nconst { database } = await client.databases.createIfNotExists({\n  id: \"my-database\",\n});\n\nconst { container } = await database.containers.createIfNotExists({\n  id: \"my-container\",\n  partitionKey: { paths: [\"\u002FpartitionKey\"] },\n});\n```\n\n### Create Document\n\n```typescript\ninterface Product {\n  id: string;\n  partitionKey: string;\n  name: string;\n  price: number;\n}\n\nconst item: Product = {\n  id: \"product-1\",\n  partitionKey: \"electronics\",\n  name: \"Laptop\",\n  price: 999.99,\n};\n\nconst { resource } = await container.items.create\u003CProduct>(item);\n```\n\n### Read Document\n\n```typescript\nconst { resource } = await container\n  .item(\"product-1\", \"electronics\") \u002F\u002F id, partitionKey\n  .read\u003CProduct>();\n\nif (resource) {\n  console.log(resource.name);\n}\n```\n\n### Update Document (Replace)\n\n```typescript\nconst { resource: existing } = await container\n  .item(\"product-1\", \"electronics\")\n  .read\u003CProduct>();\n\nif (existing) {\n  existing.price = 899.99;\n  const { resource: updated } = await container\n    .item(\"product-1\", \"electronics\")\n    .replace\u003CProduct>(existing);\n}\n```\n\n### Upsert Document\n\n```typescript\nconst item: Product = {\n  id: \"product-1\",\n  partitionKey: \"electronics\",\n  name: \"Laptop Pro\",\n  price: 1299.99,\n};\n\nconst { resource } = await container.items.upsert\u003CProduct>(item);\n```\n\n### Delete Document\n\n```typescript\nawait container.item(\"product-1\", \"electronics\").delete();\n```\n\n### Patch Document (Partial Update)\n\n```typescript\nimport { PatchOperation } from \"@azure\u002Fcosmos\";\n\nconst operations: PatchOperation[] = [\n  { op: \"replace\", path: \"\u002Fprice\", value: 799.99 },\n  { op: \"add\", path: \"\u002Fdiscount\", value: true },\n  { op: \"remove\", path: \"\u002FoldField\" },\n];\n\nconst { resource } = await container\n  .item(\"product-1\", \"electronics\")\n  .patch\u003CProduct>(operations);\n```\n\n## Queries\n\n### Simple Query\n\n```typescript\nconst { resources } = await container.items\n  .query\u003CProduct>(\"SELECT * FROM c WHERE c.price \u003C 1000\")\n  .fetchAll();\n```\n\n### Parameterized Query (Recommended)\n\n```typescript\nimport { SqlQuerySpec } from \"@azure\u002Fcosmos\";\n\nconst querySpec: SqlQuerySpec = {\n  query: \"SELECT * FROM c WHERE c.partitionKey = @category AND c.price \u003C @maxPrice\",\n  parameters: [\n    { name: \"@category\", value: \"electronics\" },\n    { name: \"@maxPrice\", value: 1000 },\n  ],\n};\n\nconst { resources } = await container.items\n  .query\u003CProduct>(querySpec)\n  .fetchAll();\n```\n\n### Query with Pagination\n\n```typescript\nconst queryIterator = container.items.query\u003CProduct>(querySpec, {\n  maxItemCount: 10, \u002F\u002F Items per page\n});\n\nwhile (queryIterator.hasMoreResults()) {\n  const { resources, continuationToken } = await queryIterator.fetchNext();\n  console.log(`Page with ${resources?.length} items`);\n  \u002F\u002F Use continuationToken for next page if needed\n}\n```\n\n### Cross-Partition Query\n\n```typescript\nconst { resources } = await container.items\n  .query\u003CProduct>(\n    \"SELECT * FROM c WHERE c.price > 500\",\n    { enableCrossPartitionQuery: true }\n  )\n  .fetchAll();\n```\n\n## Bulk Operations\n\n### Execute Bulk Operations\n\n```typescript\nimport { BulkOperationType, OperationInput } from \"@azure\u002Fcosmos\";\n\nconst operations: OperationInput[] = [\n  {\n    operationType: BulkOperationType.Create,\n    resourceBody: { id: \"1\", partitionKey: \"cat-a\", name: \"Item 1\" },\n  },\n  {\n    operationType: BulkOperationType.Upsert,\n    resourceBody: { id: \"2\", partitionKey: \"cat-a\", name: \"Item 2\" },\n  },\n  {\n    operationType: BulkOperationType.Read,\n    id: \"3\",\n    partitionKey: \"cat-b\",\n  },\n  {\n    operationType: BulkOperationType.Replace,\n    id: \"4\",\n    partitionKey: \"cat-b\",\n    resourceBody: { id: \"4\", partitionKey: \"cat-b\", name: \"Updated\" },\n  },\n  {\n    operationType: BulkOperationType.Delete,\n    id: \"5\",\n    partitionKey: \"cat-c\",\n  },\n  {\n    operationType: BulkOperationType.Patch,\n    id: \"6\",\n    partitionKey: \"cat-c\",\n    resourceBody: {\n      operations: [{ op: \"replace\", path: \"\u002Fname\", value: \"Patched\" }],\n    },\n  },\n];\n\nconst response = await container.items.executeBulkOperations(operations);\n\nresponse.forEach((result, index) => {\n  if (result.statusCode >= 200 && result.statusCode \u003C 300) {\n    console.log(`Operation ${index} succeeded`);\n  } else {\n    console.error(`Operation ${index} failed: ${result.statusCode}`);\n  }\n});\n```\n\n## Partition Keys\n\n### Simple Partition Key\n\n```typescript\nconst { container } = await database.containers.createIfNotExists({\n  id: \"products\",\n  partitionKey: { paths: [\"\u002Fcategory\"] },\n});\n```\n\n### Hierarchical Partition Key (MultiHash)\n\n```typescript\nimport { PartitionKeyDefinitionVersion, PartitionKeyKind } from \"@azure\u002Fcosmos\";\n\nconst { container } = await database.containers.createIfNotExists({\n  id: \"orders\",\n  partitionKey: {\n    paths: [\"\u002FtenantId\", \"\u002FuserId\", \"\u002FsessionId\"],\n    version: PartitionKeyDefinitionVersion.V2,\n    kind: PartitionKeyKind.MultiHash,\n  },\n});\n\n\u002F\u002F Operations require array of partition key values\nconst { resource } = await container.items.create({\n  id: \"order-1\",\n  tenantId: \"tenant-a\",\n  userId: \"user-123\",\n  sessionId: \"session-xyz\",\n  total: 99.99,\n});\n\n\u002F\u002F Read with hierarchical partition key\nconst { resource: order } = await container\n  .item(\"order-1\", [\"tenant-a\", \"user-123\", \"session-xyz\"])\n  .read();\n```\n\n## Error Handling\n\n```typescript\nimport { ErrorResponse } from \"@azure\u002Fcosmos\";\n\ntry {\n  const { resource } = await container.item(\"missing\", \"pk\").read();\n} catch (error) {\n  if (error instanceof ErrorResponse) {\n    switch (error.code) {\n      case 404:\n        console.log(\"Document not found\");\n        break;\n      case 409:\n        console.log(\"Conflict - document already exists\");\n        break;\n      case 412:\n        console.log(\"Precondition failed (ETag mismatch)\");\n        break;\n      case 429:\n        console.log(\"Rate limited - retry after:\", error.retryAfterInMs);\n        break;\n      default:\n        console.error(`Cosmos error ${error.code}: ${error.message}`);\n    }\n  }\n  throw error;\n}\n```\n\n## Optimistic Concurrency (ETags)\n\n```typescript\n\u002F\u002F Read with ETag\nconst { resource, etag } = await container\n  .item(\"product-1\", \"electronics\")\n  .read\u003CProduct>();\n\nif (resource && etag) {\n  resource.price = 899.99;\n  \n  try {\n    \u002F\u002F Replace only if ETag matches\n    await container.item(\"product-1\", \"electronics\").replace(resource, {\n      accessCondition: { type: \"IfMatch\", condition: etag },\n    });\n  } catch (error) {\n    if (error instanceof ErrorResponse && error.code === 412) {\n      console.log(\"Document was modified by another process\");\n    }\n  }\n}\n```\n\n## TypeScript Types Reference\n\n```typescript\nimport {\n  \u002F\u002F Client & Resources\n  CosmosClient,\n  Database,\n  Container,\n  Item,\n  Items,\n  \n  \u002F\u002F Operations\n  OperationInput,\n  BulkOperationType,\n  PatchOperation,\n  \n  \u002F\u002F Queries\n  SqlQuerySpec,\n  SqlParameter,\n  FeedOptions,\n  \n  \u002F\u002F Partition Keys\n  PartitionKeyDefinition,\n  PartitionKeyDefinitionVersion,\n  PartitionKeyKind,\n  \n  \u002F\u002F Responses\n  ItemResponse,\n  FeedResponse,\n  ResourceResponse,\n  \n  \u002F\u002F Errors\n  ErrorResponse,\n} from \"@azure\u002Fcosmos\";\n```\n\n## Best Practices\n\n1. **Use AAD authentication** — Prefer `DefaultAzureCredential` over keys\n2. **Always use parameterized queries** — Prevents injection, improves plan caching\n3. **Specify partition key** — Avoid cross-partition queries when possible\n4. **Use bulk operations** — For multiple writes, use `executeBulkOperations`\n5. **Handle 429 errors** — Implement retry logic with exponential backoff\n6. **Use ETags for concurrency** — Prevent lost updates in concurrent scenarios\n7. **Close client on shutdown** — Call `client.dispose()` in cleanup\n\n## Common Patterns\n\n### Service Layer Pattern\n\n```typescript\nexport class ProductService {\n  private container: Container;\n\n  constructor(client: CosmosClient) {\n    this.container = client\n      .database(process.env.COSMOS_DATABASE!)\n      .container(process.env.COSMOS_CONTAINER!);\n  }\n\n  async getById(id: string, category: string): Promise\u003CProduct | null> {\n    try {\n      const { resource } = await this.container\n        .item(id, category)\n        .read\u003CProduct>();\n      return resource ?? null;\n    } catch (error) {\n      if (error instanceof ErrorResponse && error.code === 404) {\n        return null;\n      }\n      throw error;\n    }\n  }\n\n  async create(product: Omit\u003CProduct, \"id\">): Promise\u003CProduct> {\n    const item = { ...product, id: crypto.randomUUID() };\n    const { resource } = await this.container.items.create\u003CProduct>(item);\n    return resource!;\n  }\n\n  async findByCategory(category: string): Promise\u003CProduct[]> {\n    const querySpec: SqlQuerySpec = {\n      query: \"SELECT * FROM c WHERE c.partitionKey = @category\",\n      parameters: [{ name: \"@category\", value: category }],\n    };\n    const { resources } = await this.container.items\n      .query\u003CProduct>(querySpec)\n      .fetchAll();\n    return resources;\n  }\n}\n```\n\n## Related SDKs\n\n| SDK | Purpose | Install |\n|-----|---------|---------|\n| `@azure\u002Fcosmos` | Data plane (this SDK) | `npm install @azure\u002Fcosmos` |\n| `@azure\u002Farm-cosmosdb` | Management plane (ARM) | `npm install @azure\u002Farm-cosmosdb` |\n| `@azure\u002Fidentity` | Authentication | `npm install @azure\u002Fidentity` |\n","# @azure\u002Fcosmos (TypeScript\u002FJavaScript)\n\nData plane SDK for Azure Cosmos DB NoSQL API operations — CRUD on documents, queries, bulk operations.\n\n> **⚠️ Data vs Management Plane**\n> - **This SDK (@azure\u002Fcosmos)**: CRUD operations on documents, queries, stored procedures\n> - **Management SDK (@azure\u002Farm-cosmosdb)**: Create accounts, databases, containers via ARM\n\n## Installation\n\n```bash\nnpm install @azure\u002Fcosmos @azure\u002Fidentity\n```\n\n**Current Version**: 4.9.0  \n**Node.js**: >= 20.0.0\n\n## Environment Variables\n\n```bash\nCOSMOS_ENDPOINT=https:\u002F\u002F\u003Caccount>.documents.azure.com:443\u002F\nCOSMOS_DATABASE=\u003Cdatabase-name>\nCOSMOS_CONTAINER=\u003Ccontainer-name>\n# For key-based auth only (prefer AAD)\nCOSMOS_KEY=\u003Caccount-key>\n```\n\n## Authentication\n\n### AAD with DefaultAzureCredential (Recommended)\n\n```typescript\nimport { CosmosClient } from \"@azure\u002Fcosmos\";\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\n\nconst client = new CosmosClient({\n  endpoint: process.env.COSMOS_ENDPOINT!,\n  aadCredentials: new DefaultAzureCredential(),\n});\n```\n\n### Key-Based Authentication\n\n```typescript\nimport { CosmosClient } from \"@azure\u002Fcosmos\";\n\n\u002F\u002F Option 1: Endpoint + Key\nconst client = new CosmosClient({\n  endpoint: process.env.COSMOS_ENDPOINT!,\n  key: process.env.COSMOS_KEY!,\n});\n\n\u002F\u002F Option 2: Connection String\nconst client = new CosmosClient(process.env.COSMOS_CONNECTION_STRING!);\n```\n\n## Resource Hierarchy\n\n```\nCosmosClient\n└── Database\n    └── Container\n        ├── Items (documents)\n        ├── Scripts (stored procedures, triggers, UDFs)\n        └── Conflicts\n```\n\n## Core Operations\n\n### Database & Container Setup\n\n```typescript\nconst { database } = await client.databases.createIfNotExists({\n  id: \"my-database\",\n});\n\nconst { container } = await database.containers.createIfNotExists({\n  id: \"my-container\",\n  partitionKey: { paths: [\"\u002FpartitionKey\"] },\n});\n```\n\n### Create Document\n\n```typescript\ninterface Product {\n  id: string;\n  partitionKey: string;\n  name: string;\n  price: number;\n}\n\nconst item: Product = {\n  id: \"product-1\",\n  partitionKey: \"electronics\",\n  name: \"Laptop\",\n  price: 999.99,\n};\n\nconst { resource } = await container.items.create\u003CProduct>(item);\n```\n\n### Read Document\n\n```typescript\nconst { resource } = await container\n  .item(\"product-1\", \"electronics\") \u002F\u002F id, partitionKey\n  .read\u003CProduct>();\n\nif (resource) {\n  console.log(resource.name);\n}\n```\n\n### Update Document (Replace)\n\n```typescript\nconst { resource: existing } = await container\n  .item(\"product-1\", \"electronics\")\n  .read\u003CProduct>();\n\nif (existing) {\n  existing.price = 899.99;\n  const { resource: updated } = await container\n    .item(\"product-1\", \"electronics\")\n    .replace\u003CProduct>(existing);\n}\n```\n\n### Upsert Document\n\n```typescript\nconst item: Product = {\n  id: \"product-1\",\n  partitionKey: \"electronics\",\n  name: \"Laptop Pro\",\n  price: 1299.99,\n};\n\nconst { resource } = await container.items.upsert\u003CProduct>(item);\n```\n\n### Delete Document\n\n```typescript\nawait container.item(\"product-1\", \"electronics\").delete();\n```\n\n### Patch Document (Partial Update)\n\n```typescript\nimport { PatchOperation } from \"@azure\u002Fcosmos\";\n\nconst operations: PatchOperation[] = [\n  { op: \"replace\", path: \"\u002Fprice\", value: 799.99 },\n  { op: \"add\", path: \"\u002Fdiscount\", value: true },\n  { op: \"remove\", path: \"\u002FoldField\" },\n];\n\nconst { resource } = await container\n  .item(\"product-1\", \"electronics\")\n  .patch\u003CProduct>(operations);\n```\n\n## Queries\n\n### Simple Query\n\n```typescript\nconst { resources } = await container.items\n  .query\u003CProduct>(\"SELECT * FROM c WHERE c.price \u003C 1000\")\n  .fetchAll();\n```\n\n### Parameterized Query (Recommended)\n\n```typescript\nimport { SqlQuerySpec } from \"@azure\u002Fcosmos\";\n\nconst querySpec: SqlQuerySpec = {\n  query: \"SELECT * FROM c WHERE c.partitionKey = @category AND c.price \u003C @maxPrice\",\n  parameters: [\n    { name: \"@category\", value: \"electronics\" },\n    { name: \"@maxPrice\", value: 1000 },\n  ],\n};\n\nconst { resources } = await container.items\n  .query\u003CProduct>(querySpec)\n  .fetchAll();\n```\n\n### Query with Pagination\n\n```typescript\nconst queryIterator = container.items.query\u003CProduct>(querySpec, {\n  maxItemCount: 10, \u002F\u002F Items per page\n});\n\nwhile (queryIterator.hasMoreResults()) {\n  const { resources, continuationToken } = await queryIterator.fetchNext();\n  console.log(`Page with ${resources?.length} items`);\n  \u002F\u002F Use continuationToken for next page if needed\n}\n```\n\n### Cross-Partition Query\n\n```typescript\nconst { resources } = await container.items\n  .query\u003CProduct>(\n    \"SELECT * FROM c WHERE c.price > 500\",\n    { enableCrossPartitionQuery: true }\n  )\n  .fetchAll();\n```\n\n## Bulk Operations\n\n### Execute Bulk Operations\n\n```typescript\nimport { BulkOperationType, OperationInput } from \"@azure\u002Fcosmos\";\n\nconst operations: OperationInput[] = [\n  {\n    operationType: BulkOperationType.Create,\n    resourceBody: { id: \"1\", partitionKey: \"cat-a\", name: \"Item 1\" },\n  },\n  {\n    operationType: BulkOperationType.Upsert,\n    resourceBody: { id: \"2\", partitionKey: \"cat-a\", name: \"Item 2\" },\n  },\n  {\n    operationType: BulkOperationType.Read,\n    id: \"3\",\n    partitionKey: \"cat-b\",\n  },\n  {\n    operationType: BulkOperationType.Replace,\n    id: \"4\",\n    partitionKey: \"cat-b\",\n    resourceBody: { id: \"4\", partitionKey: \"cat-b\", name: \"Updated\" },\n  },\n  {\n    operationType: BulkOperationType.Delete,\n    id: \"5\",\n    partitionKey: \"cat-c\",\n  },\n  {\n    operationType: BulkOperationType.Patch,\n    id: \"6\",\n    partitionKey: \"cat-c\",\n    resourceBody: {\n      operations: [{ op: \"replace\", path: \"\u002Fname\", value: \"Patched\" }],\n    },\n  },\n];\n\nconst response = await container.items.executeBulkOperations(operations);\n\nresponse.forEach((result, index) => {\n  if (result.statusCode >= 200 && result.statusCode \u003C 300) {\n    console.log(`Operation ${index} succeeded`);\n  } else {\n    console.error(`Operation ${index} failed: ${result.statusCode}`);\n  }\n});\n```\n\n## Partition Keys\n\n### Simple Partition Key\n\n```typescript\nconst { container } = await database.containers.createIfNotExists({\n  id: \"products\",\n  partitionKey: { paths: [\"\u002Fcategory\"] },\n});\n```\n\n### Hierarchical Partition Key (MultiHash)\n\n```typescript\nimport { PartitionKeyDefinitionVersion, PartitionKeyKind } from \"@azure\u002Fcosmos\";\n\nconst { container } = await database.containers.createIfNotExists({\n  id: \"orders\",\n  partitionKey: {\n    paths: [\"\u002FtenantId\", \"\u002FuserId\", \"\u002FsessionId\"],\n    version: PartitionKeyDefinitionVersion.V2,\n    kind: PartitionKeyKind.MultiHash,\n  },\n});\n\n\u002F\u002F Operations require array of partition key values\nconst { resource } = await container.items.create({\n  id: \"order-1\",\n  tenantId: \"tenant-a\",\n  userId: \"user-123\",\n  sessionId: \"session-xyz\",\n  total: 99.99,\n});\n\n\u002F\u002F Read with hierarchical partition key\nconst { resource: order } = await container\n  .item(\"order-1\", [\"tenant-a\", \"user-123\", \"session-xyz\"])\n  .read();\n```\n\n## Error Handling\n\n```typescript\nimport { ErrorResponse } from \"@azure\u002Fcosmos\";\n\ntry {\n  const { resource } = await container.item(\"missing\", \"pk\").read();\n} catch (error) {\n  if (error instanceof ErrorResponse) {\n    switch (error.code) {\n      case 404:\n        console.log(\"Document not found\");\n        break;\n      case 409:\n        console.log(\"Conflict - document already exists\");\n        break;\n      case 412:\n        console.log(\"Precondition failed (ETag mismatch)\");\n        break;\n      case 429:\n        console.log(\"Rate limited - retry after:\", error.retryAfterInMs);\n        break;\n      default:\n        console.error(`Cosmos error ${error.code}: ${error.message}`);\n    }\n  }\n  throw error;\n}\n```\n\n## Optimistic Concurrency (ETags)\n\n```typescript\n\u002F\u002F Read with ETag\nconst { resource, etag } = await container\n  .item(\"product-1\", \"electronics\")\n  .read\u003CProduct>();\n\nif (resource && etag) {\n  resource.price = 899.99;\n  \n  try {\n    \u002F\u002F Replace only if ETag matches\n    await container.item(\"product-1\", \"electronics\").replace(resource, {\n      accessCondition: { type: \"IfMatch\", condition: etag },\n    });\n  } catch (error) {\n    if (error instanceof ErrorResponse && error.code === 412) {\n      console.log(\"Document was modified by another process\");\n    }\n  }\n}\n```\n\n## TypeScript Types Reference\n\n```typescript\nimport {\n  \u002F\u002F Client & Resources\n  CosmosClient,\n  Database,\n  Container,\n  Item,\n  Items,\n  \n  \u002F\u002F Operations\n  OperationInput,\n  BulkOperationType,\n  PatchOperation,\n  \n  \u002F\u002F Queries\n  SqlQuerySpec,\n  SqlParameter,\n  FeedOptions,\n  \n  \u002F\u002F Partition Keys\n  PartitionKeyDefinition,\n  PartitionKeyDefinitionVersion,\n  PartitionKeyKind,\n  \n  \u002F\u002F Responses\n  ItemResponse,\n  FeedResponse,\n  ResourceResponse,\n  \n  \u002F\u002F Errors\n  ErrorResponse,\n} from \"@azure\u002Fcosmos\";\n```\n\n## Best Practices\n\n1. **Use AAD authentication** — Prefer `DefaultAzureCredential` over keys\n2. **Always use parameterized queries** — Prevents injection, improves plan caching\n3. **Specify partition key** — Avoid cross-partition queries when possible\n4. **Use bulk operations** — For multiple writes, use `executeBulkOperations`\n5. **Handle 429 errors** — Implement retry logic with exponential backoff\n6. **Use ETags for concurrency** — Prevent lost updates in concurrent scenarios\n7. **Close client on shutdown** — Call `client.dispose()` in cleanup\n\n## Common Patterns\n\n### Service Layer Pattern\n\n```typescript\nexport class ProductService {\n  private container: Container;\n\n  constructor(client: CosmosClient) {\n    this.container = client\n      .database(process.env.COSMOS_DATABASE!)\n      .container(process.env.COSMOS_CONTAINER!);\n  }\n\n  async getById(id: string, category: string): Promise\u003CProduct | null> {\n    try {\n      const { resource } = await this.container\n        .item(id, category)\n        .read\u003CProduct>();\n      return resource ?? null;\n    } catch (error) {\n      if (error instanceof ErrorResponse && error.code === 404) {\n        return null;\n      }\n      throw error;\n    }\n  }\n\n  async create(product: Omit\u003CProduct, \"id\">): Promise\u003CProduct> {\n    const item = { ...product, id: crypto.randomUUID() };\n    const { resource } = await this.container.items.create\u003CProduct>(item);\n    return resource!;\n  }\n\n  async findByCategory(category: string): Promise\u003CProduct[]> {\n    const querySpec: SqlQuerySpec = {\n      query: \"SELECT * FROM c WHERE c.partitionKey = @category\",\n      parameters: [{ name: \"@category\", value: category }],\n    };\n    const { resources } = await this.container.items\n      .query\u003CProduct>(querySpec)\n      .fetchAll();\n    return resources;\n  }\n}\n```\n\n## Related SDKs\n\n| SDK | Purpose | Install |\n|-----|---------|---------|\n| `@azure\u002Fcosmos` | Data plane (this SDK) | `npm install @azure\u002Fcosmos` |\n| `@azure\u002Farm-cosmosdb` | Management plane (ARM) | `npm install @azure\u002Farm-cosmosdb` |\n| `@azure\u002Fidentity` | Authentication | `npm install @azure\u002Fidentity` |\n",{"name":5,"package":43,"description":44},"@azure\u002Fcosmos","Azure Cosmos DB JavaScript\u002FTypeScript SDK (@azure\u002Fcosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: \"Cosmos DB\", \"@azure\u002Fcosmos\", \"CosmosClient\", \"document CRUD\", \"NoSQL queries\", \"bulk operations\", \"partition key\", \"container.items\".\n","main","d41309588593cee5c2fb44062474efc3a99fbcb6",".agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fazure-cosmos-ts","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms","https:\u002F\u002Fgithub.com\u002Fricardoaevt","2026-03-23 00:05:03",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add ricardoaevt\u002Fnexus-roms --skill azure-cosmos-ts",{"tool":57,"command":58},"bunx","bunx skills add ricardoaevt\u002Fnexus-roms --skill azure-cosmos-ts",{"tool":60,"command":61},"pnpm","pnpm dlx skills add ricardoaevt\u002Fnexus-roms --skill azure-cosmos-ts","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fazure-cosmos-ts\u002FSKILL.md",true,[65,71,75],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"references\u002Facceptance-criteria.md","REFERENCE","参考文档",10350,"https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fazure-cosmos-ts\u002Freferences\u002Facceptance-criteria.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"references\u002Fbulk-operations.md",11431,"https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fazure-cosmos-ts\u002Freferences\u002Fbulk-operations.md",{"path":76,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":77,"sourceHtmlUrl":78},"references\u002Fquery-patterns.md",8916,"https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fazure-cosmos-ts\u002Freferences\u002Fquery-patterns.md",[80,104,120,135,146,155],{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":84,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":38},"01M6G9HYKQRK6HBKVTZM3258M3","openspec-propose","Propose a new change with all artifacts generated in one step. Use when the user wants to quickly describe what they want to build and get a complete proposal with design, specs, and tasks ready for implementation.","MIT","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-propose\u002FSKILL.md",[],[88,89,90,91,92,93,94,95,96,97,98,21,99,100,101,102,103],"openspec propose","openspec","cli","generated","with","proposal","complete","get","build","implementation","ready","user","artifacts","tasks","change","design",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":84,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":38},"01M6G9HV9V20WFCHYVSDNQMJVK","openspec-new-change","Start a new OpenSpec change using the experimental artifact workflow. Use when the user wants to create a new feature, fix, or modification with a structured step-by-step approach.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-new-change\u002FSKILL.md",[],[89,111,102,112,90,113,114,115,21,99,116,117,118,119,92],"openspec new change","new feature","structured","artifact","workflow","create","start","fix","feature",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":84,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":38},"01M6G9HRF6R89QZXGSFC9DRQW3","openspec-explore","Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-explore\u002FSKILL.md",[],[127,128,89,21,129,90,102,99,130,131,132,133,134],"openspec explore","explore","partner","think","thinking partner","thinking","ideas","requirements",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":84,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":141,"publishedAt":38},"01M6G9HP3APFCXZG7XRWBMM524","openspec-continue-change","Continue working on an OpenSpec change by creating the next artifact. Use when the user wants to progress their change, create the next artifact, or continue their workflow.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-continue-change\u002FSKILL.md",[],[89,142,143,102,115,90,116,99,21,144,114,145],"continue","openspec continue change","next","progress",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":84,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":152,"publishedAt":38},"01M6G9HKT3WMSDBSKA7YM4MSSQ","openspec-archive-change","Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-archive-change\u002FSKILL.md",[],[153,89,154,102,90,115,99,21,97,94],"openspec archive change","archive",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":84,"licenseFileUrl":6,"sourceHtmlUrl":159,"categories":160,"keywords":161,"publishedAt":38},"01M6G9HHEG0RJK4E0YTVZZ6A8T","openspec-apply-change","Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-apply-change\u002FSKILL.md",[],[89,102,162,163,101,117,142,164,99,21,97,90],"openspec apply change","implement","work"]