Compare commits

...

2 Commits

Author SHA1 Message Date
51edcc50f6 updated tsp/package-lock.json 2025-03-04 07:40:53 -05:00
05414dc29d typespec-drf project 2025-03-04 07:39:44 -05:00
14 changed files with 4614 additions and 3 deletions

22
tsp/package-lock.json generated
View File

@@ -8,7 +8,7 @@
"name": "@foo/cms", "name": "@foo/cms",
"version": "0.1.0", "version": "0.1.0",
"devDependencies": { "devDependencies": {
"@pojagi/typespec-drf": "../../typespec-drf", "@pojagi/typespec-drf": "../typespec-drf",
"@typespec/compiler": "latest", "@typespec/compiler": "latest",
"@typespec/http": "latest", "@typespec/http": "latest",
"@typespec/http-server-csharp": "latest", "@typespec/http-server-csharp": "latest",
@@ -40,6 +40,24 @@
} }
}, },
"../../typespec-drf": { "../../typespec-drf": {
"name": "@pojagi/typespec-drf",
"version": "0.1.0",
"extraneous": true,
"devDependencies": {
"@types/node": "latest",
"@typespec/compiler": "latest",
"@typespec/http": "latest",
"eslint": "latest",
"prettier": "^3.3.3",
"typescript": "^5.3.3",
"typescript-eslint": "latest"
},
"peerDependencies": {
"@typespec/compiler": "latest",
"@typespec/http": "latest"
}
},
"../typespec-drf": {
"name": "@pojagi/typespec-drf", "name": "@pojagi/typespec-drf",
"version": "0.1.0", "version": "0.1.0",
"dev": true, "dev": true,
@@ -739,7 +757,7 @@
} }
}, },
"node_modules/@pojagi/typespec-drf": { "node_modules/@pojagi/typespec-drf": {
"resolved": "../../typespec-drf", "resolved": "../typespec-drf",
"link": true "link": true
}, },
"node_modules/@sigstore/bundle": { "node_modules/@sigstore/bundle": {

View File

@@ -23,6 +23,6 @@
"@typespec/http-server-js": "latest", "@typespec/http-server-js": "latest",
"counterfact": "^1.2.0", "counterfact": "^1.2.0",
"multiview": "^3.0.1", "multiview": "^3.0.1",
"@pojagi/typespec-drf": "../../typespec-drf" "@pojagi/typespec-drf": "../typespec-drf"
} }
} }

9
typespec-drf/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
# MacOS
.DS_Store
# Default TypeSpec output
tsp-output/
dist/
# Dependency directories
node_modules/

View File

@@ -0,0 +1,11 @@
// @ts-check
import eslint from "@eslint/js";
import tsEslint from "typescript-eslint";
export default tsEslint.config(
{
ignores: ["**/dist/**/*", "**/.temp/**/*"],
},
eslint.configs.recommended,
...tsEslint.configs.recommended,
);

4384
typespec-drf/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
typespec-drf/package.json Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "@pojagi/typespec-drf",
"version": "0.1.0",
"type": "module",
"main": "dist/src/index.js",
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
"./testing": {
"types": "./dist/src/testing/index.d.ts",
"default": "./dist/src/testing/index.js"
}
},
"peerDependencies": {
"@typespec/compiler": "latest",
"@typespec/http": "latest"
},
"devDependencies": {
"@types/node": "latest",
"eslint": "latest",
"typescript-eslint": "latest",
"@typespec/compiler": "latest",
"@typespec/http": "latest",
"typescript": "^5.3.3",
"prettier": "^3.3.3"
},
"scripts": {
"build": "tsc",
"watch": "tsc --watch",
"test": "node --test --no-experimental-strip-types 'dist/**/*.test.js' ",
"lint": "eslint src/ test/ --report-unused-disable-directives --max-warnings=0",
"lint:fix": "eslint . --report-unused-disable-directives --fix",
"format": "prettier . --write",
"format:check": "prettier --check ."
},
"private": true
}

View File

@@ -0,0 +1,8 @@
trailingComma: "all"
printWidth: 120
quoteProps: "consistent"
endOfLine: lf
arrowParens: always
plugins:
- "./node_modules/@typespec/prettier-plugin-typespec/dist/index.js"
overrides: [{ "files": "*.tsp", "options": { "parser": "typespec" } }]

