diff --git a/.gitignore b/.gitignore index f7cb75e..11f68f3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ yarn-error.log* # Compiled version dist/ +bin/ # Runtime data pids diff --git a/.vscode/settings.json b/.vscode/settings.json index e09bd7b..da4dccd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,6 +18,7 @@ "tslib" ], "search.exclude": { + "**/bin": true, "**/node_modules": true, "**/docs/jsdocs": true } diff --git a/Dockerfile b/Dockerfile index 83ab455..b1ccb46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,12 +8,12 @@ RUN npm install --production --silent COPY . ./src RUN cd ./src;npm install --silent;npm run build # Copy de compiled version -RUN cp -r ./src/dist ./dist +RUN cp -r ./src/bin ./bin # Remove the sources RUN rm -rf ./src # Enviroment por production ENV NODE_ENV production # Vulumes for mapping -VOLUME ["/usr/src/app/server"] +VOLUME ["/usr/src/app/bin/server"] # Start command CMD npm start \ No newline at end of file diff --git a/package.json b/package.json index 5aafd7e..59776c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "api-watcher", - "version": "0.1.0", + "version": "0.2.0", "description": "API Watcher", "engines": { "node": ">=12" @@ -11,7 +11,7 @@ "docker-build": "IMAGE=$npm_package_name:latest;docker build --rm --pull -f \"./Dockerfile\" -t $IMAGE \".\"", "docker-start": "IMAGE=$npm_package_name:latest;docker run -it -v $INIT_CWD/server:/usr/src/app/server $IMAGE", "docker-start-from-hub": "IMAGE=act2react/api-watcher:version-$npm_package_version;docker run -it -v $INIT_CWD/server:/usr/src/app/server $IMAGE", - "start": "node ./dist/index.js", + "start": "node ./bin/index.js", "lint": "npx eslint --config ./.eslintrc ./**/*.ts", "test": "jest", "test-clear": "rm -rf coverage;rm -rf dist", diff --git a/test/tests/api/isClientContent.ts b/test/tests/api/isClientContent.ts new file mode 100644 index 0000000..cfc530e --- /dev/null +++ b/test/tests/api/isClientContent.ts @@ -0,0 +1,14 @@ +import path from 'path'; + +import { readFile } from '../../../tools/fs'; +import getIsClientContent from '../../../utils/getIsClientContent'; + +const isClientPath = path.resolve(__dirname, '../../../tools/isClient.ts'); + +/** + * isClient content should be the same as `isClient.ts` file + */ +test('isClient content', async (): Promise => { + const fileContent = await readFile(isClientPath, 'utf8'); + expect(getIsClientContent()).toBe(fileContent); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 3e7f5fe..1755b27 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ "sourceMap": true, "skipLibCheck": true, "baseUrl": ".", - "outDir": "./dist", + "outDir": "./bin", "rootDir": ".", "extendedDiagnostics": true, "typeRoots": [ diff --git a/utils/apiProxy.ts b/utils/apiProxy.ts index d4d77bc..f1f59dc 100644 --- a/utils/apiProxy.ts +++ b/utils/apiProxy.ts @@ -10,7 +10,7 @@ import { } from '../model/api'; import { defaultApiSourcePath, defaultProxyTargetPath } from '../settings'; -import { getFilesRecursively, writeFile, copyFile } from '../tools/fs'; +import { getFilesRecursively, writeFile } from '../tools/fs'; import getModuleInfo from './getModuleInfo'; import getGroupedModelImports from './getGroupedModelImports'; import getProxyMethod from './getProxyMethod'; @@ -18,11 +18,10 @@ import updateApiObject from './updateApiObject'; import getApiObjectText from './getApiObject'; import getMethodWrapper from './getMethodWrapper'; import getSocketProvider from './getSocketProvider'; +import getIsClientContent from './getIsClientContent'; export const api: APIStructure = {}; -const isClientInternalPath = path.resolve(__dirname, '../tools/isClient.ts'); - /** * Gets external needed imports */ @@ -84,10 +83,10 @@ export const build = async ( apiSourcePath = defaultApiSourcePath, proxyTargetPath = defaultProxyTargetPath, ): Promise => { + const files = await getFilesRecursively(apiSourcePath, ['.ts']); const proxyIndexPath = path.resolve(proxyTargetPath, 'index.ts'); const socketFilePath = path.resolve(proxyTargetPath, 'socket.ts'); const isClientFilePath = path.resolve(proxyTargetPath, 'isClient.ts'); - const files = await getFilesRecursively(apiSourcePath, ['.ts']); const modulesInfo: ModuleInfo[] = await Promise.all( files.map(file => getModuleInfo(file, apiSourcePath)), @@ -129,7 +128,7 @@ export const build = async ( const groupedImports = getGroupedModelImports(imports); await writeFile(socketFilePath, getSocketProvider()); - await copyFile(isClientInternalPath, isClientFilePath); + await writeFile(isClientFilePath, getIsClientContent()); await writeFile( proxyIndexPath, [ diff --git a/utils/getIsClientContent.ts b/utils/getIsClientContent.ts new file mode 100644 index 0000000..ec0a661 --- /dev/null +++ b/utils/getIsClientContent.ts @@ -0,0 +1,23 @@ +const getIsClientContent = (): string => `let forceServerSimulation = false; + +/** + * Allows you to disable client detection + * @param {boolean} value True to force Server Side Simulation + */ +export const setForceServerSimulation = (value: boolean): void => { + forceServerSimulation = value; +}; + +/** + * Checks if the script is running on the client side + */ +const isClient = (): boolean => { + if (forceServerSimulation) { + return false; + } + return typeof window === 'object'; +}; + +export default isClient;` + +export default getIsClientContent; diff --git a/utils/initWatchers.ts b/utils/initWatchers.ts index 52ee1ae..710decc 100644 --- a/utils/initWatchers.ts +++ b/utils/initWatchers.ts @@ -25,7 +25,9 @@ const initWatchers = async ( ): Promise => { const pathExists = await exists(serverPath); if (!pathExists) { - throw new Error(`Provided server path doesn't exist`); + const error = `Provided server path doesn't exist: ${fullPath(serverPath)}`; + out.error(error); + throw new Error(error); } const proxyTargetPath = path.resolve(mainPath, proxyPath);