Socket
Socket
Sign inDemoInstall

fabric-contract-api

Package Overview
Dependencies
Maintainers
1
Versions
220
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fabric-contract-api - npm Package Compare versions

Comparing version 1.3.0-snapshot.6 to 1.3.0-snapshot.7

lib/context.js

2

index.js

@@ -13,4 +13,4 @@ /*

module.exports.Contract = require('./lib/contract.js');
module.exports.Context = require('./lib/context.js');

@@ -9,7 +9,10 @@ /*

const ClientIdentity = require('fabric-shim').ClientIdentity;
const Context = require('./context');
/**
* The main Contact class that all code working within a Chaincode Container must be extending. Provides indentification
* and helper functions to work with
* The main Contact class that all code working within a Chaincode Container must be extending.
*
* Overriding of the `beforeTransaction` `afterTransaction` `unknownTransaction` and `createContext` are all optional
* Supplying a namespace within the constructor is also option and will default to ''
*
* @memberof fabric-contract-api

@@ -20,94 +23,69 @@ */

/**
* If no namespace given, or it is whitespace default to 'contract'
* Constructor - supplying a namespace is recommended but is not mandatory.
*
* @param {String} namespace namespace for the logic within this contract
*/
constructor(namespace, metadata = {}){
constructor(namespace){
if (namespace && namespace.trim() !== '' ){
this.namespace = namespace.trim();
} else {
this.namespace = 'contract';
this.namespace = '';
}
this.metadata = metadata;
this.unknownFn = () => {
throw new Error('You\'ve asked to invoke a function that does not exist');
};
}
/** Is the object a function?
* @ignore
* @param {function} fn to be checked
* @return {boolean} true if function
*/
_isFunction(fn){
return !!(fn && fn.constructor && fn.call && fn.apply);
}
/**
* Sets the fn to call if something unknown comes in;
* If function is not passed a error will be thrown
*
* @param {function} fn fn -
*/
setUnknownFn(fn){
if (this._isFunction(fn)){
this.unknownFn = fn;
} else {
throw new Error('Argument is not a function');
}
* 'beforeTransaction' will be called before any of the transaction functions within your contract
* Override this method to implement your own processing. Examples of what you may wish to code
* are Logging, Event Publishing or Permissions checks
*
* If an error is thrown, the whole transaction will be rejected
*
* @param {Context} ctx the transactional context
*/
async beforeTransaction(ctx){ // eslint-disable-line
// default implementation is do nothing
}
/**
* Gets the fn to call to use if nothing specified
* @return {function} function
*/
getUnknownFn(){
return this.unknownFn;
* 'afterTransaction' will be called before any of the transaction functions within your contract
* Override this method to implement your own processing. Examples of what you may wish to code
* are Logging, Event Publishing
*
* If an error is thrown, the whole transaction will be rejected
*
* @param {Context} ctx the transactional context
* @param {Object} result value that is returned from the transaction function
*/
async afterTransaction(ctx,result){ // eslint-disable-line no-unused-vars
// default implementation is do nothing
}
/**
* This is invoked before each function
*
* @param {function} fn fn to invoke prior to the transaction function being called
*/
setBeforeFn(fn){
if (this._isFunction(fn)){
this.beforeFn = fn;
} else {
throw new Error('Argument is not a function');
}
* 'unknownTransaction' will be called if the required transaction function requested does not exist
* Override this method to implement your own processing.
* *
* If an error is thrown, the whole transaction will be rejected
*
* @param {Context} ctx the transactional context
*/
async unknownTransaction(ctx) {
const { fcn } = ctx.stub.getFunctionAndParameters();
throw new Error(`You've asked to invoke a function that does not exist: ${fcn}`);
}
/**
* Get the function that would be invoked before
*
* @return {function} fn
*/
getBeforeFn(){
return this.beforeFn;
* 'createContext' is called before any after, before, unknown or user defined transaction function. This permits contracts
* to use their own subclass of context to add additinal processing.
*
* After this function returns, the chaincodeStub and client identity objects will be injected.
* No chaincode apis are available for calling directly within this function. Nor should the constructor of the subclasses context assume
* any other setup.
*
* @return {Context} a context implementation that must subclass context
*/
createContext(){
return new Context();
}
/**
* Get the function that would be invoked after
*
* @return {function} fn
*/
getAfterFn(){
return this.afterFn;
}
/**
* This is invoked after each function
*
* @param {function} fn fn to invoke after the transaction function being called
*/
setAfterFn(fn){
if (this._isFunction(fn)){
this.afterFn = fn;
} else {
throw new Error('Argument is not a function');
}
}
/**
* @return {String} returns the namepsace

@@ -119,13 +97,4 @@ */

/**
* Gets meta data about this instance
*
* @return {Object} object with key/value map of metadata
*/
getMetadata(){
return this.metadata;
}
}
module.exports = Contract;
{
"name": "fabric-contract-api",
"version": "1.3.0-snapshot.6",
"version": "1.3.0-snapshot.7",
"description": "A node.js implementation of Hyperledger Fabric chaincode shim, to allow endorsing peers and user-provided chaincodes to communicate with each other",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -77,3 +77,3 @@ [![NPM](https://nodei.co/npm/fabric-contract-api.svg?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/fabric-contract-api/)

"scripts": {
"start": "startChaincode"
"start": "fabric-chaincode-node start"
}

@@ -80,0 +80,0 @@ ```

@@ -10,23 +10,39 @@ "use strict";

const fabric_contract_api_1 = require("fabric-contract-api");
class ScenarioContext extends fabric_contract_api_1.Context {
customFunction() {
}
}
exports.ScenarioContext = ScenarioContext;
class TestContractOne extends fabric_contract_api_1.Contract {
constructor() {
super('org.papernet.commercialpaper', { key: 'value' });
const intermediaryFn = (ctx) => {
return ctx;
};
this.setBeforeFn(intermediaryFn);
this.setAfterFn(intermediaryFn);
this.setUnknownFn(intermediaryFn);
super('org.papernet.commercialpaper');
}
beforeTransaction(ctx) {
// test that the context super class properties are available
const stubApi = ctx.stub;
const clientIdentity = ctx.clientIdentity;
// tests that the functions in the subclasses context be called
ctx.customFunction();
// This proves that typescript is enforcing the
// return type of Promise<void>
return Promise.resolve();
}
afterTransaction(ctx, result) {
// This proves that typescript is enforcing the
// return type of Promise<void>
return Promise.resolve();
}
unknownTransaction(ctx) {
// This proves that typescript is enforcing the
// return type of Promise<void>
return Promise.resolve();
}
createContext() {
return new ScenarioContext();
}
async Transaction(ctx) {
// test that the context super class properties are available
const stubApi = ctx.stub;
const clientIdentity = ctx.clientIdentity;
const afterFn = this.getAfterFn();
const testCtxAfter = afterFn(ctx);
const beforeFn = this.getBeforeFn();
const testCtxBefore = beforeFn(ctx);
const unknownFn = this.getUnknownFn();
const testCtxUnkown = beforeFn(ctx);
const testCtx = afterFn(ctx);
const data = this.getMetadata();
// test that the namespace returns a string
const ns = this.getNamespace();

@@ -38,12 +54,10 @@ }

constructor() {
super('org.papernet.commercialpaper');
super();
}
async Transaction(ctx) {
const stubApi = ctx.stub;
const clientIdentity = ctx.clientIdentity;
}
}
exports.TestContractTwo = TestContractTwo;
class TestContractThree extends fabric_contract_api_1.Contract {
constructor() {
super();
}
}
exports.TestContractThree = TestContractThree;
//# sourceMappingURL=smartcontract.js.map

@@ -8,31 +8,54 @@ /*

import { Contract, Context, IntermediaryFn } from 'fabric-contract-api';
import { Contract, Context } from 'fabric-contract-api';
import { ChaincodeStub, ClientIdentity } from 'fabric-shim';
export class ScenarioContext extends Context{
customFunction():void {
}
}
export default class TestContractOne extends Contract {
constructor() {
super('org.papernet.commercialpaper', {key: 'value'});
super('org.papernet.commercialpaper');
}
const intermediaryFn: IntermediaryFn = (ctx: Context) => {
return ctx;
}
beforeTransaction(ctx: ScenarioContext){
this.setBeforeFn(intermediaryFn);
this.setAfterFn(intermediaryFn);
this.setUnknownFn(intermediaryFn);
}
// test that the context super class properties are available
const stubApi: ChaincodeStub = ctx.stub;
const clientIdentity: ClientIdentity = ctx.clientIdentity;
async Transaction(ctx: Context) {
// tests that the functions in the subclasses context be called
ctx.customFunction();
// This proves that typescript is enforcing the
// return type of Promise<void>
return Promise.resolve();
}
afterTransaction(ctx: ScenarioContext,result: any){
// This proves that typescript is enforcing the
// return type of Promise<void>
return Promise.resolve();
}
unknownTransaction(ctx: ScenarioContext){
// This proves that typescript is enforcing the
// return type of Promise<void>
return Promise.resolve();
}
createContext(){
return new ScenarioContext();
}
async Transaction(ctx: ScenarioContext) {
// test that the context super class properties are available
const stubApi: ChaincodeStub = ctx.stub;
const clientIdentity: ClientIdentity = ctx.clientIdentity;
const afterFn: IntermediaryFn = this.getAfterFn();
const testCtxAfter: Context = afterFn(ctx);
const beforeFn: IntermediaryFn = this.getBeforeFn();
const testCtxBefore: Context = beforeFn(ctx);
const unknownFn: IntermediaryFn = this.getUnknownFn();
const testCtxUnkown: Context = beforeFn(ctx);
const testCtx: Context = afterFn(ctx);
const data: object = this.getMetadata();
// test that the namespace returns a string
const ns: string = this.getNamespace();

@@ -44,10 +67,9 @@ }

constructor() {
super('org.papernet.commercialpaper');
}
}
super();
}
export class TestContractThree extends Contract {
constructor() {
super();
async Transaction(ctx: Context) {
const stubApi: ChaincodeStub = ctx.stub;
const clientIdentity: ClientIdentity = ctx.clientIdentity;
}
}

@@ -28,7 +28,42 @@ /*

const Contract = require(path.join(pathToRoot,'fabric-contract-api/lib/contract'));
const Context = require(path.join(pathToRoot,'fabric-contract-api/lib/context'));
let beforeStub;
let afterStub;
let unknownStub;
let createContextStub;
/*
* A fake contract class;
*/
class SCAlpha extends Contract {
/** */
constructor() {
super('alpha.beta.delta');
}
async unknownTransaction(ctx){
unknownStub(ctx);
}
async beforeTransaction(ctx){
beforeStub(ctx);
}
async afterTransaction(ctx,result){
afterStub(ctx,result);
}
createContext(){
createContextStub();
}
}
describe('contract.js',()=>{
let sandbox;

@@ -46,21 +81,27 @@

it('should create with default namespace ',()=>{
let sc = new Contract();
expect(sc.namespace).to.equal('contract');
it('should create with default namespace',()=>{
let sc0 = new Contract();
expect(sc0.getNamespace()).to.equal('');
( ()=>{
sc.unknownFn();
}).should.throw(/does not exist/);
// should also create default when the supplied name is empty space
let sc1 = new Contract('');
expect(sc1.namespace).to.equal('contract');
expect(sc1.getNamespace()).to.equal('contract');
expect(sc1.getNamespace()).to.equal('');
let sc2 = new Contract(' ');
expect(sc2.namespace).to.equal('contract');
expect(sc2.getNamespace()).to.equal('contract');
expect(sc2.getNamespace()).to.equal('');
});
it('should have default unknownTx fn',()=>{
let sc0 = new Contract();
const ctx = {
stub : {
getFunctionAndParameters: 'fn'
}
};
ctx.stub.getFunctionAndParameters = sandbox.stub().returns({fcn:'wibble'});
return sc0.unknownTransaction(ctx).should.eventually.be.rejectedWith(/^You've asked to invoke a function that does not exist: wibble$/);
});
it('should create with the name specified',()=>{

@@ -75,93 +116,57 @@ let sc1 = new Contract('brain.size.planet.smart');

});
});
describe('#_isFunction',()=>{
let sc;
beforeEach('create temporary contract',()=>{
sc = new Contract();
});
it('should call the default before/after functions',()=>{
let sc0 = new Contract();
it('should return true for functions',()=>{
sc._isFunction((()=>{})).should.be.true;
return Promise.all([
sc0.beforeTransaction().should.be.fulfilled,
sc0.afterTransaction().should.be.fulfilled]);
});
it('should return false for not-functions',()=>{
sc._isFunction().should.be.false;
sc._isFunction('Hello').should.be.false;
sc._isFunction(25).should.be.false;
sc._isFunction(sc);
it('should call the default createContext functions',()=>{
let sc0 = new Contract();
sc0.createContext().should.be.an.instanceOf(Context);
});
});
describe('#set/get UnkownFn',()=>{
let sc;
beforeEach('create temporary contract',()=>{
sc = new Contract();
});
describe('subclass specific functioning',()=>{
it('should return function passed in',()=>{
let fn = ()=>{return 42;};
sc.setUnknownFn(fn);
expect(sc.unknownFn()).to.equal(42);
expect(sc.getUnknownFn()()).to.equal(42);
beforeEach('setup the stubs',()=>{
beforeStub = sandbox.stub().resolves();
afterStub = sandbox.stub().resolves();
unknownStub = sandbox.stub().resolves();
createContextStub = sandbox.stub().returns();
});
it('should throw error with wrong tyupes ',()=>{
( ()=>{
sc.setUnknownFn('wibble');
} ).should.throw(/Argument is not a function/);
});
});
describe('#set/get BeforeFn',()=>{
let sc;
beforeEach('create temporary contract',()=>{
sc = new Contract();
it('should set the correct namespace',()=>{
let sc = new SCAlpha();
sc.getNamespace().should.equal('alpha.beta.delta');
});
it('should return function passed in',()=>{
let fn = ()=>{return 42;};
sc.setBeforeFn(fn);
expect(sc.beforeFn()).to.equal(42);
expect(sc.getBeforeFn()()).to.equal(42);
it('should call the correct subclassed fns',()=>{
let sc = new SCAlpha();
let ctx = 'a really simple context';
sc.beforeTransaction(ctx);
sinon.assert.calledOnce(beforeStub);
sinon.assert.calledWith(beforeStub,ctx);
});
it('should throw error with wrong tyupes ',()=>{
( ()=>{
sc.setBeforeFn('wibble');
} ).should.throw(/Argument is not a function/);
});
});
sc.afterTransaction(ctx,'result');
sinon.assert.calledOnce(afterStub);
sinon.assert.calledWith(afterStub,ctx,'result');
describe('#set/get AfterFn',()=>{
let sc;
beforeEach('create temporary contract',()=>{
sc = new Contract();
});
sc.unknownTransaction(ctx);
sinon.assert.calledOnce(unknownStub);
sinon.assert.calledWith(unknownStub,ctx);
it('should return function passed in',()=>{
let fn = ()=>{return 42;};
sc.setAfterFn(fn);
expect(sc.afterFn()).to.equal(42);
expect(sc.getAfterFn()()).to.equal(42);
sc.createContext();
sinon.assert.calledOnce(createContextStub);
});
it('should throw error with wrong tyupes ',()=>{
( ()=>{
sc.setAfterFn('wibble');
} ).should.throw(/Argument is not a function/);
});
});
describe('#getMetadata',()=>{
let sc;
beforeEach('create temporary contract',()=>{
sc = new Contract('anamespace',{a:'value',some:'othervalue'});
});
it('should return value passed in',()=>{
let md = sc.getMetadata();
expect(md).to.deep.equal({a:'value',some:'othervalue'});
});
});
});
});

@@ -10,3 +10,3 @@ /*

import { ChaincodeStub, ClientIdentity } from 'fabric-shim';
export interface Context {
export class Context {
stub: ChaincodeStub;

@@ -16,19 +16,14 @@ clientIdentity: ClientIdentity;

export type IntermediaryFn = (ctx: Context) => Context;
export class Contract {
constructor(namespace?: string, metadata?:object);
constructor(namespace?: string);
setUnknownFn(fn : IntermediaryFn): void;
getUnknownFn(): IntermediaryFn;
beforeTransaction(ctx : Context): Promise<void>;
afterTransaction(ctx : Context,result: any): Promise<void>;
setBeforeFn(fn : IntermediaryFn): void;
getBeforeFn(): IntermediaryFn;
unknownTransaction(ctx : Context): Promise<void>;
setAfterFn(fn : IntermediaryFn): void;
getAfterFn(): IntermediaryFn;
createContext(): Context;
getNamespace(): string;
getNamespace(): string;
getMetadata(): object;
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc