From 6376d71660954fb02f5ec901eeddfb9df09ccbad Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Mon, 2 Feb 2026 09:09:36 -0700 Subject: [PATCH 1/2] chore: use oxfmt --- .github/workflows/lint.yaml | 2 +- .oxfmtrc.jsonc | 4 ++++ .prettierignore | 1 - package.json | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 .oxfmtrc.jsonc delete mode 100644 .prettierignore diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 70d7343..06bfb19 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -19,7 +19,7 @@ jobs: with: useLockFile: false - name: "Run prettier" - run: "CI=true yarn run prettier src -c" + run: "CI=true yarn run oxfmt --check" - name: "Run lint" run: "CI=true yarn lint" - name: "Run publint" diff --git a/.oxfmtrc.jsonc b/.oxfmtrc.jsonc new file mode 100644 index 0000000..01f6713 --- /dev/null +++ b/.oxfmtrc.jsonc @@ -0,0 +1,4 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "ignorePatterns": ["src/authzedapi"], +} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 11f8159..0000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -src/authzedapi diff --git a/package.json b/package.json index d2d8fb1..867162e 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "buf": "buf generate && tsc-esm-fix --src src/authzedapi --ext='.js'", "lint": "./node_modules/.bin/eslint src", "lint:package": "publint --pack npm", - "format": "prettier -w src", + "format": "oxfmt", "build": "tsc", "postbuild": "rollup dist/src/index.js --file dist/src/index.cjs --format cjs && cp dist/src/index.d.ts dist/src/index.d.cts", "prepublish": "yarn build", @@ -64,7 +64,7 @@ "@typescript-eslint/parser": "^8.54.0", "eslint": "^9.39.2", "grpc-tools": "^1.13.1", - "prettier": "^3.8.1", + "oxfmt": "^0.28.0", "publint": "^0.3.17", "rollup": "^4.57.1", "tsc-esm-fix": "^3.1.2", From bf3c2c81f1bad5fd38760701d0b0ad9f59d9ad41 Mon Sep 17 00:00:00 2001 From: Tanner Stirrat Date: Mon, 2 Feb 2026 09:11:41 -0700 Subject: [PATCH 2/2] chore: run formatter --- .github/workflows/cla.yaml | 2 +- .github/workflows/publish.yaml | 2 +- CONTRIBUTING.md | 1 + README.md | 75 +++++++++---------- docker-compose.yaml | 2 +- eslint.config.mjs | 34 +++++---- examples/v1/example.js | 41 +++++------ js-dist/package.json | 10 +-- package.json | 22 +++--- src/full-promises.test.ts | 4 +- src/types.ts | 32 ++------ src/util.ts | 15 +--- src/v1-promise.test.ts | 16 +--- src/v1.test.ts | 131 +++++++++++---------------------- src/v1.ts | 102 +++++++------------------ tsconfig.json | 13 +--- 16 files changed, 185 insertions(+), 317 deletions(-) diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index b11bbde..8bc9f98 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -1,6 +1,6 @@ --- name: "CLA" -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy issue_comment: types: - "created" diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 12aec34..9f65e1d 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,7 +1,7 @@ --- # yamllint disable rule:line-length name: "Publish to NPM" -on: # yamllint disable-line rule:truthy +on: # yamllint disable-line rule:truthy release: types: - "published" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a194860..8caa82f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -120,6 +120,7 @@ You can regenerate the code by executing `buf.gen.yaml`: Releases are published to NPM using a GitHub action. To create a new release: + 1. Use the [yarn version] command to bump the package version. 1. Create a new [release on GitHub] to initiate the release action. diff --git a/README.md b/README.md index 9d4c3c0..42eecf0 100644 --- a/README.md +++ b/README.md @@ -57,20 +57,21 @@ Everything required to connect and make API calls is located in a module respect You will have to provide a your own API Token from the [Authzed dashboard] in place of `t_your_token_here_1234567deadbeef` in the following example: ```js -import { v1 } from '@authzed/authzed-node'; +import { v1 } from "@authzed/authzed-node"; // if your endpoint is localhost // const client = v1.NewClient('t_your_token_here_1234567deadbeef', 'localhost:50051', v1.ClientSecurity.INSECURE_LOCALHOST_ALLOWED); -const client = v1.NewClient('t_your_token_here_1234567deadbeef'); +const client = v1.NewClient("t_your_token_here_1234567deadbeef"); ``` Or to use a custom certificate authority, load the CA certificate and pass the file reference to `NewClientWithCustomCert`. + ```js -import { v1 } from '@authzed/authzed-node'; -import fs from 'fs'; +import { v1 } from "@authzed/authzed-node"; +import fs from "fs"; -const endpoint = 'localhost:50051'; -const cert = fs.readFileSync('path/to/cert.pem'); -const client = v1.NewClientWithCustomCert('t_your_token_here_1234567deadbeef', endpoint, cert); +const endpoint = "localhost:50051"; +const cert = fs.readFileSync("path/to/cert.pem"); +const client = v1.NewClientWithCustomCert("t_your_token_here_1234567deadbeef", endpoint, cert); ``` ### Performing an API call @@ -80,36 +81,36 @@ Because of the verbosity of these types, we recommend writing your own functions The `create` method on generated classes takes attributes as input and defaults unspecified attributes to their empty value. This allows you to create request messages, for example, by specifying only relevant fields and leaves optional fields empty. ```js -import { v1 } from '@authzed/authzed-node'; +import { v1 } from "@authzed/authzed-node"; -const client = v1.NewClient('token') +const client = v1.NewClient("token"); // Create the relationship between the resource and the user. const firstPost = v1.ObjectReference.create({ - objectType: "blog/post", - objectId: "1", + objectType: "blog/post", + objectId: "1", }); // Create the user reference. const emilia = v1.ObjectReference.create({ - objectType: "blog/user", - objectId: "emilia", + objectType: "blog/user", + objectId: "emilia", }); // Create the subject reference using the user reference const subject = v1.SubjectReference.create({ - object: emilia, + object: emilia, }); const checkPermissionRequest = v1.CheckPermissionRequest.create({ - resource: firstPost, - permission: "read", - subject, + resource: firstPost, + permission: "read", + subject, }); client.checkPermission(checkPermissionRequest, (err, response) => { - console.log(response); - console.log(err); + console.log(response); + console.log(err); }); ``` @@ -131,9 +132,9 @@ const result = await promiseClient.checkPermission(checkPermissionRequest); For stream-returning methods, including `client.readRelationships()`, `client.lookupResources()` and `client.lookupSubjects()`, the promise-style method will result in an array of response objects once the stream has been closed. ```js -import { v1 } from '@authzed/authzed-node'; +import { v1 } from "@authzed/authzed-node"; -const client = v1.NewClient('token'); +const client = v1.NewClient("token"); const { promises: promiseClient } = client; // access client.promises const results = await promiseClient.readRelationships(/** req **/); @@ -150,28 +151,28 @@ writing context will fail silently and the relations won't reflect the context. An example: ```js -import { protobuf } from '@authzed/authzed-node'; +import { protobuf } from "@authzed/authzed-node"; const { Struct } = protobuf; const writeRequest = WriteRelationshipsRequest.create({ -updates: [ - RelationshipUpdate.create({ - relationship: Relationship.create({ - resource: resource, - relation: "caveated_viewer", - subject: SubjectReference.create({ - object: testUser, - }), - optionalCaveat: ContextualizedCaveat.create({ - caveatName: "has_special_attribute", - context: Struct.fromJson({ - special: true, + updates: [ + RelationshipUpdate.create({ + relationship: Relationship.create({ + resource: resource, + relation: "caveated_viewer", + subject: SubjectReference.create({ + object: testUser, + }), + optionalCaveat: ContextualizedCaveat.create({ + caveatName: "has_special_attribute", + context: Struct.fromJson({ + special: true, + }), }), }), + operation: RelationshipUpdate_Operation.CREATE, }), - operation: RelationshipUpdate_Operation.CREATE, - }), -], + ], }); const response = await client.writeRelationships(writeRequest); diff --git a/docker-compose.yaml b/docker-compose.yaml index 4091947..6aff71e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,7 +2,7 @@ services: spicedb-servetesting: image: quay.io/authzed/spicedb:latest - ports: ['50051:50051'] + ports: ["50051:50051"] command: serve-testing healthcheck: test: ["CMD", "/usr/local/bin/grpc_health_probe", "-addr=:50051"] diff --git a/eslint.config.mjs b/eslint.config.mjs index c3410d5..52643e8 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,32 +9,36 @@ import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: js.configs.recommended, - allConfig: js.configs.all + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, }); -export default [{ +export default [ + { ignores: ["src/authzedapi/**/*", "src/*.test.js"], -}, ...compat.extends( + }, + ...compat.extends( "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", -), { + ), + { plugins: { - "@typescript-eslint": typescriptEslint, + "@typescript-eslint": typescriptEslint, }, languageOptions: { - globals: { - ...globals.browser, - ...globals.commonjs, - }, + globals: { + ...globals.browser, + ...globals.commonjs, + }, - parser: tsParser, - ecmaVersion: 12, - sourceType: "script", + parser: tsParser, + ecmaVersion: 12, + sourceType: "script", }, rules: {}, -}]; \ No newline at end of file + }, +]; diff --git a/examples/v1/example.js b/examples/v1/example.js index 612e55e..126506d 100644 --- a/examples/v1/example.js +++ b/examples/v1/example.js @@ -1,7 +1,7 @@ -import { v1 } from '@authzed/authzed-node'; +import { v1 } from "@authzed/authzed-node"; // set up it on localhost like this: // const client = v1.NewClient('mytokenhere', 'localhost:50051', v1.ClientSecurity.INSECURE_LOCALHOST_ALLOWED); -const client = v1.NewClient('mytokenhere'); +const client = v1.NewClient("mytokenhere"); const { promises: promiseClient } = client; // access client.promises after instantiating client const writeRequest = v1.WriteSchemaRequest.create({ @@ -28,14 +28,14 @@ const writeRelationshipRequest = v1.WriteRelationshipsRequest.create({ v1.RelationshipUpdate.create({ relationship: v1.Relationship.create({ resource: v1.ObjectReference.create({ - objectType: 'test/document', - objectId: 'somedocument', + objectType: "test/document", + objectId: "somedocument", }), - relation: 'viewer', + relation: "viewer", subject: v1.SubjectReference.create({ object: v1.ObjectReference.create({ - objectType: 'test/user', - objectId: 'fred', + objectType: "test/user", + objectId: "fred", }), }), }), @@ -54,19 +54,19 @@ await new Promise((resolve, reject) => { // Check a permission. const checkPermissionRequest = v1.CheckPermissionRequest.create({ resource: v1.ObjectReference.create({ - objectType: 'test/document', - objectId: 'somedocument', + objectType: "test/document", + objectId: "somedocument", }), - permission: 'view', + permission: "view", subject: v1.SubjectReference.create({ object: v1.ObjectReference.create({ - objectType: 'test/user', - objectId: 'fred', + objectType: "test/user", + objectId: "fred", }), }), consistency: v1.Consistency.create({ requirement: { - oneofKind: 'fullyConsistent', + oneofKind: "fullyConsistent", fullyConsistent: true, }, }), @@ -80,8 +80,7 @@ const checkResult = await new Promise((resolve, reject) => { }); console.log( - checkResult.permissionship === - v1.CheckPermissionResponse_Permissionship.HAS_PERMISSION + checkResult.permissionship === v1.CheckPermissionResponse_Permissionship.HAS_PERMISSION, ); // Lookup Resources @@ -89,20 +88,20 @@ console.log( const lookupResourcesRequest = v1.LookupResourcesRequest.create({ consistency: v1.Consistency.create({ requirement: { - oneofKind: 'fullyConsistent', + oneofKind: "fullyConsistent", fullyConsistent: true, }, }), - resourceObjectType: 'test/document', - permission: 'view', + resourceObjectType: "test/document", + permission: "view", subject: v1.SubjectReference.create({ object: v1.ObjectReference.create({ - objectType: 'test/user', - objectId: 'fred', + objectType: "test/user", + objectId: "fred", }), }), }); -const results = await promiseClient.lookupResources(lookupResourcesRequest) +const results = await promiseClient.lookupResources(lookupResourcesRequest); console.log(results); diff --git a/js-dist/package.json b/js-dist/package.json index d359764..28b54fa 100644 --- a/js-dist/package.json +++ b/js-dist/package.json @@ -1,8 +1,7 @@ { "name": "@authzed/authzed-js-node", - "author": "authzed", "version": "0.19.0", - "type": "module", + "private": false, "description": "authzed js client for nodejs", "keywords": [ "authorization", @@ -13,10 +12,11 @@ "spicedb", "zanzibar" ], - "main": "src/index.js", - "repository": "https://github.com/authzed/authzed-node", "license": "Apache-2.0", - "private": false, + "author": "authzed", + "repository": "https://github.com/authzed/authzed-node", + "type": "module", + "main": "src/index.js", "scripts": { "test": "../scripts/run-and-test.sh", "only-run-tests": "vitest" diff --git a/package.json b/package.json index 867162e..4b55f3e 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,7 @@ { "name": "@authzed/authzed-node", - "author": "authzed", "version": "0.19.0", - "type": "module", + "private": false, "description": "authzed client for nodejs", "keywords": [ "authorization", @@ -13,6 +12,16 @@ "spicedb", "zanzibar" ], + "license": "Apache-2.0", + "author": "authzed", + "repository": { + "type": "git", + "url": "git+https://github.com/authzed/authzed-node.git" + }, + "files": [ + "dist" + ], + "type": "module", "main": "dist/src/index.cjs", "module": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -28,15 +37,6 @@ "import": "./dist/src/index.js" } }, - "repository": { - "type": "git", - "url": "git+https://github.com/authzed/authzed-node.git" - }, - "license": "Apache-2.0", - "private": false, - "files": [ - "dist" - ], "scripts": { "test": "./scripts/run-and-test.sh", "only-run-tests": "vitest", diff --git a/src/full-promises.test.ts b/src/full-promises.test.ts index 88f1a4f..c1bd114 100644 --- a/src/full-promises.test.ts +++ b/src/full-promises.test.ts @@ -73,9 +73,7 @@ describe("a check following a write of schema and relationships", () => { }), }); - const permissionResponse = await v1client.checkPermission( - checkPermissionRequest, - ); + const permissionResponse = await v1client.checkPermission(checkPermissionRequest); expect(permissionResponse?.permissionship).toBe( v1.CheckPermissionResponse_Permissionship.HAS_PERMISSION, ); diff --git a/src/types.ts b/src/types.ts index afc2022..7bd8a50 100644 --- a/src/types.ts +++ b/src/types.ts @@ -44,18 +44,9 @@ export type StreamCall = ( * Matches a gRPC method that returns a ClientWritableStream */ export type WritableStreamCall = ( - metadata: - | Metadata - | CallOptions - | ((err: ServiceError | null, value?: U | undefined) => void), - options?: - | CallOptions - | ((err: ServiceError | null, value?: U | undefined) => void) - | undefined, - callback?: ( - err: ServiceError | null, - value?: U | undefined, - ) => void | undefined, + metadata: Metadata | CallOptions | ((err: ServiceError | null, value?: U | undefined) => void), + options?: CallOptions | ((err: ServiceError | null, value?: U | undefined) => void) | undefined, + callback?: (err: ServiceError | null, value?: U | undefined) => void | undefined, ) => ClientWritableStream; /** @@ -82,15 +73,10 @@ export type PromisifiedCall = ( */ export type PromisifiedCallbackClient = { [prop in Exclude< - Exclude< - keyof ExcludeReturnType>, - keyof Client - >, + Exclude>, keyof Client>, // eslint-disable-next-line @typescript-eslint/no-explicit-any keyof PickReturnType> - >]: C[prop] extends UnaryCall - ? PromisifiedCall - : never; + >]: C[prop] extends UnaryCall ? PromisifiedCall : never; }; /** @@ -100,9 +86,7 @@ export type PromisifiedStreamClient = { [prop in Exclude< keyof PickReturnType>, keyof Client - >]: C[prop] extends StreamCall - ? PromisifiedCall - : never; + >]: C[prop] extends StreamCall ? PromisifiedCall : never; }; export type WritableStreamClient = { @@ -110,9 +94,7 @@ export type WritableStreamClient = { // eslint-disable-next-line @typescript-eslint/no-explicit-any keyof PickReturnType>, keyof Client - >]: C[prop] extends WritableStreamCall - ? WritableStreamCall - : never; + >]: C[prop] extends WritableStreamCall ? WritableStreamCall : never; }; /** diff --git a/src/util.ts b/src/util.ts index a0139ee..8d1ebe8 100644 --- a/src/util.ts +++ b/src/util.ts @@ -21,10 +21,7 @@ class ComposedChannelCredentials extends grpc.ChannelCredentials { } compose(callCredentials: grpc.CallCredentials) { const combinedCallCredentials = this.callCreds.compose(callCredentials); - return new ComposedChannelCredentials( - this.channelCredentials, - combinedCallCredentials, - ); + return new ComposedChannelCredentials(this.channelCredentials, combinedCallCredentials); } _isSecure(): boolean { return false; @@ -120,8 +117,7 @@ function createClientCreds( if ( security === ClientSecurity.SECURE || security === ClientSecurity.INSECURE_PLAINTEXT_CREDENTIALS || - (security === ClientSecurity.INSECURE_LOCALHOST_ALLOWED && - endpoint.startsWith("localhost:")) + (security === ClientSecurity.INSECURE_LOCALHOST_ALLOWED && endpoint.startsWith("localhost:")) ) { creds.push( grpc.credentials.createFromMetadataGenerator((_, callback) => { @@ -200,12 +196,7 @@ export function deadlineInterceptor(timeoutInMS: number): grpc.Interceptor { const authzedEndpoint = "grpc.authzed.com:443"; -export { - createClientCreds, - createClientCredsWithCustomCert, - authzedEndpoint, - promisifyStream, -}; +export { createClientCreds, createClientCredsWithCustomCert, authzedEndpoint, promisifyStream }; export default { createClientCreds, createClientCredsWithCustomCert, diff --git a/src/v1-promise.test.ts b/src/v1-promise.test.ts index 8cb7290..75ff825 100644 --- a/src/v1-promise.test.ts +++ b/src/v1-promise.test.ts @@ -51,9 +51,7 @@ describe("a check with an unknown namespace", () => { await client.checkPermission(checkPermissionRequest); throw new Error("Error should be thrown"); } catch (err) { - expect((err as grpc.ServiceError)?.code).toBe( - grpc.status.FAILED_PRECONDITION, - ); + expect((err as grpc.ServiceError)?.code).toBe(grpc.status.FAILED_PRECONDITION); client.close(); } }); @@ -359,9 +357,7 @@ describe("a check with an known namespace", () => { }), }); - const checkResponse = await client.checkPermission( - checkPermissionRequest, - ); + const checkResponse = await client.checkPermission(checkPermissionRequest); expect(checkResponse?.permissionship).toBe( CheckPermissionResponse_Permissionship.HAS_PERMISSION, ); @@ -474,9 +470,7 @@ describe("Lookup APIs", () => { ); const result = await client.lookupSubjects(lookupSubjectRequest); - expect(["someuser", "someuser2"]).toContain( - result[0].subject?.subjectObjectId, - ); + expect(["someuser", "someuser2"]).toContain(result[0].subject?.subjectObjectId); client.close(); }); @@ -505,9 +499,7 @@ describe("Lookup APIs", () => { new grpc.Metadata(), {} as grpc.CallOptions, ); - expect(["someuser", "someuser2"]).toContain( - result[0].subject?.subjectObjectId, - ); + expect(["someuser", "someuser2"]).toContain(result[0].subject?.subjectObjectId); const resStream = await client.lookupResources( lookupResourceRequest, diff --git a/src/v1.test.ts b/src/v1.test.ts index 0bbe47f..b3097e1 100644 --- a/src/v1.test.ts +++ b/src/v1.test.ts @@ -74,8 +74,7 @@ describe("a check with an known namespace", () => { generateTestToken("v1-namespace"), "localhost:50051", ClientSecurity.INSECURE_LOCALHOST_ALLOWED, - PreconnectServices.PERMISSIONS_SERVICE | - PreconnectServices.SCHEMA_SERVICE, + PreconnectServices.PERMISSIONS_SERVICE | PreconnectServices.SCHEMA_SERVICE, ); const request = WriteSchemaRequest.create({ @@ -154,13 +153,10 @@ describe("a check with an known namespace", () => { }), }); - client.checkPermission( - checkPermissionRequest, - function (err, response) { - expect(err).toBe(null); - resolve(response); - }, - ); + client.checkPermission(checkPermissionRequest, function (err, response) { + expect(err).toBe(null); + resolve(response); + }); }); }) .then((response) => { @@ -269,13 +265,10 @@ describe("a check with an known namespace", () => { context: Struct.fromJson({ special: true }), }); - client.checkPermission( - checkPermissionRequest, - function (err, response) { - expect(err).toBe(null); - resolve(response); - }, - ); + client.checkPermission(checkPermissionRequest, function (err, response) { + expect(err).toBe(null); + resolve(response); + }); }); }) .then((response) => { @@ -363,11 +356,7 @@ describe("Lookup APIs", () => { it("can lookup subjects", () => new Promise((done, fail) => { - const client = NewClient( - token, - "localhost:50051", - ClientSecurity.INSECURE_LOCALHOST_ALLOWED, - ); + const client = NewClient(token, "localhost:50051", ClientSecurity.INSECURE_LOCALHOST_ALLOWED); const request = LookupSubjectsRequest.create({ resource: ObjectReference.create({ @@ -387,9 +376,7 @@ describe("Lookup APIs", () => { const resStream = client.lookupSubjects(request); resStream.on("data", function (subject: LookupSubjectsResponse) { - expect(["someuser", "someuser2"]).toContain( - subject.subject?.subjectObjectId, - ); + expect(["someuser", "someuser2"]).toContain(subject.subject?.subjectObjectId); }); resStream.on("end", function () { @@ -409,11 +396,7 @@ describe("Lookup APIs", () => { it("can lookup resources", () => new Promise((done, fail) => { - const client = NewClient( - token, - "localhost:50051", - ClientSecurity.INSECURE_LOCALHOST_ALLOWED, - ); + const client = NewClient(token, "localhost:50051", ClientSecurity.INSECURE_LOCALHOST_ALLOWED); const request = LookupResourcesRequest.create({ subject: SubjectReference.create({ @@ -526,11 +509,7 @@ describe("Experimental Service", () => { it("can bulk import relationships", () => new Promise((done, fail) => { - const client = NewClient( - token, - "localhost:50051", - ClientSecurity.INSECURE_LOCALHOST_ALLOWED, - ); + const client = NewClient(token, "localhost:50051", ClientSecurity.INSECURE_LOCALHOST_ALLOWED); const writeStream = client.bulkImportRelationships((err, value) => { if (err) { @@ -583,11 +562,7 @@ describe("Experimental Service", () => { it("can bulk export relationships", () => new Promise((done, fail) => { - const client = NewClient( - token, - "localhost:50051", - ClientSecurity.INSECURE_LOCALHOST_ALLOWED, - ); + const client = NewClient(token, "localhost:50051", ClientSecurity.INSECURE_LOCALHOST_ALLOWED); const resource = ObjectReference.create({ objectType: "test/document", @@ -639,35 +614,32 @@ describe("Experimental Service", () => { }), ); - resStream.on( - "data", - function (response: BulkExportRelationshipsResponse) { - expect(response.relationships).toEqual([ - { - relation: "viewer", - resource: { - objectType: "test/document", - objectId: "somedocument", - }, - subject: { - optionalRelation: "", - object: { objectType: "test/user", objectId: "someuser" }, - }, + resStream.on("data", function (response: BulkExportRelationshipsResponse) { + expect(response.relationships).toEqual([ + { + relation: "viewer", + resource: { + objectType: "test/document", + objectId: "somedocument", }, - { - relation: "viewer", - resource: { - objectType: "test/document", - objectId: "somedocument", - }, - subject: { - optionalRelation: "", - object: { objectType: "test/user", objectId: "someuser2" }, - }, + subject: { + optionalRelation: "", + object: { objectType: "test/user", objectId: "someuser" }, }, - ]); - }, - ); + }, + { + relation: "viewer", + resource: { + objectType: "test/document", + objectId: "somedocument", + }, + subject: { + optionalRelation: "", + object: { objectType: "test/user", objectId: "someuser2" }, + }, + }, + ]); + }); resStream.on("end", function () { client.close(); @@ -693,14 +665,10 @@ describe("Experimental Service", () => { testToken, "localhost:50051", ClientSecurity.INSECURE_LOCALHOST_ALLOWED, - PreconnectServices.SCHEMA_SERVICE | - PreconnectServices.PERMISSIONS_SERVICE, + PreconnectServices.SCHEMA_SERVICE | PreconnectServices.PERMISSIONS_SERVICE, ); - const writeSpy = vi.spyOn( - PermissionsServiceClient.prototype, - "writeRelationships", - ); + const writeSpy = vi.spyOn(PermissionsServiceClient.prototype, "writeRelationships"); const schema = ` definition test/user {} @@ -765,20 +733,15 @@ describe("Experimental Service", () => { expect(writeSpy).toHaveBeenCalledTimes(1); - const actualRequest = writeSpy.mock - .calls[0][0] as WriteRelationshipsRequest; + const actualRequest = writeSpy.mock.calls[0][0] as WriteRelationshipsRequest; expect(actualRequest.updates).toEqual(updates); expect(actualRequest.optionalTransactionMetadata).toBeDefined(); - expect(actualRequest.optionalTransactionMetadata).toEqual( - transactionMetadata, - ); + expect(actualRequest.optionalTransactionMetadata).toEqual(transactionMetadata); const transactionIdField = - actualRequest.optionalTransactionMetadata?.fields?.[ - "transaction_id" - ]; + actualRequest.optionalTransactionMetadata?.fields?.["transaction_id"]; expect(transactionIdField?.kind?.oneofKind).toBe("stringValue"); if (transactionIdField?.kind?.oneofKind === "stringValue") { expect(transactionIdField.kind.stringValue).toBe("test-tx-123"); @@ -849,16 +812,12 @@ describe("createStructFromObject unit tests", () => { struct.fields.nestedProp.kind.structValue; expect(nestedStruct).toBeTruthy(); if (nestedStruct) { - expect(nestedStruct.fields.innerString?.kind.oneofKind).toBe( - "stringValue", - ); + expect(nestedStruct.fields.innerString?.kind.oneofKind).toBe("stringValue"); expect( nestedStruct.fields.innerString?.kind.oneofKind === "stringValue" && nestedStruct.fields.innerString?.kind.stringValue, ).toBe("world"); - expect(nestedStruct.fields.innerNumber?.kind.oneofKind).toBe( - "numberValue", - ); + expect(nestedStruct.fields.innerNumber?.kind.oneofKind).toBe("numberValue"); expect( nestedStruct.fields.innerNumber?.kind.oneofKind === "numberValue" && nestedStruct.fields.innerNumber?.kind.numberValue, diff --git a/src/v1.ts b/src/v1.ts index 3e40799..46751e0 100644 --- a/src/v1.ts +++ b/src/v1.ts @@ -30,10 +30,7 @@ export { ImportedPbStruct as PbStruct, ImportedPbNullValue as PbNullValue }; export { ErrorReason } from "./authzedapi/authzed/api/v1/error_reason.js"; // A merge of the three generated gRPC clients, with their base methods omitted -export type ZedDefaultClientInterface = OmitBaseMethods< - PermissionsServiceClient, - grpc.Client -> & +export type ZedDefaultClientInterface = OmitBaseMethods & OmitBaseMethods & OmitBaseMethods & OmitBaseMethods & @@ -42,14 +39,13 @@ export type ZedDefaultClientInterface = OmitBaseMethods< Pick; // The promisified version of the interface -export type ZedPromiseClientInterface = - PromisifiedClient & - PromisifiedClient & - PromisifiedClient & - PromisifiedClient & - PromisifiedClient & - PromisifiedClient & - Pick; +export type ZedPromiseClientInterface = PromisifiedClient & + PromisifiedClient & + PromisifiedClient & + PromisifiedClient & + PromisifiedClient & + PromisifiedClient & + Pick; // A combined client containing the root gRPC client methods and a promisified set at a "promises" key export type ZedClientInterface = ZedDefaultClientInterface & { @@ -89,11 +85,7 @@ class ZedClient implements ProxyHandler { }; if (preconnect & PreconnectServices.PERMISSIONS_SERVICE) { - this.acl = new PermissionsServiceClient( - this.endpoint, - this.creds, - options, - ); + this.acl = new PermissionsServiceClient(this.endpoint, this.creds, options); } if (preconnect & PreconnectServices.SCHEMA_SERVICE) { this.ns = new SchemaServiceClient(this.endpoint, this.creds, options); @@ -102,11 +94,7 @@ class ZedClient implements ProxyHandler { this.watch = new WatchServiceClient(this.endpoint, this.creds, options); } if (preconnect & PreconnectServices.WATCH_PERMISSIONS_SERVICE) { - this.watchPermissions = new WatchPermissionsServiceClient( - this.endpoint, - this.creds, - options, - ); + this.watchPermissions = new WatchPermissionsServiceClient(this.endpoint, this.creds, options); } if (preconnect & PreconnectServices.WATCH_PERMISSIONSETS_SERVICE) { this.watchPermissionSets = new WatchPermissionSetsServiceClient( @@ -116,11 +104,7 @@ class ZedClient implements ProxyHandler { ); } if (preconnect & PreconnectServices.EXPERIMENTAL_SERVICE) { - this.experimental = new ExperimentalServiceClient( - this.endpoint, - this.creds, - options, - ); + this.experimental = new ExperimentalServiceClient(this.endpoint, this.creds, options); } } @@ -130,10 +114,7 @@ class ZedClient implements ProxyHandler { preconnect: PreconnectServices, options: grpc.ClientOptions | undefined, ) { - return new Proxy( - {} as any, - new ZedClient(endpoint, creds, preconnect, options), - ); + return new Proxy({} as any, new ZedClient(endpoint, creds, preconnect, options)); } close = () => { @@ -157,11 +138,7 @@ class ZedClient implements ProxyHandler { // pick ACL by default since its the most likely be used. if (typeof name === "symbol") { if (this.acl === undefined) { - this.acl = new PermissionsServiceClient( - this.endpoint, - this.creds, - this.options, - ); + this.acl = new PermissionsServiceClient(this.endpoint, this.creds, this.options); } return (this.acl as any)[name]; @@ -170,11 +147,7 @@ class ZedClient implements ProxyHandler { // Otherwise, lazily instantiate the client based on the method requested. if (name in PermissionsServiceClient.prototype) { if (this.acl === undefined) { - this.acl = new PermissionsServiceClient( - this.endpoint, - this.creds, - this.options, - ); + this.acl = new PermissionsServiceClient(this.endpoint, this.creds, this.options); } return (this.acl as any)[name]; @@ -182,11 +155,7 @@ class ZedClient implements ProxyHandler { if (name in SchemaServiceClient.prototype) { if (this.ns === undefined) { - this.ns = new SchemaServiceClient( - this.endpoint, - this.creds, - this.options, - ); + this.ns = new SchemaServiceClient(this.endpoint, this.creds, this.options); } return (this.ns as any)[name as string]; @@ -194,11 +163,7 @@ class ZedClient implements ProxyHandler { if (name in WatchServiceClient.prototype) { if (this.watch === undefined) { - this.watch = new WatchServiceClient( - this.endpoint, - this.creds, - this.options, - ); + this.watch = new WatchServiceClient(this.endpoint, this.creds, this.options); } return (this.watch as any)[name]; @@ -230,11 +195,7 @@ class ZedClient implements ProxyHandler { if (name in ExperimentalServiceClient.prototype) { if (this.experimental === undefined) { - this.experimental = new ExperimentalServiceClient( - this.endpoint, - this.creds, - this.options, - ); + this.experimental = new ExperimentalServiceClient(this.endpoint, this.creds, this.options); } return (this.experimental as any)[name]; @@ -265,10 +226,7 @@ class ZedPromiseClient implements ProxyHandler { "watchPermissions", "watchPermissionSets", ]); - private writableStreamMethods = new Set([ - "bulkImportRelationships", - "importBulkRelationships", - ]); + private writableStreamMethods = new Set(["bulkImportRelationships", "importBulkRelationships"]); constructor(client: ZedDefaultClientInterface) { this.client = client; @@ -283,16 +241,13 @@ class ZedPromiseClient implements ProxyHandler { const clientMethod = (this.client as any)[name as string]; if (clientMethod !== undefined) { if (this.streamMethods.has(name as string)) { - this.promiseCache[name as string] = promisifyStream( - clientMethod, - this.client, - ); + this.promiseCache[name as string] = promisifyStream(clientMethod, this.client); } else if (this.writableStreamMethods.has(name as string)) { this.promiseCache[name as string] = clientMethod.bind(this.client); } else if (typeof clientMethod === "function") { - this.promiseCache[name as string] = promisify( - (this.client as any)[name as string], - ).bind(this.client); + this.promiseCache[name as string] = promisify((this.client as any)[name as string]).bind( + this.client, + ); } else { return clientMethod; } @@ -314,10 +269,7 @@ class ZedCombinedClient implements ProxyHandler { private client: ZedDefaultClientInterface; private promiseClient: ZedPromiseClientInterface; - constructor( - client: ZedDefaultClientInterface, - promiseClient: ZedPromiseClientInterface, - ) { + constructor(client: ZedDefaultClientInterface, promiseClient: ZedPromiseClientInterface) { this.client = client; this.promiseClient = promiseClient; } @@ -419,13 +371,9 @@ export function createStructFromObject(data: JsonObject): ImportedPbStruct { } catch (error) { if ( error instanceof Error && - error.message.includes( - "Unable to parse message google.protobuf.Struct from JSON", - ) + error.message.includes("Unable to parse message google.protobuf.Struct from JSON") ) { - throw new Error( - "Input data for createStructFromObject must be a non-null object.", - ); + throw new Error("Input data for createStructFromObject must be a non-null object."); } throw error; } diff --git a/tsconfig.json b/tsconfig.json index ecc8549..811dec5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,15 +9,8 @@ "rootDir": "./", "declaration": true, "outDir": "./dist", - "typeRoots": [ - "node_modules/@types" - ] + "typeRoots": ["node_modules/@types"] }, - "include": [ - "src" - ], - "exclude": [ - "node_modules", - "src/**/*.test.*/*" - ] + "include": ["src"], + "exclude": ["node_modules", "src/**/*.test.*/*"] }