Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { normalizeConfigPath } from './helpers';
import { JsiiDiagnostic } from './jsii-diagnostic';
import * as literate from './literate';
import * as bindings from './node-bindings';
import { AssemblyTargets, ProjectInfo } from './project-info';
import { AssemblyTargets, ProjectInfo, validateTargets } from './project-info';
import { isReservedName } from './reserved-words';
import { Sets } from './sets';
import { DeprecatedRemover } from './transforms/deprecated-remover';
Expand Down Expand Up @@ -721,7 +721,7 @@ export class Assembler implements Emitter {
return undefined;
}
const data = JSON.parse(fs.readFileSync(jsiirc, 'utf-8'));
return data.targets;
return validateTargets(data.targets as AssemblyTargets) as SubmoduleSpec['targets'];
}

/**
Expand Down
54 changes: 49 additions & 5 deletions src/project-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,33 +308,77 @@ export function loadProjectInfo(projectRoot: string): ProjectInfoResult {
/**
* Validate the values of the `.jsii.targets` field
*/
function validateTargets(targets: AssemblyTargets | undefined): AssemblyTargets | undefined {
export function validateTargets(targets: AssemblyTargets | undefined): AssemblyTargets | undefined {
if (!targets) {
return undefined;
}

const VALID_TARGET_KEYS: Record<string, string[]> = {
java: ['package', 'maven', 'versionSuffix'],
python: ['module', 'distName', 'classifiers'],
dotnet: ['namespace', 'packageId', 'iconUrl', 'versionSuffix'],
go: ['moduleName', 'packageName', 'versionSuffix'],
};

for (const [language, config] of Object.entries(targets)) {
if (!(language in VALID_TARGET_KEYS)) {
throw new JsiiError(`Unknown target language: ${language}`);
}

if (typeof config !== 'object' || config === null) {
throw new JsiiError(`jsii.targets.${language} must be an object`);
}

const validKeys = VALID_TARGET_KEYS[language];
for (const key of Object.keys(config)) {
if (!validKeys.includes(key)) {
throw new JsiiError(`Unknown key in jsii.targets.${language}: ${key}`);
}
}
}

// Go package names must be valid identifiers
if (targets.go) {
if (
targets.go &&
typeof targets.go === 'object' &&
'packageName' in targets.go &&
typeof targets.go.packageName === 'string'
) {
if (!isIdentifier(targets.go.packageName)) {
throw new JsiiError(`jsii.targets.go.packageName contains non-identifier characters: ${targets.go.packageName}`);
}
}

if (targets.dotnet) {
if (
targets.dotnet &&
typeof targets.dotnet === 'object' &&
'namespace' in targets.dotnet &&
typeof targets.dotnet.namespace === 'string'
) {
if (!targets.dotnet.namespace.split('.').every(isIdentifier)) {
throw new JsiiError(
`jsii.targets.dotnet.namespace contains non-identifier characters: ${targets.dotnet.namespace}`,
);
}
}

if (targets.java) {
if (
targets.java &&
typeof targets.java === 'object' &&
'package' in targets.java &&
typeof targets.java.package === 'string'
) {
if (!targets.java.package.split('.').every(isIdentifier)) {
throw new JsiiError(`jsii.targets.java.package contains non-identifier characters: ${targets.java.package}`);
}
}

if (targets.python) {
if (
targets.python &&
typeof targets.python === 'object' &&
'module' in targets.python &&
typeof targets.python.module === 'string'
) {
if (!targets.python.module.split('.').every(isIdentifier)) {
throw new JsiiError(`jsii.targets.python.module contains non-identifier characters: ${targets.python.module}`);
}
Expand Down
2 changes: 1 addition & 1 deletion test/compiler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe(Compiler, () => {
} finally {
rmSync(sourceDir, { force: true, recursive: true });
}
}, 25_000);
}, 40_000);

test('rootDir is added to assembly', () => {
const outDir = 'jsii-outdir';
Expand Down
2 changes: 1 addition & 1 deletion test/project-info.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const BASE_PROJECT = {
main: 'index.js',
types: 'index.d.ts',
jsii: {
targets: { foo: { bar: 'baz' } },
targets: { python: { module: 'test_module', distName: 'test-dist' } },
},
dependencies: { 'jsii-test-dep': '^1.2.3' } as { [name: string]: string },
peerDependencies: { 'jsii-test-dep': '^1.2.3' } as { [name: string]: string },
Expand Down
Loading