Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
26c5235
mswのインストールとworkerの生成
Futadaruma Jan 20, 2025
2cef1e3
handlerの追加
Futadaruma Jan 20, 2025
29d83d2
contestsのモックを実装
Futadaruma Jan 20, 2025
6ed630c
パスの記法を変更
Futadaruma Jan 20, 2025
7826dc4
パスの記法を相対パスで統一
Futadaruma Jan 21, 2025
111718f
groupsのモックを実装
Futadaruma Jan 21, 2025
8ba2b30
モックの表示名が実態に即するように変更
Futadaruma Jan 21, 2025
5d26989
projectsのモックの枠組みを実装
Futadaruma Jan 21, 2025
92acc70
モックの内容が実態に即するように変更
Futadaruma Jan 21, 2025
1e1270e
usersのモックの枠組みを実装
Futadaruma Jan 23, 2025
ef0d049
format
Futadaruma Mar 25, 2025
873574e
viteとmswのバージョン更新
Futadaruma Mar 25, 2025
741eccc
typo
Futadaruma Mar 28, 2025
3f2860f
call SW in`main.ts`
Futadaruma Apr 24, 2025
8f200a2
moved await
Futadaruma Apr 24, 2025
e831bbe
deleted the unnecessary function
Futadaruma Apr 24, 2025
a5cb17f
wip
Futadaruma May 21, 2025
73e882e
update msw
Futadaruma Jun 25, 2025
b2a3623
deleted unnecessary proxy setting
Futadaruma Jun 25, 2025
7ca6944
moved setupWorker to handler.ts
Futadaruma Jun 25, 2025
e268922
uninstalled `concurrently` & deleted the command fot prism
Futadaruma Jun 26, 2025
2d8a4ed
brushed up sample data & refactored endpoints
Futadaruma Jun 26, 2025
471ea99
brushed up sample contest data
Futadaruma Jun 27, 2025
8b6a2c1
deleted unnecessary if blocks
Futadaruma Jun 27, 2025
2e7215b
added sample group data
Futadaruma Jun 27, 2025
345d87a
fix param in contest handler
Futadaruma Jun 27, 2025
be5a4ca
fix param in project handler
Futadaruma Jun 27, 2025
ad32f2f
run `npm run format`
Futadaruma Jun 27, 2025
40258fa
followed the way of enabling mock on reference
Futadaruma Jun 27, 2025
8d546aa
add account id to sample data
Futadaruma Jun 28, 2025
18b9c22
fix typo
Futadaruma Jul 2, 2025
6d28914
不足していたエンドポイントを追加しmockを完成
Futadaruma Jul 13, 2025
e24c7b1
コンフリクト解消に向けてパッケージの更新
Futadaruma Jul 13, 2025
fa11988
パッケージバージョンの相違により生じるコンフリクトを解消
Futadaruma Jul 13, 2025
d2ee73d
指定バージョンに誤りがあったので修正
Futadaruma Jul 13, 2025
6e68b86
コンフリクトの解消
Futadaruma Jul 13, 2025
502b849
Merge branch 'main' into dev/mock
Futadaruma Jul 13, 2025
870985d
Recreate package-lock.json
Futadaruma Jul 13, 2025
77f6b47
不要なprPermittedプロパティを削除
Futadaruma Jul 13, 2025
74b772e
clean reinstall of all dependencies
Futadaruma Jul 13, 2025
2d3132c
fix typo
Futadaruma Aug 25, 2025
3945e91
Merge branch 'main' into dev/mock
Futadaruma Oct 20, 2025
c973fa5
chore: 依存関係のコンフリクトを解決
Futadaruma Oct 20, 2025
427f96f
chore: mswをバージョン2.11.6にアップデート
Futadaruma Oct 20, 2025
f7a2476
eslintのwarningを解消
Futadaruma Oct 22, 2025
bf2b15c
サンプルドメインをRFC準拠のものに変更
Futadaruma Oct 22, 2025
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
1,936 changes: 1,006 additions & 930 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
"format:nofix": "prettier --cache --check \"src/**/*.{vue,ts}\"",
"type-check": "vue-tsc --noEmit",
"test": "vitest --passWithNoTests",
"gen-api": "node scripts/generateApi.js",
"start-mock": "prism mock -p 4010 -d https://raw.githubusercontent.com/traPtitech/traPortfolio/main/docs/swagger/traPortfolio.v1.yaml"
"gen-api": "node scripts/generateApi.js"
},
"dependencies": {
"autosize": "^6.0.1",
Expand All @@ -35,6 +34,7 @@
"eslint": "^9.34.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-vue": "^10.4.0",
"msw": "^2.11.6",
"node-fetch": "^3.3.2",
"prettier": "^3.6.2",
"sass": "^1.89.2",
Expand All @@ -46,5 +46,10 @@
"vue-tsc": "3.0.6"
},
"private": true,
"type": "module"
"type": "module",
"msw": {
"workerDirectory": [
"public"
]
}
}
349 changes: 349 additions & 0 deletions public/mockServiceWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
/* eslint-disable */
/* tslint:disable */

