@openpkg-ts/sdk 0.54.5 → 0.54.6

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.
Files changed (2) hide show
  1. package/dist/index.js +93 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3210,6 +3210,88 @@ function isFluentThisType(type) {
3210
3210
  return false;
3211
3211
  return declarations.some((decl) => ts5.isClassDeclaration(decl) || ts5.isClassExpression(decl) || ts5.isInterfaceDeclaration(decl));
3212
3212
  }
3213
+ function containsUnresolvedTypeParameter(type, seen = new Set) {
3214
+ if (seen.has(type))
3215
+ return false;
3216
+ seen.add(type);
3217
+ if (type.flags & ts5.TypeFlags.TypeParameter) {
3218
+ return !isFluentThisType(type);
3219
+ }
3220
+ if (type.isUnionOrIntersection()) {
3221
+ return type.types.some((t) => containsUnresolvedTypeParameter(t, seen));
3222
+ }
3223
+ if (type.aliasTypeArguments) {
3224
+ for (const arg of type.aliasTypeArguments) {
3225
+ if (containsUnresolvedTypeParameter(arg, seen))
3226
+ return true;
3227
+ }
3228
+ }
3229
+ const targs = type.typeArguments;
3230
+ if (targs) {
3231
+ for (const arg of targs) {
3232
+ if (containsUnresolvedTypeParameter(arg, seen))
3233
+ return true;
3234
+ }
3235
+ }
3236
+ if (type.flags & ts5.TypeFlags.IndexedAccess) {
3237
+ const ia = type;
3238
+ return containsUnresolvedTypeParameter(ia.objectType, seen) || containsUnresolvedTypeParameter(ia.indexType, seen);
3239
+ }
3240
+ return false;
3241
+ }
3242
+ function isUtilityOverTypeParameter(type) {
3243
+ const name = type.aliasSymbol?.getName();
3244
+ if (!name || !RESOLVED_UTILITY_TYPES.has(name))
3245
+ return false;
3246
+ const args = type.aliasTypeArguments;
3247
+ if (!args || args.length === 0)
3248
+ return false;
3249
+ return args.some((t) => containsUnresolvedTypeParameter(t));
3250
+ }
3251
+ function writtenUtilityText(type, checker, typeNode) {
3252
+ let node = typeNode;
3253
+ while (node && ts5.isParenthesizedTypeNode(node))
3254
+ node = node.type;
3255
+ const fromNode = writtenTypeText(node);
3256
+ if (fromNode)
3257
+ return fromNode;
3258
+ if (node) {
3259
+ try {
3260
+ const text = scrubImportQualifiers(node.getText().replace(/\s+/g, " ").trim());
3261
+ if (text)
3262
+ return text;
3263
+ } catch {}
3264
+ }
3265
+ const name = type.aliasSymbol?.getName();
3266
+ const args = type.aliasTypeArguments;
3267
+ if (name && args && args.length > 0) {
3268
+ const inner = args.map((t) => scrubImportQualifiers(checker.typeToString(t))).join(", ");
3269
+ return `${name}<${inner}>`;
3270
+ }
3271
+ return renderTypeText(type, checker);
3272
+ }
3273
+ function isReadonlyArrayType(type, typeNode) {
3274
+ let node = typeNode;
3275
+ while (node && ts5.isParenthesizedTypeNode(node))
3276
+ node = node.type;
3277
+ if (node && ts5.isTypeOperatorNode(node) && node.operator === ts5.SyntaxKind.ReadonlyKeyword) {
3278
+ return true;
3279
+ }
3280
+ if (node && ts5.isTypeReferenceNode(node) && typeRefName(node) === "ReadonlyArray") {
3281
+ return true;
3282
+ }
3283
+ const ref = type;
3284
+ const name = ref.target?.getSymbol()?.getName() ?? type.getSymbol()?.getName();
3285
+ return name === "ReadonlyArray";
3286
+ }
3287
+ function withReadonlyArrayHint(schema, type, typeNode) {
3288
+ if (!isReadonlyArrayType(type, typeNode))
3289
+ return schema;
3290
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema))
3291
+ return schema;
3292
+ setSchemaExtension(schema, "x-ts-readonly", true);
3293
+ return schema;
3294
+ }
3213
3295
  function withDepth(ctx, fn) {
3214
3296
  ctx.currentDepth++;
3215
3297
  try {
@@ -3366,6 +3448,9 @@ function buildSchemaInternal(type, checker, ctx, typeNode) {
3366
3448
  if (type.flags & ts5.TypeFlags.TypeParameter) {
3367
3449
  return { "x-ts-type": checker.typeToString(type) };
3368
3450
  }
3451
+ if (isUtilityOverTypeParameter(type)) {
3452
+ return { "x-ts-type": writtenUtilityText(type, checker, typeNode) };
3453
+ }
3369
3454
  if (type.flags & ts5.TypeFlags.StringLiteral) {
3370
3455
  const literal = type.value;
3371
3456
  return { type: "string", enum: [literal] };
@@ -3465,15 +3550,10 @@ function buildSchemaInternal(type, checker, ctx, typeNode) {
3465
3550
  const arrayTypeArgs = checker.getTypeArguments(arrayTypeRef);
3466
3551
  const elementType = arrayTypeArgs?.[0];
3467
3552
  if (elementType) {
3468
- if (ctx) {
3469
- return withDepth(ctx, () => ({
3470
- type: "array",
3471
- items: buildSchema(elementType, checker, ctx)
3472
- }));
3473
- }
3474
- return { type: "array", items: buildSchema(elementType, checker, ctx) };
3553
+ const build = () => withReadonlyArrayHint({ type: "array", items: buildSchema(elementType, checker, ctx) }, type, typeNode);
3554
+ return ctx ? withDepth(ctx, build) : build();
3475
3555
  }
3476
- return { type: "array" };
3556
+ return withReadonlyArrayHint({ type: "array" }, type, typeNode);
3477
3557
  }
3478
3558
  if (checker.isTupleType(type)) {
3479
3559
  const tupleTypeRef = type;
@@ -3995,8 +4075,11 @@ function applyDefault(param, initializer) {
3995
4075
  if (param.schema && typeof param.schema === "object" && !Array.isArray(param.schema)) {
3996
4076
  param.schema.default = extracted.value;
3997
4077
  }
3998
- } else if (param.schema && typeof param.schema === "object" && !Array.isArray(param.schema)) {
3999
- param.schema["x-ts-default"] = extracted.text;
4078
+ } else {
4079
+ param.default = extracted.text;
4080
+ if (param.schema && typeof param.schema === "object" && !Array.isArray(param.schema)) {
4081
+ param.schema["x-ts-default"] = extracted.text;
4082
+ }
4000
4083
  }
4001
4084
  }
4002
4085
  function registerReferencedTypes(type, ctx, depth = 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/sdk",
3
- "version": "0.54.5",
3
+ "version": "0.54.6",
4
4
  "description": "TypeScript API extraction SDK - programmatic primitives for OpenPkg specs",
5
5
  "keywords": [
6
6
  "openpkg",