@pikku/openapi-parser 0.12.19 → 0.12.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/dist/auth-config.d.ts +3 -3
- package/dist/codegen.js +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +8 -6
- package/src/auth-config.ts +0 -94
- package/src/codegen.test.ts +0 -973
- package/src/codegen.ts +0 -1670
- package/src/index.ts +0 -26
- package/src/naming.test.ts +0 -260
- package/src/naming.ts +0 -369
- package/src/openapi-to-zod-schema.test.ts +0 -664
- package/src/openapi-to-zod-schema.ts +0 -583
- package/src/parse-openapi.test.ts +0 -316
- package/src/parse-openapi.ts +0 -467
- package/src/zod-codegen.ts +0 -9
- package/tsconfig.json +0 -12
- package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# @pikku/openapi-parser
|
|
2
2
|
|
|
3
|
+
## 0.12.21
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4c7a1b5: Run the monorepo's own scripts through bun instead of yarn. What moves is the
|
|
8
|
+
package manager each package's `prepublishOnly` and build scripts invoke, plus
|
|
9
|
+
the two manifest fixes bun needs to resolve the tree: `uWebSockets.js` is
|
|
10
|
+
declared with an explicit `github:` specifier, and `@pikku/uws-handler` marks
|
|
11
|
+
its `uWebSockets.js` peer optional so a bun install of a consumer that brings
|
|
12
|
+
its own uWS app does not try to fetch it from the registry.
|
|
13
|
+
|
|
14
|
+
Three published behaviours change, all of them cases where an isolated
|
|
15
|
+
`node_modules` or bun as the runtime had been papered over by yarn's hoisting:
|
|
16
|
+
|
|
17
|
+
- `@pikku/migrator-sql` turns foreign keys on when it opens a sqlite database
|
|
18
|
+
through bun. `node:sqlite` enforces them by default and `bun:sqlite` does not,
|
|
19
|
+
which silently turned every `ON DELETE CASCADE` into a no-op under
|
|
20
|
+
`bunx --bun pikku`.
|
|
21
|
+
- `@pikku/cli` resolves a deploy provider against the project being deployed
|
|
22
|
+
rather than against wherever the CLI itself is installed, which is what its
|
|
23
|
+
own "is not installed" error asks the user to arrange.
|
|
24
|
+
- `@pikku/cli` treats a specifier a runtime hands straight back — bun does this
|
|
25
|
+
for the modules it implements itself — as not resolved from the project, so
|
|
26
|
+
it falls back rather than loading the runtime's own copy.
|
|
27
|
+
|
|
28
|
+
## 0.12.20
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- 6eef0a0: Bump every dependency to its latest compatible minor/patch across the monorepo.
|
|
33
|
+
- 266e3bc: `#pikku` is a namespace, not a module: one subpath per wiring
|
|
34
|
+
|
|
35
|
+
The bare `#pikku` specifier resolved to `.pikku/pikku-types.gen.ts`, a hub that
|
|
36
|
+
re-exported all twelve wiring leaves with `export *` — undoing the split the
|
|
37
|
+
leaves exist for, each of which still says so in its own generated header
|
|
38
|
+
("HTTP-specific type definitions for tree-shaking optimization"). Reaching that
|
|
39
|
+
hub put 33 distinct `@pikku/core` subpaths into the module graph, and neither
|
|
40
|
+
consumer could drop them again: bundlers keep `export *` chains because the app
|
|
41
|
+
declares no `sideEffects`, and Node and tsx do not tree-shake at all, so an app
|
|
42
|
+
with no queues still executed `@pikku/core/queue` at boot.
|
|
43
|
+
|
|
44
|
+
The hub is gone. An app now imports the leaf the name belongs to —
|
|
45
|
+
`#pikku/function`, `#pikku/http`, `#pikku/workflow` — and a project's `imports`
|
|
46
|
+
map declares two patterns, because both resolvers pick the more specific one:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
"#pikku/*.js": "./.pikku/*.ts",
|
|
50
|
+
"#pikku/*": "./.pikku/*/index.ts"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A source tree names the `.ts` on both. Webpack, esbuild and Bun all rewrite a
|
|
54
|
+
`.js` specifier to the `.ts` beside it for a relative import but not for an
|
|
55
|
+
imports-map target, so a `.js` target there resolves to a file that does not
|
|
56
|
+
exist. The two places that keep `.js` are the ones where it is the real file: a
|
|
57
|
+
published addon, whose map points into `dist`, and a project that imports a
|
|
58
|
+
declaration-only generated file such as `pikku-rpc-wirings-map.gen.d.ts`, where
|
|
59
|
+
naming the `.js` lets the type resolver's own mapping reach the `.d.ts`.
|
|
60
|
+
|
|
61
|
+
`pikku` generates the leaf indexes and removes the hub, and `pikku validate`
|
|
62
|
+
reports a barrel import as an error. The split also turns the addon boundary
|
|
63
|
+
from advice into a rule: an addon never generates the wiring leaves, so
|
|
64
|
+
`#pikku/http` fails at the specifier rather than yielding "no exported member"
|
|
65
|
+
from a hub that quietly dropped the re-export.
|
|
66
|
+
|
|
3
67
|
## 0.12.19
|
|
4
68
|
|
|
5
69
|
### Patch Changes
|
package/dist/auth-config.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export declare const DelegatedLoginSchema: z.ZodObject<{
|
|
|
14
14
|
loginPath: z.ZodString;
|
|
15
15
|
loginMethod: z.ZodDefault<z.ZodString>;
|
|
16
16
|
credentials: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
17
|
+
apiKey: "apiKey";
|
|
17
18
|
email: "email";
|
|
18
19
|
password: "password";
|
|
19
|
-
apiKey: "apiKey";
|
|
20
20
|
}>>>;
|
|
21
21
|
apiKeyHeader: z.ZodDefault<z.ZodString>;
|
|
22
22
|
tokenPath: z.ZodString;
|
|
@@ -36,17 +36,17 @@ export declare const DelegatedLoginSchema: z.ZodObject<{
|
|
|
36
36
|
export declare const AuthConfigSchema: z.ZodObject<{
|
|
37
37
|
headerName: z.ZodOptional<z.ZodString>;
|
|
38
38
|
headerFormat: z.ZodOptional<z.ZodEnum<{
|
|
39
|
-
raw: "raw";
|
|
40
39
|
bearer: "bearer";
|
|
40
|
+
raw: "raw";
|
|
41
41
|
}>>;
|
|
42
42
|
extraHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
43
43
|
delegated: z.ZodOptional<z.ZodObject<{
|
|
44
44
|
loginPath: z.ZodString;
|
|
45
45
|
loginMethod: z.ZodDefault<z.ZodString>;
|
|
46
46
|
credentials: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
47
|
+
apiKey: "apiKey";
|
|
47
48
|
email: "email";
|
|
48
49
|
password: "password";
|
|
49
|
-
apiKey: "apiKey";
|
|
50
50
|
}>>>;
|
|
51
51
|
apiKeyHeader: z.ZodDefault<z.ZodString>;
|
|
52
52
|
tokenPath: z.ZodString;
|
package/dist/codegen.js
CHANGED
|
@@ -520,7 +520,7 @@ function generateFunctionFile(named, parsed, vars, ctx, spec, flags, inlineSchem
|
|
|
520
520
|
if (needsZod) {
|
|
521
521
|
lines.push("import { z } from 'zod'");
|
|
522
522
|
}
|
|
523
|
-
lines.push("import { pikkuSessionlessFunc } from '#pikku'");
|
|
523
|
+
lines.push("import { pikkuSessionlessFunc } from '#pikku/function'");
|
|
524
524
|
if (errorClasses.length > 0) {
|
|
525
525
|
lines.push(`import { ${errorClasses.join(', ')} } from '@pikku/core/errors'`);
|
|
526
526
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { parseOpenAPISpec, computeContractHash, type ParsedSpec, } from './parse-openapi.js';
|
|
2
2
|
export { generateAddonFromOpenAPI } from './codegen.js';
|
|
3
3
|
export { loadAuthConfig, type AuthConfig, type DelegatedLoginConfig, } from './auth-config.js';
|
|
4
|
-
export { type NamedOperation
|
|
4
|
+
export { type NamedOperation } from './naming.js';
|
|
5
5
|
export { type OpenAPISchema, type ZodCodegenContext, createContext, schemaToZod, schemaVarName, sanitizeTypeName, } from './openapi-to-zod-schema.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/openapi-parser",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.21",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/pikkujs/pikku.git",
|
|
7
|
+
"directory": "packages/openapi-parser"
|
|
8
|
+
},
|
|
4
9
|
"description": "OpenAPI spec parser and code generator for Pikku",
|
|
5
10
|
"author": "yasser.fadl@gmail.com",
|
|
6
11
|
"license": "MIT",
|
|
@@ -12,16 +17,13 @@
|
|
|
12
17
|
"ncu": "npx npm-check-updates",
|
|
13
18
|
"build": "tsc -b",
|
|
14
19
|
"test": "node --import tsx --test src/**/*.test.ts",
|
|
15
|
-
"prepublishOnly": "
|
|
20
|
+
"prepublishOnly": "bun run build"
|
|
16
21
|
},
|
|
17
22
|
"exports": {
|
|
18
23
|
".": "./dist/index.js"
|
|
19
24
|
},
|
|
20
25
|
"dependencies": {
|
|
21
|
-
"yaml": "^2.
|
|
26
|
+
"yaml": "^2.9.0",
|
|
22
27
|
"zod": "^4"
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"typescript": "^6.0.3"
|
|
26
28
|
}
|
|
27
29
|
}
|
package/src/auth-config.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Operator/agent-supplied auth configuration that overrides or augments an
|
|
3
|
-
* OpenAPI spec's securitySchemes. Needed for real-world enterprise specs that
|
|
4
|
-
* carry no machine-readable auth at all (auth described only in prose), or
|
|
5
|
-
* that use a custom auth header the spec doesn't declare.
|
|
6
|
-
*/
|
|
7
|
-
import { readFile } from 'fs/promises'
|
|
8
|
-
import { z } from 'zod'
|
|
9
|
-
|
|
10
|
-
export const DelegatedClaimsSchema = z.object({
|
|
11
|
-
/** Where identity claims live: the decoded login-JWT payload, or the login response body. */
|
|
12
|
-
source: z.enum(['jwt', 'response']),
|
|
13
|
-
/** Dot-path to the stable upstream user id (e.g. 'user._id'). */
|
|
14
|
-
externalId: z.string(),
|
|
15
|
-
email: z.string(),
|
|
16
|
-
/** One dot-path, or several joined with a space (e.g. first + last name). */
|
|
17
|
-
name: z.union([z.string(), z.array(z.string())]).optional(),
|
|
18
|
-
role: z.string().optional(),
|
|
19
|
-
tenantId: z.string().optional(),
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
export const DelegatedLoginSchema = z.object({
|
|
23
|
-
/** Spec-relative path of the login operation (e.g. '/users/login'). */
|
|
24
|
-
loginPath: z.string(),
|
|
25
|
-
loginMethod: z.string().default('post'),
|
|
26
|
-
/** Which credential fields the login accepts. email/password go in the JSON body; apiKey in a header. */
|
|
27
|
-
credentials: z
|
|
28
|
-
.array(z.enum(['email', 'password', 'apiKey']))
|
|
29
|
-
.default(['email', 'password']),
|
|
30
|
-
/** Header carrying the apiKey when 'apiKey' is a supported credential. */
|
|
31
|
-
apiKeyHeader: z.string().default('x-api-key'),
|
|
32
|
-
/** Dot-path to the token in the login response (e.g. 'token'). */
|
|
33
|
-
tokenPath: z.string(),
|
|
34
|
-
/** Dot-path to an epoch-seconds expiry in the response; defaults to the JWT `exp` claim when source is jwt. */
|
|
35
|
-
expiresAtPath: z.string().optional(),
|
|
36
|
-
claims: DelegatedClaimsSchema,
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
export const AuthConfigSchema = z.object({
|
|
40
|
-
/** Auth header the API expects on authenticated calls (e.g. 'authentication'). Overrides the spec. */
|
|
41
|
-
headerName: z.string().optional(),
|
|
42
|
-
/** 'raw' sends the bare token; 'bearer' prefixes it. Default: bearer for Authorization, raw for custom headers. */
|
|
43
|
-
headerFormat: z.enum(['raw', 'bearer']).optional(),
|
|
44
|
-
/**
|
|
45
|
-
* Static headers sent on EVERY request — the delegated login call and all
|
|
46
|
-
* proxied API calls. Needed for upstreams that route on a header, e.g. a
|
|
47
|
-
* multi-tenant API that resolves the tenant from an `Origin` header and
|
|
48
|
-
* rejects requests without it.
|
|
49
|
-
*/
|
|
50
|
-
extraHeaders: z.record(z.string(), z.string()).optional(),
|
|
51
|
-
/** Present when end-users sign in with their existing upstream credentials (delegated login). */
|
|
52
|
-
delegated: DelegatedLoginSchema.optional(),
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
export type DelegatedLoginConfig = z.infer<typeof DelegatedLoginSchema>
|
|
56
|
-
export type AuthConfig = z.infer<typeof AuthConfigSchema>
|
|
57
|
-
|
|
58
|
-
/** The effective value template for the auth header. */
|
|
59
|
-
export const authHeaderValue = (
|
|
60
|
-
config: AuthConfig,
|
|
61
|
-
tokenExpr: string
|
|
62
|
-
): { header: string; value: string } => {
|
|
63
|
-
const header = config.headerName ?? 'Authorization'
|
|
64
|
-
const format =
|
|
65
|
-
config.headerFormat ??
|
|
66
|
-
(config.headerName && config.headerName !== 'Authorization'
|
|
67
|
-
? 'raw'
|
|
68
|
-
: 'bearer')
|
|
69
|
-
return {
|
|
70
|
-
header,
|
|
71
|
-
value: format === 'bearer' ? `\`Bearer \${${tokenExpr}}\`` : tokenExpr,
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** Load and validate an auth-config JSON file; throws with the zod issue list on mismatch. */
|
|
76
|
-
export async function loadAuthConfig(filePath: string): Promise<AuthConfig> {
|
|
77
|
-
const raw = await readFile(filePath, 'utf-8')
|
|
78
|
-
let parsed: unknown
|
|
79
|
-
try {
|
|
80
|
-
parsed = JSON.parse(raw)
|
|
81
|
-
} catch (error) {
|
|
82
|
-
throw new Error(
|
|
83
|
-
`Auth config ${filePath} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
const result = AuthConfigSchema.safeParse(parsed)
|
|
87
|
-
if (!result.success) {
|
|
88
|
-
const issues = result.error.issues
|
|
89
|
-
.map((i) => ` ${i.path.join('.') || '(root)'}: ${i.message}`)
|
|
90
|
-
.join('\n')
|
|
91
|
-
throw new Error(`Auth config ${filePath} is invalid:\n${issues}`)
|
|
92
|
-
}
|
|
93
|
-
return result.data
|
|
94
|
-
}
|