Skip to content

Commit

Permalink
feat(typescript): Added namespace support
Browse files Browse the repository at this point in the history
Introduces --ts-namespaces option

fix #10
  • Loading branch information
grantila committed Feb 5, 2023
1 parent 2e04875 commit a3a0807
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 13 deletions.
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,48 @@ Usage: typeconv [options] file ...
--(no-)ts-disable-lint-header Output comments for disabling linting (default: true)
--(no-)ts-descriptive-header Output the header comment (default: true)
--(no-)ts-use-unknown Use 'unknown' type instead of 'any' (default: true)
--ts-non-exported <method> Strategy for non-exported types (default: include-if-referenced)

Values:
fail Fail conversion
ignore Don't include non-exported types,
even if referenced
include Include non-exported types
inline Don't include non-exported types,
inline them if necessary.
Will fail on cyclic types
include-if-referenced Include non-exported types only if they
are referenced from exported types

--ts-namespaces <method> Namespace strategy. (default: ignore)

Values:
ignore Ignore namespaces entirely (default).
- When converting from TypeScript, types in namespaces
aren't exported.
- When converting to TypeScript, no attempt to
reconstruct namespaces is performed.
hoist When converting from TypeScript, hoist types inside
namespaces to top-level, so that the types are
included, but without their namespace.
This can cause conflicts, in which case deeper
declarations will be dropped in favor of more top-
level declarations.
In case of same-level (namespace depth) declarations
with the same name, only one will be exported in a
non-deterministic manner.
dot When converting from TypeScript, join the namespaces
and the exported type with a dot (.).
When converting to TypeScript, try to reconstruct
namespaces by splitting the name on dot (.).
underscore When converting from TypeScript, join the namespaces
and the exported type with an underscore (_).
When converting to TypeScript, try to reconstruct
namespaces by splitting the name on underscore (_).
reconstruct-all When converting to TypeScript, try to reconstruct
namespaces by splitting the name on both dot and
underscore.

GraphQL
--gql-unsupported <method> Method to use for unsupported types

Expand All @@ -222,10 +264,17 @@ Usage: typeconv [options] file ...
--st-ref-method <method> SureType reference export method (default: provided)

Values:
no-refs Don't ref anything, inline all types.
no-refs Don't ref anything, inline all types
provided Reference types that are explicitly exported
ref-all Ref all provided types and those with names

--st-missing-ref <method> What to do when detecting an unresolvable reference (default: warn)

Values:
ignore Ignore; skip type or cast to any
warn Same as 'ignore', but warn
error Fail conversion

--(no-)st-inline-types Inline pretty typescript types aside validator code (default: true)
--(no-)st-export-type Export the deduced types (or the pretty types,
depending on --st-inline-types)
Expand Down
14 changes: 7 additions & 7 deletions lib/batch-convert.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ describe( "batch-convert", ( ) =>
);

expect( log.mock.calls.length ).toBe( 2 );
const types1 = JSON.parse( log.mock.calls[ 0 ] );
const types2 = JSON.parse( log.mock.calls[ 1 ] );
const types1 = JSON.parse( log.mock.calls[ 0 ] as any );
const types2 = JSON.parse( log.mock.calls[ 1 ] as any );

expect( types1 ).toMatchSnapshot( );
expect( types2 ).toMatchSnapshot( );
Expand All @@ -62,8 +62,8 @@ describe( "batch-convert", ( ) =>
);

expect( log.mock.calls.length ).toBe( 2 );
const types1 = JSON.parse( log.mock.calls[ 0 ] );
const types2 = JSON.parse( log.mock.calls[ 1 ] );
const types1 = JSON.parse( log.mock.calls[ 0 ] as any );
const types2 = JSON.parse( log.mock.calls[ 1 ] as any );

expect( types1 ).toMatchSnapshot( );
expect( types2 ).toMatchSnapshot( );
Expand All @@ -74,7 +74,7 @@ describe( "batch-convert", ( ) =>
.map( ( line, i ) =>
i === 0
// Absolute local files system, must be aligned with CI/CD
? path.basename( line[ 0 ] )
? path.basename( line[ 0 ] as any )
: line
)
).toMatchSnapshot( );
Expand All @@ -94,8 +94,8 @@ describe( "batch-convert", ( ) =>
);

expect( log.mock.calls.length ).toBe( 2 );
const types1 = JSON.parse( log.mock.calls[ 0 ] );
const types2 = JSON.parse( log.mock.calls[ 1 ] );
const types1 = JSON.parse( log.mock.calls[ 0 ] as any );
const types2 = JSON.parse( log.mock.calls[ 1 ] as any );

expect( types1 ).toMatchSnapshot( );
expect( types2 ).toMatchSnapshot( );
Expand Down
78 changes: 75 additions & 3 deletions lib/bin/typeconv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { fileURLToPath } from "url"
import chalk from "chalk"
import { oppa } from "oppa"
import { stripAnnotations } from "core-types"
import { JsonSchemaToSuretypeOptions } from 'core-types-suretype'
import { FromTsOptions } from "core-types-ts"
import { ExportRefMethod } from "suretype"
import type { JsonSchemaToSuretypeOptions } from "core-types-suretype"
import type { FromTsOptions, ToTsOptions } from "core-types-ts"
import type { ExportRefMethod } from "suretype"

import { makeConverter } from "../converter.js"
import { batchConvertGlob } from "../batch-convert.js"
Expand Down Expand Up @@ -202,6 +202,52 @@ const oppaInstance =
] },
],
} )
.add( {
name: "ts-namespaces",
type: "string",
argumentName: "method",
description: [
"Namespace strategy."
],
default: "ignore",
values: [
{ "ignore": [
"Ignore namespaces entirely (default).",
"- When converting from TypeScript, types in namespaces",
"aren't exported.",
"- When converting to TypeScript, no attempt to",
"reconstruct namespaces is performed.",
] },
{ "hoist": [
"When converting from TypeScript, hoist types inside",
"namespaces to top-level, so that the types are",
"included, but without their namespace.",
"This can cause conflicts, in which case deeper",
"declarations will be dropped in favor of more top-",
"level declarations.",
"In case of same-level (namespace depth) declarations",
"with the same name, only one will be exported in a",
"non-deterministic manner.",
] },
{ "dot": [
"When converting from TypeScript, join the namespaces",
"and the exported type with a dot (.).",
"When converting to TypeScript, try to reconstruct",
"namespaces by splitting the name on dot (.).",
] },
{ "underscore": [
"When converting from TypeScript, join the namespaces",
"and the exported type with an underscore (_).",
"When converting to TypeScript, try to reconstruct",
"namespaces by splitting the name on underscore (_).",
] },
{ "reconstruct-all": [
"When converting to TypeScript, try to reconstruct",
"namespaces by splitting the name on both dot and",
"underscore.",
] },
],
} )

.group( {
name: "GraphQL",
Expand Down Expand Up @@ -364,6 +410,7 @@ const {
"ts-descriptive-header": tsDescriptiveHeader,
"ts-use-unknown": tsUseUnknown,
"ts-non-exported": tsNonExported,
"ts-namespaces": tsNamespaces,

// JSON Schema

Expand Down Expand Up @@ -417,6 +464,29 @@ if ( !ensureType< FromTsOptions[ 'nonExported' ] >(
) )
throw new Error( );


if ( !ensureType<
'ignore' | 'hoist' | 'dot' | 'underscore' | 'reconstruct-all'
>(
tsNamespaces,
'ts-namespaces',
[ 'ignore', 'hoist', 'dot', 'underscore', 'reconstruct-all' ],
printHelp
) )
throw new Error( );

const toTsNamespaces: ToTsOptions[ 'namespaces' ] =
tsNamespaces === 'reconstruct-all' ? 'all' :
tsNamespaces === 'dot' ? 'dot' :
tsNamespaces === 'underscore' ? 'underscore' :
'ignore';

const fromTsNamespaces: FromTsOptions[ 'namespaces' ] =
tsNamespaces === 'hoist' ? 'hoist' :
tsNamespaces === 'dot' ? 'join-dot' :
tsNamespaces === 'underscore' ? 'join-underscore' :
'ignore';

if ( !ensureType< ExportRefMethod | undefined >(
stRefMethod,
'ref-method',
Expand All @@ -438,6 +508,7 @@ const getReader = ( ): Reader =>
return fromType === 'ts'
? getTypeScriptReader( {
nonExported: tsNonExported,
namespaces: fromTsNamespaces,
} )
: fromType === 'jsc'
? getJsonSchemaReader( )
Expand All @@ -464,6 +535,7 @@ const getWriter = ( ): Writer =>
declaration: tsDeclaration,
noDisableLintHeader: tsDisableLintHeader,
noDescriptiveHeader: tsDescriptiveHeader,
namespaces: toTsNamespaces,
useUnknown: tsUseUnknown,
} )
: toType === 'jsc'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"core-types-graphql": "^2.0.0",
"core-types-json-schema": "^2.0.0",
"core-types-suretype": "^3.1.0",
"core-types-ts": "^3.2.0",
"core-types-ts": "^3.3.0",
"globby": "^13.1.3",
"js-yaml": "^4.1.0",
"oppa": "^0.4.0",
Expand Down
12 changes: 11 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3033,6 +3033,16 @@ __metadata:
languageName: node
linkType: hard

"core-types-ts@npm:^3.3.0":
version: 3.3.0
resolution: "core-types-ts@npm:3.3.0"
dependencies:
core-types: ^2.0.1
typescript: ^4.9.5
checksum: f16a340f65e0ea6d4aa8241508de064fb3cc3f87f4ed5ae80a14ab34170a8bd0eae92ea537c4fb702e392df88c13ff6a8858823c3a3707007960c564223007b5
languageName: node
linkType: hard

"core-types@npm:^2.0.1":
version: 2.0.1
resolution: "core-types@npm:2.0.1"
Expand Down Expand Up @@ -6303,7 +6313,7 @@ __metadata:
core-types-graphql: ^2.0.0
core-types-json-schema: ^2.0.0
core-types-suretype: ^3.1.0
core-types-ts: ^3.2.0
core-types-ts: ^3.3.0
cz-conventional-changelog: ^3.3.0
execa: ^6.1.0
globby: ^13.1.3
Expand Down

0 comments on commit a3a0807

Please sign in to comment.