Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TS/JS/JSON formatting to the project #2543

Merged
merged 6 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Apply prettier to the project
0523bf8b36a937348f1bb79eceda2463a5c220b5
34 changes: 34 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Lint

on:
pull_request:
push:
branches:
- main

jobs:
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
show-progress: false
- name: Setup Linux
run: |
export DEBIAN_FRONTEND=noninteractive
wget https://apt.llvm.org/llvm.sh
sed -i '/apt-get install/d' llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 18
sudo apt-get install -y --no-install-recommends clang-format-18
- name: Install pnpm
uses: pnpm/action-setup@v4
# The pnpm version will be determined by the `packageManager` field in `.npmrc`
- name: Install project deps with pnpm
run: |
pnpm i
- name: Lint
run: |
python3 ./tools/cross/format.py --check
env:
CLANG_FORMAT: clang-format-18
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
samples/nodejs-compat-streams-split2/split2.js
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 80,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5"
}
45 changes: 45 additions & 0 deletions githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

set -euo pipefail


source "$(dirname -- $BASH_SOURCE)/../tools/unix/find-python3.sh"
PYTHON_PATH=$(get_python3)
if [[ -z "$PYTHON_PATH" ]]; then
echo
echo "python3 is required for formatting and was not found"
echo
echo "ERROR: you must either install python3 and try pushing again or run `git push` with `--no-verify`"
exit 1
fi

while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA
do
git fetch origin master &>/dev/null
# Check all local changes, not present in origin/master, for lint.
set +e
$PYTHON_PATH "$(dirname -- $BASH_SOURCE)/../tools/cross/format.py" --check git --source $LOCAL_SHA --target origin/master
EXIT_CODE=$?
set -e
case $EXIT_CODE in
0)
# No lint.
;;
1)
echo
echo "ERROR: changes in $LOCAL_REF have lint which may fail CI."
echo
echo "To fix lint:"
echo " python3 ./tools/cross/format.py"
echo
exit 1
;;
2)
echo
echo "ERROR: failed to run format.py, Pass '--no-verify' or '-n' to skip."
echo
exit 1
;;
esac
done

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "@cloudflare/workerd-root",
"private": true,
"scripts": {
"lint": "eslint types/src"
"lint": "eslint types/src",
"format": "prettier"
},
"dependencies": {
"capnp-ts": "^0.7.0",
Expand Down
1 change: 1 addition & 0 deletions samples/nodejs-compat-diagnosticschannel/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default {
async fetch(request) {
doSomething();

// prettier-ignore
console.log(c.runStores(1, (...args) => {
console.log(this, ...args, als1.getStore(), als2.getStore());
return 1;
Expand Down
62 changes: 31 additions & 31 deletions src/cloudflare/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
{
"env": {
"es2022": true,
"worker": true
"es2022": true,
"worker": true
},
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/strict"
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/strict"
],
"overrides": [],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"project": "src/cloudflare/tsconfig.json"
},
"ecmaVersion": "latest",
"sourceType": "module",
"project": "src/cloudflare/tsconfig.json"
},
"rules": {
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/explicit-member-accessibility": "error",
"@typescript-eslint/explicit-module-boundary-types": "error",
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/prefer-enum-initializers": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/restrict-template-expressions": "warn",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-extraneous-class": "off",
"@typescript-eslint/unified-signatures": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"args": "all",
"argsIgnorePattern": "^_",
"caughtErrors": "all",
"caughtErrorsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
]
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/explicit-member-accessibility": "error",
"@typescript-eslint/explicit-module-boundary-types": "error",
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/prefer-enum-initializers": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/restrict-template-expressions": "warn",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-extraneous-class": "off",
"@typescript-eslint/unified-signatures": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"args": "all",
"argsIgnorePattern": "^_",
"caughtErrors": "all",
"caughtErrorsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
]
}
}
6 changes: 5 additions & 1 deletion src/cloudflare/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
// Licensed under the Apache 2.0 license found in the LICENSE file or at:
// https://opensource.org/licenses/Apache-2.0

export { AiOptions, InferenceUpstreamError, Ai } from 'cloudflare-internal:ai-api';
export {
AiOptions,
InferenceUpstreamError,
Ai,
} from 'cloudflare-internal:ai-api';
108 changes: 61 additions & 47 deletions src/cloudflare/internal/ai-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@
// https://opensource.org/licenses/Apache-2.0

interface Fetcher {
fetch: typeof fetch
fetch: typeof fetch;
}

interface AiError {
internalCode: number
message: string
name: string
description: string
internalCode: number;
message: string;
name: string;
description: string;
}

export type SessionOptions = { // Deprecated, do not use this
export type SessionOptions = {
// Deprecated, do not use this
extraHeaders?: object;
}
};

export type GatewayOptions = {
id: string;
cacheTtl?: number
skipCache?: boolean
cacheTtl?: number;
skipCache?: boolean;
metadata?: Record<string, number | string | boolean | null | bigint>;
}
};

