From 446fe7d98e50277e3ea6941709d2b9373c0e8517 Mon Sep 17 00:00:00 2001 From: Patrik Date: Wed, 21 Sep 2022 17:34:18 +0200 Subject: [PATCH] feat: OPL typescript library on npm --- .github/workflows/npm_publish_grpc_client.yml | 4 +- .github/workflows/npm_publish_typelib.yml | 39 ++++++++++ contrib/namespace-type-lib/index.d.ts | 34 ++++++++ contrib/namespace-type-lib/package-lock.json | 58 ++++++++++++++ contrib/namespace-type-lib/package.json | 21 +++++ contrib/namespace-type-lib/test.ts | 36 +++++++++ contrib/namespace-type-lib/tsconfig.json | 7 ++ contrib/rewrites-example/lib.ts | 18 ----- contrib/rewrites-example/namespaces.keto.ts | 2 +- contrib/rewrites-example/namespaces.ts | 78 +++++++++++++++++++ contrib/rewrites-example/package-lock.json | 56 +++++++++++++ contrib/rewrites-example/package.json | 7 ++ contrib/rewrites-example/tsconfig.json | 7 ++ 13 files changed, 346 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/npm_publish_typelib.yml create mode 100644 contrib/namespace-type-lib/index.d.ts create mode 100644 contrib/namespace-type-lib/package-lock.json create mode 100644 contrib/namespace-type-lib/package.json create mode 100644 contrib/namespace-type-lib/test.ts create mode 100644 contrib/namespace-type-lib/tsconfig.json delete mode 100644 contrib/rewrites-example/lib.ts create mode 100644 contrib/rewrites-example/namespaces.ts create mode 100644 contrib/rewrites-example/package-lock.json create mode 100644 contrib/rewrites-example/package.json create mode 100644 contrib/rewrites-example/tsconfig.json diff --git a/.github/workflows/npm_publish_grpc_client.yml b/.github/workflows/npm_publish_grpc_client.yml index ee42b0a3d..0b24182f1 100644 --- a/.github/workflows/npm_publish_grpc_client.yml +++ b/.github/workflows/npm_publish_grpc_client.yml @@ -28,8 +28,8 @@ jobs: env: RELEASE_VERSION: ${{ github.event.inputs.version || github.ref }} - run: |- - git config --local user.email "zepatrik@users.noreply.github.com" - git config --local user.name "zepatrik" + git config --global user.email "60093411+ory-bot@users.noreply.github.com" + git config --global user.name "ory-bot" git add proto/package.json git commit -m "autogen: bump node gRPC client version" - run: |- diff --git a/.github/workflows/npm_publish_typelib.yml b/.github/workflows/npm_publish_typelib.yml new file mode 100644 index 000000000..667d8239f --- /dev/null +++ b/.github/workflows/npm_publish_typelib.yml @@ -0,0 +1,39 @@ +name: Publish OPL typelib to npm + +on: + release: + types: + - created + workflow_dispatch: + inputs: + version: + required: true + description: The version to release + +jobs: + btp: + runs-on: ubuntu-latest + name: Publish + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "14" + registry-url: "https://registry.npmjs.org" + - run: sudo npm i -g npm@7 + - name: Bump version + run: |- + cd contrib/namespace-type-lib + cat <<< $(jq '.version = (env.RELEASE_VERSION | sub("(^refs/tags/v)|(^v)"; ""))' package.json) > package.json + env: + RELEASE_VERSION: ${{ github.event.inputs.version || github.ref }} + - run: |- + git config --global user.email "60093411+ory-bot@users.noreply.github.com" + git config --global user.name "ory-bot" + git add contrib/namespace-type-lib/package.json + git commit -m "autogen: bump OPL typelib" + - run: |- + cd contrib/namespace-type-lib + npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN_AENEASR }} diff --git a/contrib/namespace-type-lib/index.d.ts b/contrib/namespace-type-lib/index.d.ts new file mode 100644 index 000000000..d21bc4725 --- /dev/null +++ b/contrib/namespace-type-lib/index.d.ts @@ -0,0 +1,34 @@ +/// + +declare interface Boolean {} +declare interface String {} +declare interface Number {} +declare interface Function {} +declare interface Object {} +declare interface IArguments {} +declare interface RegExp {} + +declare interface Array { + includes(element: T): boolean + traverse(iteratorfn: (element: T) => boolean): boolean +} + +interface context { + subject: never +} + +interface namespace { + related?: { [relation: string]: namespace[] } + permits?: { [method: string]: (ctx: context) => boolean } +} + +declare module "@ory/keto-namespace-types" { + export type Context = context + + export type Namespace = namespace + + export type SubjectSet< + A extends Namespace, + R extends keyof A["related"], + > = A["related"][R] extends Array ? T : never +} diff --git a/contrib/namespace-type-lib/package-lock.json b/contrib/namespace-type-lib/package-lock.json new file mode 100644 index 000000000..bc04f9bea --- /dev/null +++ b/contrib/namespace-type-lib/package-lock.json @@ -0,0 +1,58 @@ +{ + "name": "@ory/keto-namespace-types", + "version": "0.9.0-alpha.0", + "lockfileVersion": 2, + "requires": true, + "dev": true, + "packages": { + "": { + "name": "@ory/keto-namespace-types", + "version": "0.9.0-alpha.0", + "dev": true, + "devDependencies": { + "@ory/keto-namespace-types": "file:./", + "typescript": "^4.7.4" + } + }, + "node_modules/@ory/keto-namespace-types": { + "resolved": "", + "link": true + }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + } + }, + "dependencies": { + "@ory/keto-namespace-types": { + "version": "file:", + "requires": { + "@ory/keto-namespace-types": "file:", + "typescript": "^4.7.4" + }, + "dependencies": { + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true + } + } + }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true + } + } +} diff --git a/contrib/namespace-type-lib/package.json b/contrib/namespace-type-lib/package.json new file mode 100644 index 000000000..15cadd178 --- /dev/null +++ b/contrib/namespace-type-lib/package.json @@ -0,0 +1,21 @@ +{ + "name": "@ory/keto-namespace-types", + "version": "0.9.0-alpha.0", + "description": "TypeScript definitions for Ory Keto Namespaces", + "homepage": "https://www.ory.sh/keto", + "bugs": "https://github.com/ory/keto/issues", + "main": "", + "types": "index.d.ts", + "files": [ + "index.d.ts", + "tsconfig.json" + ], + "scripts": { + "test": "tsc --types --noEmit --noLib test.ts" + }, + "dependencies": {}, + "devDependencies": { + "@ory/keto-namespace-types": "file:./", + "typescript": "^4.7.4" + } +} diff --git a/contrib/namespace-type-lib/test.ts b/contrib/namespace-type-lib/test.ts new file mode 100644 index 000000000..f17f5713d --- /dev/null +++ b/contrib/namespace-type-lib/test.ts @@ -0,0 +1,36 @@ +import { Namespace, SubjectSet, Context } from "@ory/keto-namespace-types" + +// This test is not really a valid config, but rather a check of the types. +class User implements Namespace { + related: { + friends: User[] + } +} + +class Group implements Namespace { + related: { + members: (User | Group)[] + } + + permits = { + isMember: (ctx: Context): boolean => + this.related.members.traverse((m) => + m instanceof User ? m == ctx.subject : m.permits.isMember(ctx), + ), + } +} + +class File implements Namespace { + related: { + viewers: (User | SubjectSet)[] + } + + permits = { + view: (ctx: Context): boolean => + this.related.viewers.traverse((p) => + p instanceof User + ? p.related.friends.includes(ctx.subject) + : p.permits.isMember(ctx), + ) || this.related.viewers.includes(ctx.subject), + } +} diff --git a/contrib/namespace-type-lib/tsconfig.json b/contrib/namespace-type-lib/tsconfig.json new file mode 100644 index 000000000..7599d6be6 --- /dev/null +++ b/contrib/namespace-type-lib/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "noLib": true, + "noEmit": true, + "types": [] + } +} diff --git a/contrib/rewrites-example/lib.ts b/contrib/rewrites-example/lib.ts deleted file mode 100644 index ebf6d5bf1..000000000 --- a/contrib/rewrites-example/lib.ts +++ /dev/null @@ -1,18 +0,0 @@ -/// - -type Context = { subject: never } - -interface Namespace { - related?: { [relation: string]: Namespace[] } - permits?: { [method: string]: (ctx: Context) => boolean } -} - -interface Array { - includes(element: Namespace): boolean - traverse(iteratorfn: (element: Namespace) => boolean): boolean -} - -type SubjectSet< - A extends Namespace, - R extends keyof A["related"], -> = A["related"][R] extends Array ? T : never diff --git a/contrib/rewrites-example/namespaces.keto.ts b/contrib/rewrites-example/namespaces.keto.ts index 1884336d3..5e67f2604 100644 --- a/contrib/rewrites-example/namespaces.keto.ts +++ b/contrib/rewrites-example/namespaces.keto.ts @@ -1,4 +1,4 @@ -/// +import { Namespace, SubjectSet, Context } from "@ory/keto-namespace-types" class User implements Namespace { related: { diff --git a/contrib/rewrites-example/namespaces.ts b/contrib/rewrites-example/namespaces.ts new file mode 100644 index 000000000..703cfaca0 --- /dev/null +++ b/contrib/rewrites-example/namespaces.ts @@ -0,0 +1,78 @@ +import { Namespace, SubjectSet, Context } from "@ory/keto-namespace-types" + +// Declare new namespaces as classes that implement `Namespaces` +class User implements Namespace { + related: { + // Define relations to other objects here. + // Examples: + // + // parents: (File | Folder)[] + // viewers: SubjectSet[] + } + + permits = { + // Define permissions here. These can be derived from the relations above. + // Examples: + // + // view: (ctx: Context): boolean => + // this.related.viewers.includes(ctx.subject) || + // this.related.parents.traverse((p) => p.permits.view(ctx)), + } +} + +class Group implements Namespace { + related: { + // Define relations to other objects here. + // Examples: + // + // parents: (File | Folder)[] + // viewers: SubjectSet[] + } + + permits = { + // Define permissions here. These can be derived from the relations above. + // Examples: + // + // view: (ctx: Context): boolean => + // this.related.viewers.includes(ctx.subject) || + // this.related.parents.traverse((p) => p.permits.view(ctx)), + } +} + +class Folder implements Namespace { + related: { + // Define relations to other objects here. + // Examples: + // + // parents: (File | Folder)[] + // viewers: SubjectSet[] + } + + permits = { + // Define permissions here. These can be derived from the relations above. + // Examples: + // + // view: (ctx: Context): boolean => + // this.related.viewers.includes(ctx.subject) || + // this.related.parents.traverse((p) => p.permits.view(ctx)), + } +} + +class File implements Namespace { + related: { + // Define relations to other objects here. + // Examples: + // + // parents: (File | Folder)[] + // viewers: SubjectSet[] + } + + permits = { + // Define permissions here. These can be derived from the relations above. + // Examples: + // + // view: (ctx: Context): boolean => + // this.related.viewers.includes(ctx.subject) || + // this.related.parents.traverse((p) => p.permits.view(ctx)), + } +} diff --git a/contrib/rewrites-example/package-lock.json b/contrib/rewrites-example/package-lock.json new file mode 100644 index 000000000..7fe9354fe --- /dev/null +++ b/contrib/rewrites-example/package-lock.json @@ -0,0 +1,56 @@ +{ + "name": "rewrites-example", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@ory/keto-namespace-types": "file:../namespace-type-lib", + "typescript": "latest" + } + }, + "../../../../../../namespace-type-lib": { + "extraneous": true + }, + "../namespace-type-lib": { + "version": "0.9.0-alpha.0", + "dev": true, + "devDependencies": { + "@ory/keto-namespace-types": "file:./", + "typescript": "^4.7.4" + } + }, + "node_modules/@ory/keto-namespace-types": { + "resolved": "../namespace-type-lib", + "link": true + }, + "node_modules/typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + } + }, + "dependencies": { + "@ory/keto-namespace-types": { + "version": "file:../namespace-type-lib", + "requires": { + "@ory/keto-namespace-types": "file:", + "typescript": "^4.7.4" + } + }, + "typescript": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "dev": true + } + } +} diff --git a/contrib/rewrites-example/package.json b/contrib/rewrites-example/package.json new file mode 100644 index 000000000..f2eed3d92 --- /dev/null +++ b/contrib/rewrites-example/package.json @@ -0,0 +1,7 @@ +{ + "private": true, + "devDependencies": { + "@ory/keto-namespace-types": "file:../namespace-type-lib", + "typescript": "latest" + } +} diff --git a/contrib/rewrites-example/tsconfig.json b/contrib/rewrites-example/tsconfig.json new file mode 100644 index 000000000..7599d6be6 --- /dev/null +++ b/contrib/rewrites-example/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "noLib": true, + "noEmit": true, + "types": [] + } +}