/**
* Mock Service Worker.
* @see https://github.com/mswjs/msw
* - Please do NOT modify this file.
*/

const PACKAGE_VERSION = '2.11.6'
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()

addEventListener('install', function () {
self.skipWaiting()
})

addEventListener('activate', function (event) {
event.waitUntil(self.clients.claim())
})

addEventListener('message', async function (event) {
const clientId = Reflect.get(event.source || {}, 'id')

if (!clientId || !self.clients) {
return
}

const client = await self.clients.get(clientId)

if (!client) {
return
}

const allClients = await self.clients.matchAll({
type: 'window',
})

switch (event.data) {
case 'KEEPALIVE_REQUEST': {
sendToClient(client, {
type: 'KEEPALIVE_RESPONSE',
})
break
}

case 'INTEGRITY_CHECK_REQUEST': {
sendToClient(client, {
type: 'INTEGRITY_CHECK_RESPONSE',
payload: {
packageVersion: PACKAGE_VERSION,
checksum: INTEGRITY_CHECKSUM,
},
})
break
}

case 'MOCK_ACTIVATE': {
activeClientIds.add(clientId)

sendToClient(client, {
type: 'MOCKING_ENABLED',
payload: {
client: {
id: client.id,
frameType: client.frameType,
},
},
})
break
}

case 'CLIENT_CLOSED': {
activeClientIds.delete(clientId)

const remainingClients = allClients.filter((client) => {
return client.id !== clientId
})

// Unregister itself when there are no more clients
if (remainingClients.length === 0) {
self.registration.unregister()
}

break
}
}
})

addEventListener('fetch', function (event) {
const requestInterceptedAt = Date.now()

// Bypass navigation requests.
if (event.request.mode === 'navigate') {
return
}

// Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests.
if (
event.request.cache === 'only-if-cached' &&
event.request.mode !== 'same-origin'
) {
return
}

// Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests
// after it's been terminated (still remains active until the next reload).
if (activeClientIds.size === 0) {
return
}

const requestId = crypto.randomUUID()
event.respondWith(handleRequest(event, requestId, requestInterceptedAt))
})

/**
* @param {FetchEvent} event
* @param {string} requestId
* @param {number} requestInterceptedAt
*/
async function handleRequest(event, requestId, requestInterceptedAt) {
const client = await resolveMainClient(event)
const requestCloneForEvents = event.request.clone()
const response = await getResponse(
event,
client,
requestId,
requestInterceptedAt,
)

// Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) {
const serializedRequest = await serializeRequest(requestCloneForEvents)

// Clone the response so both the client and the library could consume it.
const responseClone = response.clone()

sendToClient(
client,
{
type: 'RESPONSE',
payload: {
isMockedResponse: IS_MOCKED_RESPONSE in response,
request: {
id: requestId,
...serializedRequest,
},
response: {
type: responseClone.type,
status: responseClone.status,
statusText: responseClone.statusText,
headers: Object.fromEntries(responseClone.headers.entries()),
body: responseClone.body,
},
},
},
responseClone.body ? [serializedRequest.body, responseClone.body] : [],
)
}

