generated from astrohelm/node-workspace
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
291 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
'use strict'; | ||
|
||
const [test, assert] = [require('node:test'), require('node:assert')]; | ||
const Schema = require('../..'); | ||
|
||
test('[Handyman] Schema with namespace', () => { | ||
const namespace = { User: new Schema('string') }; | ||
const schema = new Schema(['User', 'User'], { namespace }); | ||
const sample = ['Alexander', 'Ivanov']; | ||
|
||
assert.strictEqual(namespace.User.warnings.length + schema.warnings.length, 0); | ||
assert.strictEqual(schema.test(sample).length, 0); | ||
}); | ||
|
||
test('[Handyman] Pull schemas', () => { | ||
const schema = new Schema({ | ||
$id: 'MySchema', | ||
a: 'string', | ||
b: { $id: 'MySubSchema', c: 'number' }, | ||
c: new Schema('?string'), | ||
d: { $type: 'schema', schema: new Schema('number'), $id: 'MySubSchema2' }, | ||
e: { $type: 'schema', schema: new Schema({ $type: 'number', $id: 'MySubSchema3' }) }, | ||
}); | ||
|
||
assert.strictEqual(schema.warnings.length, 0); | ||
assert.strictEqual(!!schema.pull('MySchema'), false); | ||
assert.strictEqual(!!schema.pull('MySubSchema'), true); | ||
assert.strictEqual(!!schema.pull('MySubSchema2'), true); | ||
assert.strictEqual(!!schema.pull('MySubSchema3'), true); | ||
}); | ||
|
||
test('[Handyman] Shorthands', () => { | ||
const schema = new Schema( | ||
{ | ||
a: 'string', //? scalar shorthand | ||
b: '?string', //? optional shorthand | ||
c: ['string', 'string'], //? tuple | ||
d: new Schema('?string'), //? Schema shorthand | ||
e: ['winter', 'spring'], //? Enum shorthand | ||
f: { a: 'number', b: 'string' }, //? Object shorthand | ||
g: { $type: 'array', items: 'string' }, //? Array items shorthand | ||
h: 'MyExternalSchema', | ||
}, | ||
{ namespace: { MyExternalSchema: new Schema('string') } }, | ||
); | ||
|
||
assert.strictEqual(schema.warnings.length, 0); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,33 @@ | ||
'use strict'; | ||
|
||
const { nameFix } = require('./utils'); | ||
const types = require('./types'); | ||
|
||
module.exports = schema => { | ||
function TypescriptWrapper() { | ||
this.toTypescript = () => 'unknown'; | ||
} | ||
for (const [name, proto] of types.entries()) schema.forge.attach(name, proto); | ||
schema.forge.attach('before', TypescriptWrapper); | ||
schema.forge.attach('before', { toTypescript: () => 'unknown' }); | ||
schema.forge.attach('after', function TypescriptWrapper() { | ||
const compile = this.toTypescript; | ||
this.toTypescript = (name, namespace) => compile(nameFix(name), namespace); | ||
}); | ||
|
||
schema.dts = (name = 'MetaForge', options = {}) => { | ||
const mode = options.mode ?? 'mjs'; | ||
if (name !== nameFix(name)) throw new Error('Invalid name format'); | ||
const namespace = { definitions: new Set(), exports: new Set() }; | ||
const type = schema.toTypescript(name, namespace); | ||
if (type !== name) { | ||
if (namespace.exports.size === 1) { | ||
const definitions = Array.from(namespace.definitions).join(''); | ||
if (mode === 'cjs') return definitions + `export = ${type}`; | ||
return definitions + `export type ${name}=${type};export default ${type};`; | ||
} | ||
namespace.definitions.add(`type ${name}=${type};`); | ||
} | ||
namespace.exports.add(name); | ||
const definitions = Array.from(namespace.definitions).join(''); | ||
if (mode === 'cjs') return definitions + `export = ${name};`; | ||
const exports = `export type{${Array.from(namespace.exports).join(',')}};`; | ||
return definitions + exports + `export default ${name};`; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* eslint-disable quotes */ | ||
'use strict'; | ||
|
||
const [test, assert] = [require('node:test'), require('node:assert')]; | ||
const Schema = require('../../'); | ||
|
||
const generate = (type, name) => new Schema(type).dts(name); | ||
const base = 'type MetaForge='; | ||
const exp = 'export type{MetaForge};export default MetaForge;'; | ||
test('[DTS] Basic', () => { | ||
assert.strictEqual(generate({ $type: 'string' }), base + 'string;' + exp); | ||
assert.strictEqual(generate('number'), base + 'number;' + exp); | ||
assert.strictEqual(generate('bigint'), base + 'bigint;' + exp); | ||
assert.strictEqual(generate('boolean'), base + 'boolean;' + exp); | ||
assert.strictEqual(generate('unknown'), base + 'unknown;' + exp); | ||
assert.strictEqual(generate('?any'), base + '(any|null|undefined);' + exp); | ||
}); | ||
|
||
test('[DTS] Enumerable', () => { | ||
assert.strictEqual(generate(['hello', 'world']), base + "('hello'|'world');" + exp); | ||
const data = ['hello', 'there', 'my', 'dear', 'world']; | ||
const result = `type MetaForge='hello'|'there'|'my'|'dear'|'world';`; | ||
assert.strictEqual(generate(data), result + exp); | ||
}); | ||
|
||
test('[DTS] Union', () => { | ||
assert.strictEqual( | ||
generate({ $type: 'union', types: ['string', '?number'] }), | ||
'type MetaForge=(string|(number|null|undefined));' + exp, | ||
); | ||
assert.strictEqual( | ||
generate({ $type: 'union', types: [{ $type: 'union', types: ['string', '?number'] }] }), | ||
'type MetaForge=((string|(number|null|undefined)));' + exp, | ||
); | ||
}); | ||
|
||
test('[DTS] Array', () => { | ||
assert.strictEqual( | ||
generate(['string', '?number']), | ||
'type MetaForge=[string,(number|null|undefined)];' + exp, | ||
); | ||
assert.strictEqual( | ||
generate({ $type: 'set', items: ['string', '?number'] }), | ||
'type MetaForge=Set<string|(number|null|undefined)>;' + exp, | ||
); | ||
assert.strictEqual( | ||
generate({ $type: 'array', items: { $type: 'union', types: ['string', '?number'] } }), | ||
'type MetaForge=((string|(number|null|undefined)))[];' + exp, | ||
); | ||
assert.strictEqual( | ||
generate({ $type: 'tuple', items: { $type: 'union', types: ['string', '?number'] } }), | ||
'type MetaForge=[(string|(number|null|undefined))];' + exp, | ||
); | ||
const enumerable = ['hello', 'there', 'my', 'dear', 'world']; | ||
const complex = ['?number', enumerable, { a: 'string', b: enumerable }]; | ||
let result = "type MetaForge_1='hello'|'there'|'my'|'dear'|'world';"; | ||
result += "type MetaForge_2_b='hello'|'there'|'my'|'dear'|'world';"; | ||
result += 'interface MetaForge_2{a:string;b:MetaForge_2_b;};'; | ||
result += 'type MetaForge=[(number|null|undefined),MetaForge_1,MetaForge_2];' + exp; | ||
assert.strictEqual(generate(complex), result); | ||
}); | ||
|
||
test('[DTS] Struct', () => { | ||
const schema = { "'": 'string', '"': 'string', b: '?number', 'c+': { d: ['hello', 'world'] } }; | ||
let result = "interface MetaForge_c{d:('hello'|'world');};"; | ||
result += 'interface MetaForge{"\'":string;\'"\':string;'; | ||
result += "b?:(number|null|undefined);'c+':MetaForge_c;};"; | ||
result += exp; | ||
assert.strictEqual(generate(schema), result); | ||
}); | ||
|
||
test('[DTS] Schema', () => { | ||
const schema = { | ||
$id: 'MySchema', | ||
a: 'string', | ||
b: { $id: 'MySubSchema', c: 'number' }, | ||
c: new Schema('?string'), | ||
d: { $type: 'schema', schema: new Schema('number'), $id: 'MySubSchema2' }, | ||
e: { $type: 'schema', schema: new Schema({ $type: 'number', $id: 'MySubSchema3' }) }, | ||
}; | ||
let r = 'interface MySubSchema{c:number;};type MySubSchema2=number;type MySubSchema3=number;'; | ||
r += `interface MetaForge{a:string;b:MySubSchema;c?:(string|null|undefined);`; | ||
r += 'd:MySubSchema2;e:MySubSchema3;};'; | ||
r += 'export type{MySubSchema,MySubSchema2,MySubSchema3,MetaForge};export default MetaForge;'; | ||
assert.strictEqual(generate(schema), r); | ||
}); | ||
|
||
test('[DTS] Modes', () => { | ||
const schema = new Schema({ a: { $id: 'MySubSchema', c: 'number' } }); | ||
const result = 'interface MySubSchema{c:number;};interface MetaForge{a:MySubSchema;};'; | ||
const mjs = result + 'export type{MySubSchema,MetaForge};export default MetaForge;'; | ||
const cjs = result + 'export = MetaForge;'; | ||
assert.strictEqual(schema.dts('MetaForge'), mjs); | ||
assert.strictEqual(schema.dts('MetaForge', { mode: 'cjs' }), cjs); | ||
}); |
Oops, something went wrong.