View File

@@ -0,0 +1,42 @@
import { EmitContext, emitFile, resolvePath, navigateProgram, Model, Operation, Service, listServices } from "@typespec/compiler";
import { getHttpService } from "@typespec/http";
export async function $onEmit(context: EmitContext) {
if (!context.program.compilerOptions.noEmit) {
const services = listServices(context.program);
if (!services.length) {
throw new Error("No services defined.");
}
if (services.length > 1) {
throw new Error("Only one service permitted.");
}
const service = services[0];
console.log(context.program.getGlobalNamespaceType().interfaces);
console.log(Object.keys(service));
console.log(service.type);
// navigateProgram(context.program, {
// // model(m: Model) {
// // if (m.name === "ProblemDetails") {
// // console.log(m.properties.get("status")?.type);
// // console.log(Array.from(m.properties.keys()));
// // console.log(Object.keys(m));
// // }
// // }
// operation(o: Operation) {
// console.log(o.name, Object.keys(o), o.namespace);
// }
// });
///////
await emitFile(context.program, {
path: resolvePath(context.emitterOutputDir, "output.txt"),
content: "Hello world\n",
});
}
}

View File

@@ -0,0 +1,2 @@
export { $onEmit } from "./emitter.js";
export { $lib } from "./lib.js";

8
typespec-drf/src/lib.ts Normal file
View File

@@ -0,0 +1,8 @@
import { createTypeSpecLibrary } from "@typespec/compiler";
export const $lib = createTypeSpecLibrary({
name: "@pojagi/@pojagi/typespec-drf",
diagnostics: {},
});
export const { reportDiagnostic, createDiagnostic } = $lib;

View File

@@ -0,0 +1,8 @@
import { resolvePath } from "@typespec/compiler";
import { createTestLibrary, TypeSpecTestLibrary } from "@typespec/compiler/testing";
import { fileURLToPath } from "url";
export const TspDrfTestLibrary: TypeSpecTestLibrary = createTestLibrary({
name: "@pojagi/typespec-drf",
packageRoot: resolvePath(fileURLToPath(import.meta.url), "../../../../"),
});

View File

@@ -0,0 +1,18 @@
import { strictEqual } from "node:assert";
import { describe, it } from "node:test";
import { emit } from "./test-host.js";
describe("hello", () => {
it("emit output.txt with content hello world", async () => {
const results = await emit(`
using TypeSpec.Http;
@service({
title: "My Foo Service"
})
@route("/api/v1")
namespace Foo;
`);
strictEqual(results["output.txt"], "Hello world\n");
});
});

View File

@@ -0,0 +1,47 @@
import { Diagnostic, resolvePath } from "@typespec/compiler";
import {
createTestHost,
createTestWrapper,
expectDiagnosticEmpty,
} from "@typespec/compiler/testing";
import { TspDrfTestLibrary } from "../src/testing/index.js";
export async function createTspDrfTestHost() {
return createTestHost({
libraries: [TspDrfTestLibrary],
});
}
export async function createTspDrfTestRunner() {
const host = await createTspDrfTestHost();
return createTestWrapper(host, {
compilerOptions: {
noEmit: false,
emit: ["@pojagi/typespec-drf"],
},
});
}
export async function emitWithDiagnostics(
code: string
): Promise<[Record<string, string>, readonly Diagnostic[]]> {
const runner = await createTspDrfTestRunner();
await runner.compileAndDiagnose(code, {
outputDir: "tsp-output",
});
const emitterOutputDir = "./tsp-output/@pojagi/typespec-drf";
const files = await runner.program.host.readDir(emitterOutputDir);
const result: Record<string, string> = {};
for (const file of files) {
result[file] = (await runner.program.host.readFile(resolvePath(emitterOutputDir, file))).text;
}
return [result, runner.program.diagnostics];
}
export async function emit(code: string): Promise<Record<string, string>> {
const [result, diagnostics] = await emitWithDiagnostics(code);
expectDiagnosticEmpty(diagnostics);
return result;
}

View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"useDefineForClassFields": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022"],
"rootDir": ".",
"outDir": "dist",
"sourceMap": true,
"declaration": true,
/* Linting */
"strict": true
},
"include": ["src", "test"]
}