feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

25
api.hyungi.net/node_modules/shimmer/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2013-2019, Forrest L Norvell
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

80
api.hyungi.net/node_modules/shimmer/README.md generated vendored Normal file
View File

@@ -0,0 +1,80 @@
[![Build Status](https://travis-ci.org/othiym23/shimmer.svg)](https://travis-ci.org/othiym23/shimmer)
[![Coverage Status](https://coveralls.io/repos/othiym23/shimmer/badge.svg?branch=master)](https://coveralls.io/r/othiym23/shimmer?branch=master)
## Safer monkeypatching for Node.js
`shimmer` does a bunch of the work necessary to wrap other methods in
a wrapper you provide:
```javascript
var http = require('http');
var shimmer = require('shimmer');
shimmer.wrap(http, 'request', function (original) {
return function () {
console.log("Starting request!");
var returned = original.apply(this, arguments)
console.log("Done setting up request -- OH YEAH!");
return returned;
};
});
```
### Mandatory disclaimer
There are times when it's necessary to monkeypatch default behavior in
JavaScript and Node. However, changing the behavior of the runtime on the fly
is rarely a good idea, and you should be using this module because you need to,
not because it seems like fun.
### API
All monkeypatched functions have an attribute, `__wrapped`, set to true on
them.
#### shimmer(options)
If you pass in an options object containing a function labeled `logger`,
`shimmer` will use it instead of the logger, which defaults to `console.error`.
`shimmer` is built to be as unobtrusive as possible and has no need to run
asynchronously, so it defaults to logging when things fail, instead of
throwing.
#### shimmer.wrap(nodule, name, wrapper)
`shimmer` monkeypatches in place, so it expects to be passed an object.
It accepts either instances, prototypes, or the results of calling
`require`. `name` must be the string key for the field's name on the
object.
`wrapper` is a function that takes a single parameter, which is the original
function to be monkeypatched. `shimmer` assumes that you're adding behavior
to the original method, and not replacing it outright. If you *are* replacing
the original function, feel free to ignore the passed-in function.
If you *aren't* discarding the original, remember these tips:
* call the original with something like `original.apply(this, arguments)`,
unless your reason for monkeypatching is to transform the arguments.
* always capture and return the return value coming from the original function.
Today's null-returning callback is tomorrow's error-code returning callback.
* Don't make an asynchronous function synchronous and vice versa.
#### shimmer.massWrap(nodules, names, wrapper)
Just like `wrap`, with the addition that you can wrap multiple methods on
multiple modules. Note that this function expects the list of functions to be
monkeypatched on all of the modules to be the same.
#### shimmer.unwrap(nodule, name)
A convenience function for restoring the function back the way it was before
you started. Won't unwrap if somebody else has monkeypatched the function after
you (but will log in that case). Won't throw if you try to double-unwrap a
function (but will log).
#### shimmer.massUnwrap(nodules, names)
Just like `unwrap`, with the addition that you can unwrap multiple methods on
multiple modules. Note that this function expects the list of functions to be
unwrapped on all of the modules to be the same.

121
api.hyungi.net/node_modules/shimmer/index.js generated vendored Normal file
View File

@@ -0,0 +1,121 @@
'use strict'
function isFunction (funktion) {
return typeof funktion === 'function'
}
// Default to complaining loudly when things don't go according to plan.
var logger = console.error.bind(console)
// Sets a property on an object, preserving its enumerability.
// This function assumes that the property is already writable.
function defineProperty (obj, name, value) {
var enumerable = !!obj[name] && obj.propertyIsEnumerable(name)
Object.defineProperty(obj, name, {
configurable: true,
enumerable: enumerable,
writable: true,
value: value
})
}
// Keep initialization idempotent.
function shimmer (options) {
if (options && options.logger) {
if (!isFunction(options.logger)) logger("new logger isn't a function, not replacing")
else logger = options.logger
}
}
function wrap (nodule, name, wrapper) {
if (!nodule || !nodule[name]) {
logger('no original function ' + name + ' to wrap')
return
}
if (!wrapper) {
logger('no wrapper function')
logger((new Error()).stack)
return
}
if (!isFunction(nodule[name]) || !isFunction(wrapper)) {
logger('original object and wrapper must be functions')
return
}
var original = nodule[name]
var wrapped = wrapper(original, name)
defineProperty(wrapped, '__original', original)
defineProperty(wrapped, '__unwrap', function () {
if (nodule[name] === wrapped) defineProperty(nodule, name, original)
})
defineProperty(wrapped, '__wrapped', true)
defineProperty(nodule, name, wrapped)
return wrapped
}
function massWrap (nodules, names, wrapper) {
if (!nodules) {
logger('must provide one or more modules to patch')
logger((new Error()).stack)
return
} else if (!Array.isArray(nodules)) {
nodules = [nodules]
}
if (!(names && Array.isArray(names))) {
logger('must provide one or more functions to wrap on modules')
return
}
nodules.forEach(function (nodule) {
names.forEach(function (name) {
wrap(nodule, name, wrapper)
})
})
}
function unwrap (nodule, name) {
if (!nodule || !nodule[name]) {
logger('no function to unwrap.')
logger((new Error()).stack)
return
}
if (!nodule[name].__unwrap) {
logger('no original to unwrap to -- has ' + name + ' already been unwrapped?')
} else {
return nodule[name].__unwrap()
}
}
function massUnwrap (nodules, names) {
if (!nodules) {
logger('must provide one or more modules to patch')
logger((new Error()).stack)
return
} else if (!Array.isArray(nodules)) {
nodules = [nodules]
}
if (!(names && Array.isArray(names))) {
logger('must provide one or more functions to unwrap on modules')
return
}
nodules.forEach(function (nodule) {
names.forEach(function (name) {
unwrap(nodule, name)
})
})
}
shimmer.wrap = wrap
shimmer.massWrap = massWrap
shimmer.unwrap = unwrap
shimmer.massUnwrap = massUnwrap
module.exports = shimmer

28
api.hyungi.net/node_modules/shimmer/package.json generated vendored Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "shimmer",
"version": "1.2.1",
"description": "Safe(r) monkeypatching for JavaScript.",
"main": "index.js",
"scripts": {
"test": "standard && tap test/*.tap.js --coverage"
},
"repository": {
"type": "git",
"url": "https://github.com/othiym23/shimmer.git"
},
"keywords": [
"monkeypatch",
"swizzle",
"wrapping",
"danger",
"hmm",
"shim"
],
"author": "Forrest L Norvell <ogd@aoaioxxysz.net>",
"license": "BSD-2-Clause",
"devDependencies": {
"sinon": "^7.2.2",
"standard": "^12.0.1",
"tap": "^12.1.1"
}
}

48
api.hyungi.net/node_modules/shimmer/test/init.tap.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
'use strict'
var tap = require('tap')
var test = tap.test
var sinon = require('sinon')
var shimmer = require('../index.js')
test('shimmer initialization', function (t) {
t.plan(4)
t.doesNotThrow(function () { shimmer() })
var mock = sinon.expectation
.create('logger')
.withArgs('no original function undefined to wrap')
.once()
t.doesNotThrow(function () {
shimmer({ logger: mock })
}, "initializer doesn't throw")
t.doesNotThrow(function () {
shimmer.wrap()
}, "invoking the wrap method with no params doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger method was called with the expected message')
})
test('shimmer initialized with non-function logger', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withArgs("new logger isn't a function, not replacing")
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer({ logger: { ham: 'chunx' } })
}, "even bad initialization doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger initialization failed in the expected way')
})

View File

@@ -0,0 +1,121 @@
'use strict'
var tap = require('tap')
var test = tap.test
var sinon = require('sinon')
var shimmer = require('../index.js')
var outsider = 0
function counter () { return ++outsider }
function anticounter () { return --outsider }
var generator = {
inc: counter,
dec: anticounter
}
test('should unwrap safely', function (t) {
t.plan(18)
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.equal(anticounter, generator.dec, 'basic function equality testing should work')
t.doesNotThrow(function () { generator.inc() })
t.equal(1, outsider, 'calls have side effects')
t.doesNotThrow(function () { generator.dec() })
t.equal(0, outsider, 'calls have side effects')
function wrapper (original) {
return function () {
return original.apply(this, arguments)
}
}
shimmer.massWrap(generator, ['inc', 'dec'], wrapper)
t.doesNotEqual(counter, generator.inc, 'function should be wrapped')
t.doesNotEqual(anticounter, generator.dec, 'function should be wrapped')
t.doesNotThrow(function () { generator.inc() })
t.equal(1, outsider, 'original function has still been called')
t.doesNotThrow(function () { generator.dec() })
t.equal(0, outsider, 'original function has still been called')
shimmer.massUnwrap(generator, ['inc', 'dec'])
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.equal(anticounter, generator.dec, 'basic function equality testing should work')
t.doesNotThrow(function () { generator.inc() })
t.equal(1, outsider, 'original function has still been called')
t.doesNotThrow(function () { generator.dec() })
t.equal(0, outsider, 'original function has still been called')
})
test("shouldn't throw on double unwrapping", function (t) {
t.plan(10)
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.equal(anticounter, generator.dec, 'basic function equality testing should work')
var mock = sinon.stub()
shimmer({ logger: mock })
function wrapper (original) {
return function () {
return original.apply(this, arguments)
}
}
shimmer.wrap(generator, 'inc', wrapper)
shimmer.wrap(generator, 'dec', wrapper)
t.doesNotEqual(counter, generator.inc, 'function should be wrapped')
t.doesNotEqual(anticounter, generator.dec, 'function should be wrapped')
shimmer.massUnwrap(generator, ['inc', 'dec'])
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.equal(anticounter, generator.dec, 'basic function equality testing should work')
t.doesNotThrow(function () { shimmer.massUnwrap(generator, ['inc', 'dec']) },
'should double unwrap without issue')
t.equal(counter, generator.inc, 'function is unchanged after unwrapping')
t.equal(anticounter, generator.dec, 'function is unchanged after unwrapping')
t.doesNotThrow(function () {
sinon.assert.calledWith(mock, 'no original to unwrap to -- ' +
'has inc already been unwrapped?')
sinon.assert.calledWith(mock, 'no original to unwrap to -- ' +
'has dec already been unwrapped?')
sinon.assert.calledTwice(mock)
}, 'logger was called with the expected message')
})
test('massUnwrap called with no arguments', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.twice()
shimmer({ logger: mock })
t.doesNotThrow(function () { shimmer.massUnwrap() }, 'should log instead of throwing')
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('massUnwrap called with module but nothing else', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withExactArgs('must provide one or more functions to unwrap on modules')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.massUnwrap(generator)
}, "wrapping with only 1 argument doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})

View File

@@ -0,0 +1,174 @@
'use strict'
var tap = require('tap')
var test = tap.test
var sinon = require('sinon')
var shimmer = require('../index.js')
var outsider = 0
function counter () { return ++outsider }
function anticounter () { return --outsider }
var generator = {
inc: counter,
dec: anticounter
}
var arrow = {
in: counter,
out: anticounter
}
var nester = {
in: counter,
out: anticounter
}
test('should wrap multiple functions safely', function (t) {
t.plan(9)
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.equal(anticounter, generator.dec, 'basic function equality testing should work')
t.doesNotThrow(function () { generator.inc() })
t.doesNotThrow(function () { generator.dec() })
t.equal(0, outsider, 'calls have side effects')
var count = 0
function wrapper (original) {
return function () {
count++
var returned = original.apply(this, arguments)
count++
return returned
}
}
shimmer.massWrap(generator, ['inc', 'dec'], wrapper)
t.doesNotThrow(function () { generator.inc() })
t.doesNotThrow(function () { generator.dec() })
t.equal(4, count, 'both pre and post increments should have happened')
t.equal(0, outsider, 'original function has still been called')
})
test('should wrap multiple functions on multiple modules safely', function (t) {
t.plan(15)
t.equal(counter, arrow.in, 'basic function equality testing should work')
t.equal(counter, nester.in, 'basic function equality testing should work')
t.equal(anticounter, arrow.out, 'basic function equality testing should work')
t.equal(anticounter, nester.out, 'basic function equality testing should work')
t.doesNotThrow(function () { arrow.in() })
t.doesNotThrow(function () { nester.in() })
t.doesNotThrow(function () { arrow.out() })
t.doesNotThrow(function () { nester.out() })
t.equal(0, outsider, 'calls have side effects')
var count = 0
function wrapper (original) {
return function () {
count++
var returned = original.apply(this, arguments)
count++
return returned
}
}
shimmer.massWrap([arrow, nester], ['in', 'out'], wrapper)
t.doesNotThrow(function () { arrow.in() })
t.doesNotThrow(function () { arrow.out() })
t.doesNotThrow(function () { nester.in() })
t.doesNotThrow(function () { nester.out() })
t.equal(8, count, 'both pre and post increments should have happened')
t.equal(0, outsider, 'original function has still been called')
})
test('wrap called with no arguments', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.twice()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.massWrap()
}, "wrapping with no arguments doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with module but nothing else', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withExactArgs('must provide one or more functions to wrap on modules')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.massWrap(generator)
}, "wrapping with only 1 argument doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with original but no wrapper', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.twice()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.massWrap(generator, ['inc'])
}, "wrapping with only original function doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with non-function original', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withExactArgs('must provide one or more functions to wrap on modules')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.massWrap({ orange: 'slices' }, 'orange', function () {})
}, "wrapping non-function original doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with non-function wrapper', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withArgs('must provide one or more functions to wrap on modules')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.massWrap({ orange: function () {} }, 'orange', 'hamchunx')
}, "wrapping with non-function wrapper doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})

