Typescript Dependency Contracts for dependency inversion
npm install @jonloucks/contracts-ts
Typescript Dependency Contracts for dependency inversion
``bash`
npm install @jonloucks/contracts-ts
Importing the Package
`typescript`
import { CONTRACTS, createContract } from '@jonloucks/contracts-ts';
Importing the Convenience Package
`typescript`
import {
AutoClose,
bind,
claim,
Contract,
createExtractor,
createLifeCycle,
createRepository,
createSingleton,
createValue,
createContract,
enforce,
guardFunctions,
isBound
} from "@jonloucks/contracts-ts/api/Convenience";
Creating a Contract
`typescript
// Define a service interface
interface Logger {
log(message: string): void;
}
// Create a contract for the service
const LOGGER_CONTRACT: Contract
name: "Logger",
test: (obj: unknown): obj is Logger => { // example of duck-typing check
return guardFunctions(obj, 'log'); // example of using guardFunctions helper
}
});
`
Binding a Contract
`typescript
bind
createSingleton
() => ({
log: (message: string) => {
console.log("LOG:", message);
}
})));
`
Using the Contract
`typescript`
const logger : Logger = enforce
logger.log("Using the service in the test.");
Install dependencies
`bash`
npm install
Build the project
`bash`
npm run build
Run tests
`bash`
npm test
Run tests in watch mode
`bash`
npm run test:watch
Run test coverage
`bash`
npm run test:coverage
Lint the code
`bash`
npm run lint
Fix linting issues
`bash`
npm run lint:fix
Generate documents
`bash`
npm run docs
Generate badges
`bash`
npm run badges
Project Structure
* All tests must have suffix of -test.ts or -spec.ts
* Tests that validate supported APIs go in src/test
* Tests that validate internal implementation details go in src/impl
``
contracts-ts
├── .github
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows
│ ├── main-pull-request-matrix.yml
│ ├── main-pull-request.yml
│ ├── main-push.yml
│ └── main-release.yml
├── CODE_OF_CONDUCT.md
├── CODING_STANDARDS.md
├── CONTRIBUTING.md
├── editorconfig
├── eslint.config.mjs
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── scripts
│ ├── badge-template.svg.dat
│ └── tsconfig.json
├── SECURITY.md
├── src
│ ├── index.ts
│ ├── version.ts
│ ├── api
│ │ ├── *.ts
│ │ ├── *.api.ts
│ ├── auxiliary
│ │ ├── *.ts
│ │ ├── *.impl.ts
│ │ ├── *.test.ts // internal implementation specific
│ │ └── *.api.ts
│ ├── impl
│ │ ├── *.ts
│ │ ├── *.impl.ts
│ │ ├── *.test.ts // internal implementation specific
│ │ └── *.api.ts
│ ├── test
│ │ └── *.test.ts
│ └── never-publish // non shippable development scripts
│ ├── *.ts
│ ├── .. // data files etc
│ └── *.test.ts
├── tsconfig.json
└── typedoc.json
CI Workflow
The CI workflow runs on every push and pull request to main branch. It:
- Tests against Node.js versions 18.x, 20.x, 22.x, and 24.x
- Runs linting
- Builds the project
- Runs tests with coverage
- Uploads coverage to Codecov (optional)
Publish Workflow
The GitHub publishings workflows are run to make an official release.
- If all scanning and tests pass it is published. There is no other way allowed.
- Publishing authentication is done using (OIDC trusted publishing)
To set up your own publishing:
1. Publishing this project as is intentionally disabled
2. You are welcome to fork this repository and publish where you want.
3. Run npm pkg delete private to remove the private flag from the package.name
4. Change the field in package.json` to your desired package name.
MIT