return response
}

/**
* Resolve the main client for the given event.
* Client that issues a request doesn't necessarily equal the client
* that registered the worker. It's with the latter the worker should
* communicate with during the response resolving phase.
* @param {FetchEvent} event
* @returns {Promise<Client | undefined>}
*/
async function resolveMainClient(event) {
const client = await self.clients.get(event.clientId)

if (activeClientIds.has(event.clientId)) {
return client
}

if (client?.frameType === 'top-level') {
return client
}

const allClients = await self.clients.matchAll({
type: 'window',
})

return allClients
.filter((client) => {
// Get only those clients that are currently visible.
return client.visibilityState === 'visible'
})
.find((client) => {
// Find the client ID that's recorded in the
// set of clients that have registered the worker.
return activeClientIds.has(client.id)
})
}

/**
* @param {FetchEvent} event
* @param {Client | undefined} client
* @param {string} requestId
* @param {number} requestInterceptedAt
* @returns {Promise<Response>}
*/
async function getResponse(event, client, requestId, requestInterceptedAt) {
// Clone the request because it might've been already used
// (i.e. its body has been read and sent to the client).
const requestClone = event.request.clone()

function passthrough() {
// Cast the request headers to a new Headers instance
// so the headers can be manipulated with.
const headers = new Headers(requestClone.headers)

// Remove the "accept" header value that marked this request as passthrough.
// This prevents request alteration and also keeps it compliant with the
// user-defined CORS policies.
const acceptHeader = headers.get('accept')
if (acceptHeader) {
const values = acceptHeader.split(',').map((value) => value.trim())
const filteredValues = values.filter(
(value) => value !== 'msw/passthrough',
)

if (filteredValues.length > 0) {
headers.set('accept', filteredValues.join(', '))
} else {
headers.delete('accept')
}
}

return fetch(requestClone, { headers })
}

// Bypass mocking when the client is not active.
if (!client) {
return passthrough()
}

// Bypass initial page load requests (i.e. static assets).
// The absence of the immediate/parent client in the map of the active clients
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
// and is not ready to handle requests.
if (!activeClientIds.has(client.id)) {
return passthrough()
}

// Notify the client that a request has been intercepted.
const serializedRequest = await serializeRequest(event.request)
const clientMessage = await sendToClient(
client,
{
type: 'REQUEST',
payload: {
id: requestId,
interceptedAt: requestInterceptedAt,
...serializedRequest,
},
},
[serializedRequest.body],
)

switch (clientMessage.type) {
case 'MOCK_RESPONSE': {
return respondWithMock(clientMessage.data)
}

case 'PASSTHROUGH': {
return passthrough()
}
}

return passthrough()
}

/**
* @param {Client} client
* @param {any} message
* @param {Array<Transferable>} transferrables
* @returns {Promise<any>}
*/
function sendToClient(client, message, transferrables = []) {
return new Promise((resolve, reject) => {
const channel = new MessageChannel()

channel.port1.onmessage = (event) => {
if (event.data && event.data.error) {
return reject(event.data.error)
}

resolve(event.data)
}

client.postMessage(message, [
channel.port2,
...transferrables.filter(Boolean),
])
})
}

/**
* @param {Response} response
* @returns {Response}
*/
function respondWithMock(response) {
// Setting response status code to 0 is a no-op.
// However, when responding with a "Response.error()", the produced Response
// instance will have status code set to 0. Since it's not possible to create
// a Response instance with status code 0, handle that use-case separately.
if (response.status === 0) {
return Response.error()
}

const mockedResponse = new Response(response.body, response)

Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
value: true,
enumerable: true,
})

return mockedResponse
}

/**
* @param {Request} request
*/
async function serializeRequest(request) {
return {
url: request.url,
mode: request.mode,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
cache: request.cache,
credentials: request.credentials,
destination: request.destination,
integrity: request.integrity,
redirect: request.redirect,
referrer: request.referrer,
referrerPolicy: request.referrerPolicy,
body: await request.arrayBuffer(),
keepalive: request.keepalive,
}
}
Loading
Loading