101
api.hyungi.net/node_modules/shimmer/test/unwrap.tap.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
'use strict'
var tap = require('tap')
var test = tap.test
var sinon = require('sinon')
var shimmer = require('../index.js')
var outsider = 0
function counter () { return ++outsider }
var generator = {
inc: counter
}
test('should unwrap safely', function (t) {
t.plan(9)
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.doesNotThrow(function () { generator.inc() })
t.equal(1, outsider, 'calls have side effects')
function wrapper (original) {
return function () {
return original.apply(this, arguments)
}
}
shimmer.wrap(generator, 'inc', wrapper)
t.doesNotEqual(counter, generator.inc, 'function should be wrapped')
t.doesNotThrow(function () { generator.inc() })
t.equal(2, outsider, 'original function has still been called')
shimmer.unwrap(generator, 'inc')
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.doesNotThrow(function () { generator.inc() })
t.equal(3, outsider, 'original function has still been called')
})
test("shouldn't throw on double unwrapping", function (t) {
t.plan(6)
t.equal(counter, generator.inc, 'basic function equality testing should work')
var mock = sinon.expectation
.create('logger')
.withArgs('no original to unwrap to -- ' +
'has inc already been unwrapped?')
.once()
shimmer({ logger: mock })
function wrapper (original) {
return function () {
return original.apply(this, arguments)
}
}
shimmer.wrap(generator, 'inc', wrapper)
t.doesNotEqual(counter, generator.inc, 'function should be wrapped')
shimmer.unwrap(generator, 'inc')
t.equal(counter, generator.inc, 'basic function equality testing should work')
t.doesNotThrow(function () { shimmer.unwrap(generator, 'inc') },
'should double unwrap without issue')
t.equal(counter, generator.inc, 'function is unchanged after unwrapping')
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('unwrap called with no arguments', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.twice()
shimmer({ logger: mock })
t.doesNotThrow(function () { shimmer.unwrap() }, 'should log instead of throwing')
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('unwrap called with module but no name', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.twice()
shimmer({ logger: mock })
t.doesNotThrow(function () { shimmer.unwrap({}) }, 'should log instead of throwing')
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})

148
api.hyungi.net/node_modules/shimmer/test/wrap.tap.js generated vendored Normal file
View File

@@ -0,0 +1,148 @@
'use strict'
var tap = require('tap')
var test = tap.test
var sinon = require('sinon')
var shimmer = require('../index.js')
var outsider = 0
function counter () { return ++outsider }
function anticounter () { return --outsider }
var generator = {
inc: counter
}
Object.defineProperty(generator, 'dec', {
value: anticounter,
writable: true,
configurable: true,
enumerable: false
})
test('should wrap safely', function (t) {
t.plan(12)
t.equal(counter, generator.inc, 'method is mapped to function')
t.doesNotThrow(function () { generator.inc() }, 'original function works')
t.equal(1, outsider, 'calls have side effects')
var count = 0
function wrapper (original, name) {
t.equal(name, 'inc')
return function () {
count++
var returned = original.apply(this, arguments)
count++
return returned
}
}
shimmer.wrap(generator, 'inc', wrapper)
t.ok(generator.inc.__wrapped, "function tells us it's wrapped")
t.equal(generator.inc.__original, counter, 'original function is available')
t.doesNotThrow(function () { generator.inc() }, 'wrapping works')
t.equal(2, count, 'both pre and post increments should have happened')
t.equal(2, outsider, 'original function has still been called')
t.ok(generator.propertyIsEnumerable('inc'),
'wrapped enumerable property is still enumerable')
t.equal(Object.keys(generator.inc).length, 0,
'wrapped object has no additional properties')
shimmer.wrap(generator, 'dec', function (original) {
return function () {
return original.apply(this, arguments)
}
})
t.ok(!generator.propertyIsEnumerable('dec'),
'wrapped unenumerable property is still unenumerable')
})
test('wrap called with no arguments', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withExactArgs('no original function undefined to wrap')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.wrap()
}, "wrapping with no arguments doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with module but nothing else', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withExactArgs('no original function undefined to wrap')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.wrap(generator)
}, "wrapping with only 1 argument doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with original but no wrapper', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.twice()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.wrap(generator, 'inc')
}, "wrapping with only original method doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with non-function original', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withExactArgs('original object and wrapper must be functions')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.wrap({ orange: 'slices' }, 'orange', function () {})
}, "wrapping non-function original doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})
test('wrap called with non-function wrapper', function (t) {
t.plan(2)
var mock = sinon.expectation
.create('logger')
.withArgs('original object and wrapper must be functions')
.once()
shimmer({ logger: mock })
t.doesNotThrow(function () {
shimmer.wrap({ orange: function () {} }, 'orange', 'hamchunx')
}, "wrapping with non-function wrapper doesn't throw")
t.doesNotThrow(function () {
mock.verify()
}, 'logger was called with the expected message')
})