export type AiOptions = {
gateway?: GatewayOptions;
Expand All @@ -33,17 +34,17 @@ export type AiOptions = {
* @deprecated this option is deprecated, do not use this
*/
sessionOptions?: SessionOptions;
}
};

export class InferenceUpstreamError extends Error {
public constructor(message: string, name = "InferenceUpstreamError") {
public constructor(message: string, name = 'InferenceUpstreamError') {
super(message);
this.name = name;
}
}

export class Ai {
private readonly fetcher: Fetcher
private readonly fetcher: Fetcher;

/*
* @deprecated this option is deprecated, do not use this
Expand All @@ -54,11 +55,14 @@ export class Ai {
public lastRequestId: string | null = null;

public constructor(fetcher: Fetcher) {
this.fetcher = fetcher
this.fetcher = fetcher;
}

public async fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
return this.fetcher.fetch(input, init)
public async fetch(
input: RequestInfo | URL,
init?: RequestInit
): Promise<Response> {
return this.fetcher.fetch(input, init);
}

public async run(
Expand All @@ -67,73 +71,83 @@ export class Ai {
options: AiOptions = {}
): Promise<Response | ReadableStream<Uint8Array> | object | null> {
this.options = options;
this.lastRequestId = "";
this.lastRequestId = '';

// This removes some unwanted options from getting sent in the body
const cleanedOptions = (({ prefix, extraHeaders, sessionOptions, ...object }): object => object)(this.options || {});
const cleanedOptions = (({
prefix,
extraHeaders,
sessionOptions,
...object
}): object => object)(this.options || {});

const body = JSON.stringify({
inputs,
options: cleanedOptions
options: cleanedOptions,
});

const fetchOptions = {
method: "POST",
method: 'POST',
body: body,
headers: {
...(this.options?.sessionOptions?.extraHeaders || {}),
...(this.options?.extraHeaders || {}),
"content-type": "application/json",
"cf-consn-sdk-version": "2.0.0",
"cf-consn-model-id": `${this.options.prefix ? `${this.options.prefix}:` : ""}${model}`,
'content-type': 'application/json',
'cf-consn-sdk-version': '2.0.0',
'cf-consn-model-id': `${this.options.prefix ? `${this.options.prefix}:` : ''}${model}`,
},
};

const res = await this.fetcher.fetch("http://workers-binding.ai/run?version=3", fetchOptions);
const res = await this.fetcher.fetch(
'http://workers-binding.ai/run?version=3',
fetchOptions
);

this.lastRequestId = res.headers.get("cf-ai-req-id");
this.lastRequestId = res.headers.get('cf-ai-req-id');

if (inputs['stream']) {
if (!res.ok) {
throw await this._parseError(res)
throw await this._parseError(res);
}

return res.body;

} else {
if (!res.ok || !res.body) {
throw await this._parseError(res)
throw await this._parseError(res);
}

const contentType = res.headers.get("content-type");
const contentType = res.headers.get('content-type');

if (contentType === "application/json") {
return (await res.json() as object);
if (contentType === 'application/json') {
return (await res.json()) as object;
}

return res.body;
}
}

/*
* @deprecated this method is deprecated, do not use this
*/
public getLogs(): string[] {
return []
}

private async _parseError(res: Response): Promise<InferenceUpstreamError> {
const content = await res.text()
/*
* @deprecated this method is deprecated, do not use this
*/
public getLogs(): string[] {
return [];
}

try {
const parsedContent = (JSON.parse(content)) as AiError
return new InferenceUpstreamError(`${parsedContent.internalCode}: ${parsedContent.description}`, parsedContent.name);
} catch {
return new InferenceUpstreamError(content);
}
private async _parseError(res: Response): Promise<InferenceUpstreamError> {
const content = await res.text();

try {
const parsedContent = JSON.parse(content) as AiError;
return new InferenceUpstreamError(
`${parsedContent.internalCode}: ${parsedContent.description}`,
parsedContent.name
);
} catch {
return new InferenceUpstreamError(content);
}
}
}

export default function makeBinding(env: { fetcher: Fetcher }): Ai {
return new Ai(env.fetcher)
return new Ai(env.fetcher);
}
Loading
Loading