turborepo-remote-cache 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ![Turborepo Remote Cache](https://user-images.githubusercontent.com/6388707/149501949-9a385f04-ec94-45f4-9ea9-d211be123071.png)
2
2
 
3
3
 
4
- ![GitHub package.json version](https://img.shields.io/github/package-json/v/fox1t/turborepo-remote-cache) [![Build](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/build.yml/badge.svg)](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/build.yml) [![Docker Pulls](https://img.shields.io/docker/pulls/fox1t/turborepo-remote-cache?logo=docker)](https://hub.docker.com/r/fox1t/turborepo-remote-cache)
4
+ ![GitHub package.json version](https://img.shields.io/github/package-json/v/fox1t/turborepo-remote-cache) [![Build](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/build.yml/badge.svg)](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/build.yml) [![Docker Build](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/docker-build.yml/badge.svg?branch=main)](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/docker-build.yml) [![Docker Pulls](https://img.shields.io/docker/pulls/fox1t/turborepo-remote-cache?logo=docker)](https://hub.docker.com/r/fox1t/turborepo-remote-cache) ![npm](https://img.shields.io/npm/dt/turborepo-remote-cache)
5
5
 
6
6
 
7
7
  This project is an open-source implementation of the [Turborepo custom remote cache server](https://turborepo.org/docs/features/remote-caching#custom-remote-caches). If Vercel's official cache server isn't a viable option, this server is an alternative for self-hosted deployments.
@@ -28,15 +28,24 @@ It supports several storage providers and deploys environments. Moreover, the pr
28
28
  - `LOG_LEVEL`: String. Optional. Default value: `'info'`
29
29
  - `STORAGE_PROVIDER`: Optional. Possible values: `local | s3`. Default value: "local". Use this var to choose the storage provider.
30
30
  - `STORAGE_PATH`: String. Caching folder. If `STORAGE_PROVIDER` is set to `s3`, this will be the name of the bucket.
31
- - `S3_ACCESS_KEY`: String. Used only if `STORAGE_PROVIDER=s3`
32
- - `S3_SECRET_KEY`: String. Used only if `STORAGE_PROVIDER=s3`
33
- - `S3_REGION`: String. Used only if `STORAGE_PROVIDER=s3`
34
- - `S3_ENDPOINT`: String. Optional. Used only if `STORAGE_PROVIDER=s3`. __NOTE: This var can be omitted if the other s3 vars are provided.__
31
+
32
+ ## AWS Credentials and Region
33
+
34
+ AWS credentials and configuration are loaded as described in the AWS SDK documentation:
35
+
36
+ - [Setting Credentials](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html)
37
+ - [Setting Configuration](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html)
38
+
39
+ For example, you can set environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, or create a file
40
+ `~/.aws/credentials` with AWS credentials.
41
+
42
+ Specify the region using the `AWS_REGION` environment variable, or in `~/.aws/config`.
35
43
 
36
44
  ## Deployment Environments
37
45
  - [Deploy on Vercel](#deploy-on-vercel)
38
46
  - [Deploy on Docker](#deploy-on-docker)
39
47
  - [Deploy on DigitalOcean](#deploy-on-digitalocean)
48
+ - [Remoteless with npx](#deploy-remoteless-with-npx)
40
49
 
41
50
  ## Enable custom remote caching in your Turborepo monorepo
42
51
  To enable a custom remote caching server in your Turborepo monorepo, you must add a config file by hand. The `turbo login` command works only with the official Vercel server.
@@ -89,9 +98,9 @@ TURBO_TOKEN=
89
98
  LOG_LEVEL=
90
99
  STORAGE_PROVIDER=
91
100
  STORAGE_PATH=
92
- S3_ACCESS_KEY=
93
- S3_SECRET_KEY=
94
- S3_REGION=
101
+ AWS_ACCESS_KEY_ID=
102
+ AWS_SECRET_ACCESS_KEY=
103
+ AWS_REGION=
95
104
  S3_ENDPOINT=
96
105
  ```
97
106
  2. run the image using the `.env` file created on the step one.
@@ -106,6 +115,14 @@ __Note: Local storage isn't supported for this deployment method.__
106
115
 
107
116
  [![Deploy to DO](https://www.deploytodo.com/do-btn-blue.svg)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/fox1t/turborepo-remote-cache/tree/main)
108
117
 
118
+ ## Deploy "remoteless" with npx
119
+ If you have Node.js installed, you can run the server simply by typing
120
+
121
+ ```bash
122
+ npx turborepo-remote-cache
123
+ ```
124
+ **Note**: Same env vars rules apply as for other deployments.
125
+
109
126
 
110
127
  ## Contribute to this project
111
128
  1. clone this repository
package/build/app.js CHANGED
@@ -17,7 +17,7 @@ function createApp(options = {}) {
17
17
  });
18
18
  app.register(config_1.default).after(() => {
19
19
  app.register(remote_cache_1.default, {
20
- allowedTokens: [app.config.TURBO_TOKEN],
20
+ allowedTokens: [...app.config.TURBO_TOKEN],
21
21
  provider: app.config.STORAGE_PROVIDER,
22
22
  });
23
23
  });
package/build/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;AAAA,mEAAwE;AACxE,mEAA6B;AAC7B,qCAAmC;AACnC,uFAAgD;AAChD,2EAAqC;AACrC,qCAAiC;AAEjC,MAAM,IAAI,GAAG,IAAA,iBAAO,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AAEvC,SAAgB,SAAS,CAAC,UAAgC,EAAE;IAC1D,MAAM,GAAG,GAAG,IAAA,iBAAO,EAAC;QAClB,MAAM,EAAN,eAAM;QACN,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE;QACtB,GAAG,OAAO;KACX,CAAC,CAAA;IAEF,GAAG,CAAC,QAAQ,CAAC,gBAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QAC9B,GAAG,CAAC,QAAQ,CAAC,sBAAW,EAAE;YACxB,aAAa,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;YACvC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,gBAAgB;SACtC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC1C,IAAI,GAAG,CAAC,UAAU,EAAE;YAClB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACnB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;SAC/C;aAAM,IAAI,IAAA,aAAM,EAAC,GAAG,CAAC,EAAE;YACtB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACnB,KAAK;iBACF,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;iBAC3B,IAAI,CACH,GAAG,CAAC,IAAI,IAAI,IAAI;gBACd,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE;gBACvC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAC5C,CAAA;SACJ;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;SAC/C;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC;AAlCD,8BAkCC","sourcesContent":["import Fastify, { FastifyInstance, FastifyServerOptions } from 'fastify'\nimport hyperid from 'hyperid'\nimport { isBoom } from '@hapi/boom'\nimport remoteCache from './plugins/remote-cache'\nimport config from './plugins/config'\nimport { logger } from './logger'\n\nconst uuid = hyperid({ urlSafe: true })\n\nexport function createApp(options: FastifyServerOptions = {}): FastifyInstance {\n const app = Fastify({\n logger,\n genReqId: () => uuid(),\n ...options,\n })\n\n app.register(config).after(() => {\n app.register(remoteCache, {\n allowedTokens: [app.config.TURBO_TOKEN],\n provider: app.config.STORAGE_PROVIDER,\n })\n })\n\n app.setErrorHandler((err, request, reply) => {\n if (err.validation) {\n reply.log.warn(err)\n reply.code(400).send({ message: err.message })\n } else if (isBoom(err)) {\n reply.log.warn(err)\n reply\n .code(err.output.statusCode)\n .send(\n err.data != null\n ? { message: err.message, ...err.data }\n : { message: err.output.payload.message },\n )\n } else {\n request.log.error(err)\n reply.code(500).send({ message: err.message })\n }\n })\n\n return app\n}\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;AAAA,mEAAwE;AACxE,mEAA6B;AAC7B,qCAAmC;AACnC,uFAAgD;AAChD,2EAAqC;AACrC,qCAAiC;AAEjC,MAAM,IAAI,GAAG,IAAA,iBAAO,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AAEvC,SAAgB,SAAS,CAAC,UAAgC,EAAE;IAC1D,MAAM,GAAG,GAAG,IAAA,iBAAO,EAAC;QAClB,MAAM,EAAN,eAAM;QACN,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE;QACtB,GAAG,OAAO;KACX,CAAC,CAAA;IAEF,GAAG,CAAC,QAAQ,CAAC,gBAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QAC9B,GAAG,CAAC,QAAQ,CAAC,sBAAW,EAAE;YACxB,aAAa,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;YAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,gBAAgB;SACtC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC1C,IAAI,GAAG,CAAC,UAAU,EAAE;YAClB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACnB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;SAC/C;aAAM,IAAI,IAAA,aAAM,EAAC,GAAG,CAAC,EAAE;YACtB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACnB,KAAK;iBACF,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;iBAC3B,IAAI,CACH,GAAG,CAAC,IAAI,IAAI,IAAI;gBACd,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE;gBACvC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAC5C,CAAA;SACJ;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;SAC/C;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC;AAlCD,8BAkCC","sourcesContent":["import Fastify, { FastifyInstance, FastifyServerOptions } from 'fastify'\nimport hyperid from 'hyperid'\nimport { isBoom } from '@hapi/boom'\nimport remoteCache from './plugins/remote-cache'\nimport config from './plugins/config'\nimport { logger } from './logger'\n\nconst uuid = hyperid({ urlSafe: true })\n\nexport function createApp(options: FastifyServerOptions = {}): FastifyInstance {\n const app = Fastify({\n logger,\n genReqId: () => uuid(),\n ...options,\n })\n\n app.register(config).after(() => {\n app.register(remoteCache, {\n allowedTokens: [...app.config.TURBO_TOKEN],\n provider: app.config.STORAGE_PROVIDER,\n })\n })\n\n app.setErrorHandler((err, request, reply) => {\n if (err.validation) {\n reply.log.warn(err)\n reply.code(400).send({ message: err.message })\n } else if (isBoom(err)) {\n reply.log.warn(err)\n reply\n .code(err.output.statusCode)\n .send(\n err.data != null\n ? { message: err.message, ...err.data }\n : { message: err.output.payload.message },\n )\n } else {\n request.log.error(err)\n reply.code(500).send({ message: err.message })\n }\n })\n\n return app\n}\n"]}
package/build/cli.js CHANGED
File without changes
package/build/env.js CHANGED
@@ -19,7 +19,7 @@ var STORAGE_PROVIDERS;
19
19
  })(STORAGE_PROVIDERS = exports.STORAGE_PROVIDERS || (exports.STORAGE_PROVIDERS = {}));
20
20
  const schema = typebox_1.Type.Object({
21
21
  NODE_ENV: typebox_1.Type.Optional(typebox_1.Type.Enum(NODE_ENVS, { default: NODE_ENVS.PRODUCTION })),
22
- TURBO_TOKEN: typebox_1.Type.String(),
22
+ TURBO_TOKEN: typebox_1.Type.String({ separator: ',' }),
23
23
  PORT: typebox_1.Type.Number({ default: 3000 }),
24
24
  LOG_LEVEL: typebox_1.Type.Optional(typebox_1.Type.String({ default: 'info' })),
25
25
  STORAGE_PROVIDER: typebox_1.Type.Optional(typebox_1.Type.Enum(STORAGE_PROVIDERS, { default: STORAGE_PROVIDERS.LOCAL })),
@@ -28,13 +28,15 @@ const schema = typebox_1.Type.Object({
28
28
  S3_SECRET_KEY: typebox_1.Type.Optional(typebox_1.Type.String()),
29
29
  S3_REGION: typebox_1.Type.Optional(typebox_1.Type.String()),
30
30
  S3_ENDPOINT: typebox_1.Type.Optional(typebox_1.Type.String()),
31
- }, { additionalProperties: false });
31
+ }, {
32
+ additionalProperties: false,
33
+ });
32
34
  exports.env = (0, env_schema_1.default)({
33
35
  ajv: new ajv_1.default({
34
36
  removeAdditional: true,
35
37
  useDefaults: true,
36
38
  coerceTypes: true,
37
- keywords: ['kind', 'RegExp', 'modifier'],
39
+ keywords: ['kind', 'RegExp', 'modifier', env_schema_1.default.keywords.separator],
38
40
  }),
39
41
  dotenv: process.env.NODE_ENV === NODE_ENVS.DEVELOPMENT ? true : false,
40
42
  schema,
package/build/env.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":";;;;AAAA,2DAAqB;AACrB,yEAAkC;AAClC,+CAAgD;AAEhD,IAAK,SAIJ;AAJD,WAAK,SAAS;IACZ,sCAAyB,CAAA;IACzB,wCAA2B,CAAA;IAC3B,0BAAa,CAAA;AACf,CAAC,EAJI,SAAS,KAAT,SAAS,QAIb;AAED,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IAC3B,oCAAe,CAAA;IACf,8BAAS,CAAA;IACT,8BAAS,CAAA;AACX,CAAC,EAJW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAI5B;AAED,MAAM,MAAM,GAAG,cAAI,CAAC,MAAM,CACxB;IACE,QAAQ,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;IAChF,WAAW,EAAE,cAAI,CAAC,MAAM,EAAE;IAC1B,IAAI,EAAE,cAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACpC,SAAS,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,gBAAgB,EAAE,cAAI,CAAC,QAAQ,CAC7B,cAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC,CACnE;IACD,YAAY,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IAC1C,aAAa,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IAC3C,aAAa,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IAC3C,SAAS,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IACvC,WAAW,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;CAC1C,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAChC,CAAA;AAEY,QAAA,GAAG,GAAG,IAAA,oBAAS,EAAwB;IAClD,GAAG,EAAE,IAAI,aAAG,CAAC;QACX,gBAAgB,EAAE,IAAI;QACtB,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC;KACzC,CAAC;IACF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;IACrE,MAAM;CACP,CAAC,CAAA","sourcesContent":["import Ajv from 'ajv'\nimport envSchema from 'env-schema'\nimport { Type, Static } from '@sinclair/typebox'\n\nenum NODE_ENVS {\n PRODUCTION = 'production',\n DEVELOPMENT = 'development',\n TEST = 'test',\n}\n\nexport enum STORAGE_PROVIDERS {\n LOCAL = 'local',\n S3 = 'S3',\n s3 = 's3',\n}\n\nconst schema = Type.Object(\n {\n NODE_ENV: Type.Optional(Type.Enum(NODE_ENVS, { default: NODE_ENVS.PRODUCTION })),\n TURBO_TOKEN: Type.String(),\n PORT: Type.Number({ default: 3000 }),\n LOG_LEVEL: Type.Optional(Type.String({ default: 'info' })),\n STORAGE_PROVIDER: Type.Optional(\n Type.Enum(STORAGE_PROVIDERS, { default: STORAGE_PROVIDERS.LOCAL }),\n ),\n STORAGE_PATH: Type.Optional(Type.String()),\n S3_ACCESS_KEY: Type.Optional(Type.String()),\n S3_SECRET_KEY: Type.Optional(Type.String()),\n S3_REGION: Type.Optional(Type.String()),\n S3_ENDPOINT: Type.Optional(Type.String()),\n },\n { additionalProperties: false },\n)\n\nexport const env = envSchema<Static<typeof schema>>({\n ajv: new Ajv({\n removeAdditional: true,\n useDefaults: true,\n coerceTypes: true,\n keywords: ['kind', 'RegExp', 'modifier'],\n }),\n dotenv: process.env.NODE_ENV === NODE_ENVS.DEVELOPMENT ? true : false,\n schema,\n})\n"]}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":";;;;AAAA,2DAAqB;AACrB,yEAAkC;AAClC,+CAAgD;AAEhD,IAAK,SAIJ;AAJD,WAAK,SAAS;IACZ,sCAAyB,CAAA;IACzB,wCAA2B,CAAA;IAC3B,0BAAa,CAAA;AACf,CAAC,EAJI,SAAS,KAAT,SAAS,QAIb;AAED,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IAC3B,oCAAe,CAAA;IACf,8BAAS,CAAA;IACT,8BAAS,CAAA;AACX,CAAC,EAJW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAI5B;AAED,MAAM,MAAM,GAAG,cAAI,CAAC,MAAM,CACxB;IACE,QAAQ,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;IAChF,WAAW,EAAE,cAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IAC5C,IAAI,EAAE,cAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACpC,SAAS,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,gBAAgB,EAAE,cAAI,CAAC,QAAQ,CAC7B,cAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC,CACnE;IACD,YAAY,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IAC1C,aAAa,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IAC3C,aAAa,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IAC3C,SAAS,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;IACvC,WAAW,EAAE,cAAI,CAAC,QAAQ,CAAC,cAAI,CAAC,MAAM,EAAE,CAAC;CAC1C,EACD;IACE,oBAAoB,EAAE,KAAK;CAC5B,CACF,CAAA;AACY,QAAA,GAAG,GAAG,IAAA,oBAAS,EAAwB;IAClD,GAAG,EAAE,IAAI,aAAG,CAAC;QACX,gBAAgB,EAAE,IAAI;QACtB,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,oBAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;KACvE,CAAC;IACF,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;IACrE,MAAM;CACP,CAAC,CAAA","sourcesContent":["import Ajv from 'ajv'\nimport envSchema from 'env-schema'\nimport { Type, Static } from '@sinclair/typebox'\n\nenum NODE_ENVS {\n PRODUCTION = 'production',\n DEVELOPMENT = 'development',\n TEST = 'test',\n}\n\nexport enum STORAGE_PROVIDERS {\n LOCAL = 'local',\n S3 = 'S3',\n s3 = 's3',\n}\n\nconst schema = Type.Object(\n {\n NODE_ENV: Type.Optional(Type.Enum(NODE_ENVS, { default: NODE_ENVS.PRODUCTION })),\n TURBO_TOKEN: Type.String({ separator: ',' }),\n PORT: Type.Number({ default: 3000 }),\n LOG_LEVEL: Type.Optional(Type.String({ default: 'info' })),\n STORAGE_PROVIDER: Type.Optional(\n Type.Enum(STORAGE_PROVIDERS, { default: STORAGE_PROVIDERS.LOCAL }),\n ),\n STORAGE_PATH: Type.Optional(Type.String()),\n S3_ACCESS_KEY: Type.Optional(Type.String()),\n S3_SECRET_KEY: Type.Optional(Type.String()),\n S3_REGION: Type.Optional(Type.String()),\n S3_ENDPOINT: Type.Optional(Type.String()),\n },\n {\n additionalProperties: false,\n },\n)\nexport const env = envSchema<Static<typeof schema>>({\n ajv: new Ajv({\n removeAdditional: true,\n useDefaults: true,\n coerceTypes: true,\n keywords: ['kind', 'RegExp', 'modifier', envSchema.keywords.separator],\n }),\n dotenv: process.env.NODE_ENV === NODE_ENVS.DEVELOPMENT ? true : false,\n schema,\n})\n"]}
@@ -25,10 +25,7 @@ async function turboRemoteCache(instance, options) {
25
25
  }
26
26
  });
27
27
  instance.decorate('location', (0, storage_1.createLocation)(provider, {
28
- accessKey: instance.config.S3_ACCESS_KEY,
29
- secretKey: instance.config.S3_SECRET_KEY,
30
28
  path: instance.config.STORAGE_PATH,
31
- region: instance.config.S3_REGION,
32
29
  endpoint: instance.config.S3_ENDPOINT,
33
30
  }));
34
31
  await instance.register(async function (i) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/remote-cache/index.ts"],"names":[],"mappings":";;AACA,qCAAqD;AACrD,qCAAmD;AACnD,uCAA0C;AAC1C,mCAA6C;AAE7C,KAAK,UAAU,gBAAgB,CAC7B,QAAyB,EACzB,OAKC;IAED,MAAM,EACJ,aAAa,EACb,SAAS,GAAG,SAAS,EACrB,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,uBAAiB,CAAC,KAAK,GACnC,GAAG,OAAO,CAAA;IACX,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE;QAC3D,MAAM,IAAI,KAAK,CACb,+CAA+C,OAAO,aAAa,mBAAmB,CACvF,CAAA;KACF;IAED,QAAQ,CAAC,oBAAoB,CAC3B,0BAA0B,EAC1B,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,EAChC,KAAK,UAAU,MAAM,CAAC,OAAO,EAAE,OAAO;QACpC,OAAO,OAAO,CAAA;IAChB,CAAC,CACF,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAS,aAAa,CAAC,CAAA;IAC7C,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,WAAW,OAAO;QACnD,IAAI,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QACjD,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;QAEvE,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,IAAA,iBAAU,EAAC,8BAA8B,CAAC,CAAA;SACjD;QACD,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACtB,MAAM,IAAA,mBAAY,EAAC,6BAA6B,CAAC,CAAA;SAClD;IACH,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,QAAQ,CACf,UAAU,EACV,IAAA,wBAAc,EAAC,QAAQ,EAAE;QACvB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa;QACxC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa;QACxC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY;QAClC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS;QACjC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW;KACtC,CAAC,CACH,CAAA;IAED,MAAM,QAAQ,CAAC,QAAQ,CACrB,KAAK,WAAW,CAAC;QACf,CAAC,CAAC,KAAK,CAAC,oBAAW,CAAC,CAAA;QACpB,CAAC,CAAC,KAAK,CAAC,oBAAW,CAAC,CAAA;IACtB,CAAC,EACD,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,EAAE,CAC7B,CAAA;AACH,CAAC;AAED,kBAAe,gBAAgB,CAAA","sourcesContent":["import { FastifyInstance } from 'fastify'\nimport { badRequest, unauthorized } from '@hapi/boom'\nimport { getArtifact, putArtifact } from './routes'\nimport { createLocation } from './storage'\nimport { STORAGE_PROVIDERS } from '../../env'\n\nasync function turboRemoteCache(\n instance: FastifyInstance,\n options: {\n allowedTokens: string[]\n bodyLimit?: number\n apiVersion?: `v${number}`\n provider?: STORAGE_PROVIDERS\n },\n) {\n const {\n allowedTokens,\n bodyLimit = 104857600,\n apiVersion = 'v8',\n provider = STORAGE_PROVIDERS.LOCAL,\n } = options\n if (!(Array.isArray(allowedTokens) && allowedTokens.length)) {\n throw new Error(\n `'allowedTokens' options must be a string[], ${typeof allowedTokens} provided instead`,\n )\n }\n\n instance.addContentTypeParser<Buffer>(\n 'application/octet-stream',\n { parseAs: 'buffer', bodyLimit },\n async function parser(request, payload) {\n return payload\n },\n )\n\n const tokens = new Set<string>(allowedTokens)\n instance.addHook('onRequest', async function (request) {\n let authHeader = request.headers['authorization']\n authHeader = Array.isArray(authHeader) ? authHeader.join() : authHeader\n\n if (!authHeader) {\n throw badRequest(`Missing Authorization header`)\n }\n const [, token] = authHeader.split('Bearer ')\n if (!tokens.has(token)) {\n throw unauthorized(`Invalid authorization token`)\n }\n })\n\n instance.decorate(\n 'location',\n createLocation(provider, {\n accessKey: instance.config.S3_ACCESS_KEY,\n secretKey: instance.config.S3_SECRET_KEY,\n path: instance.config.STORAGE_PATH,\n region: instance.config.S3_REGION,\n endpoint: instance.config.S3_ENDPOINT,\n }),\n )\n\n await instance.register(\n async function (i) {\n i.route(getArtifact)\n i.route(putArtifact)\n },\n { prefix: `/${apiVersion}` },\n )\n}\n\nexport default turboRemoteCache\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/remote-cache/index.ts"],"names":[],"mappings":";;AACA,qCAAqD;AACrD,qCAAmD;AACnD,uCAA0C;AAC1C,mCAA6C;AAE7C,KAAK,UAAU,gBAAgB,CAC7B,QAAyB,EACzB,OAKC;IAED,MAAM,EACJ,aAAa,EACb,SAAS,GAAG,SAAS,EACrB,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,uBAAiB,CAAC,KAAK,GACnC,GAAG,OAAO,CAAA;IACX,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE;QAC3D,MAAM,IAAI,KAAK,CACb,+CAA+C,OAAO,aAAa,mBAAmB,CACvF,CAAA;KACF;IAED,QAAQ,CAAC,oBAAoB,CAC3B,0BAA0B,EAC1B,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,EAChC,KAAK,UAAU,MAAM,CAAC,OAAO,EAAE,OAAO;QACpC,OAAO,OAAO,CAAA;IAChB,CAAC,CACF,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAS,aAAa,CAAC,CAAA;IAC7C,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,WAAW,OAAO;QACnD,IAAI,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;QACjD,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;QAEvE,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,IAAA,iBAAU,EAAC,8BAA8B,CAAC,CAAA;SACjD;QACD,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACtB,MAAM,IAAA,mBAAY,EAAC,6BAA6B,CAAC,CAAA;SAClD;IACH,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,QAAQ,CACf,UAAU,EACV,IAAA,wBAAc,EAAC,QAAQ,EAAE;QACvB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY;QAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW;KACtC,CAAC,CACH,CAAA;IAED,MAAM,QAAQ,CAAC,QAAQ,CACrB,KAAK,WAAW,CAAC;QACf,CAAC,CAAC,KAAK,CAAC,oBAAW,CAAC,CAAA;QACpB,CAAC,CAAC,KAAK,CAAC,oBAAW,CAAC,CAAA;IACtB,CAAC,EACD,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,EAAE,CAC7B,CAAA;AACH,CAAC;AAED,kBAAe,gBAAgB,CAAA","sourcesContent":["import { FastifyInstance } from 'fastify'\nimport { badRequest, unauthorized } from '@hapi/boom'\nimport { getArtifact, putArtifact } from './routes'\nimport { createLocation } from './storage'\nimport { STORAGE_PROVIDERS } from '../../env'\n\nasync function turboRemoteCache(\n instance: FastifyInstance,\n options: {\n allowedTokens: string[]\n bodyLimit?: number\n apiVersion?: `v${number}`\n provider?: STORAGE_PROVIDERS\n },\n) {\n const {\n allowedTokens,\n bodyLimit = 104857600,\n apiVersion = 'v8',\n provider = STORAGE_PROVIDERS.LOCAL,\n } = options\n if (!(Array.isArray(allowedTokens) && allowedTokens.length)) {\n throw new Error(\n `'allowedTokens' options must be a string[], ${typeof allowedTokens} provided instead`,\n )\n }\n\n instance.addContentTypeParser<Buffer>(\n 'application/octet-stream',\n { parseAs: 'buffer', bodyLimit },\n async function parser(request, payload) {\n return payload\n },\n )\n\n const tokens = new Set<string>(allowedTokens)\n instance.addHook('onRequest', async function (request) {\n let authHeader = request.headers['authorization']\n authHeader = Array.isArray(authHeader) ? authHeader.join() : authHeader\n\n if (!authHeader) {\n throw badRequest(`Missing Authorization header`)\n }\n const [, token] = authHeader.split('Bearer ')\n if (!tokens.has(token)) {\n throw unauthorized(`Invalid authorization token`)\n }\n })\n\n instance.decorate(\n 'location',\n createLocation(provider, {\n path: instance.config.STORAGE_PATH,\n endpoint: instance.config.S3_ENDPOINT,\n }),\n )\n\n await instance.register(\n async function (i) {\n i.route(getArtifact)\n i.route(putArtifact)\n },\n { prefix: `/${apiVersion}` },\n )\n}\n\nexport default turboRemoteCache\n"]}
@@ -10,10 +10,10 @@ const local_1 = require("./local");
10
10
  const pipeline = (0, util_1.promisify)(stream_1.pipeline);
11
11
  const TURBO_CACHE_FOLDER_NAME = 'turborepocache';
12
12
  function createLocation(provider, providerOptions) {
13
- const { path = TURBO_CACHE_FOLDER_NAME, accessKey, secretKey, region, endpoint } = providerOptions;
13
+ const { path = TURBO_CACHE_FOLDER_NAME, endpoint } = providerOptions;
14
14
  const location = provider === env_1.STORAGE_PROVIDERS.LOCAL
15
15
  ? (0, local_1.createLocal)({ path })
16
- : (0, s3_1.createS3)({ accessKey, secretKey, bucket: path, region, endpoint });
16
+ : (0, s3_1.createS3)({ bucket: path, endpoint });
17
17
  async function getCachedArtifact(artifactId, teamId) {
18
18
  return new Promise((resolve, reject) => {
19
19
  const artifactPath = (0, path_1.join)(teamId, artifactId);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/remote-cache/storage/index.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAC3B,mCAA+D;AAC/D,+BAAgC;AAChC,sCAAgD;AAChD,6BAA+C;AAC/C,mCAAmD;AAEnD,MAAM,QAAQ,GAAG,IAAA,gBAAS,EAAC,iBAAgB,CAAC,CAAA;AAC5C,MAAM,uBAAuB,GAAG,gBAAyB,CAAA;AAIzD,SAAgB,cAAc,CAAC,QAA2B,EAAE,eAAgC;IAC1F,MAAM,EAAE,IAAI,GAAG,uBAAuB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAA;IAClG,MAAM,QAAQ,GACZ,QAAQ,KAAK,uBAAiB,CAAC,KAAK;QAClC,CAAC,CAAC,IAAA,mBAAW,EAAC,EAAE,IAAI,EAAE,CAAC;QACvB,CAAC,CAAC,IAAA,aAAQ,EAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IAExE,KAAK,UAAU,iBAAiB,CAAC,UAAkB,EAAE,MAAc;QACjE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAA;YAC7C,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;gBAC5C,IAAI,GAAG,EAAE;oBACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;iBACnB;gBACD,IAAI,CAAC,MAAM,EAAE;oBACX,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,YAAY,iBAAiB,CAAC,CAAC,CAAA;iBACpE;gBACD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAA;YAClD,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,UAAU,oBAAoB,CAAC,UAAkB,EAAE,MAAc,EAAE,QAAkB;QACxF,OAAO,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjF,CAAC;IACD,OAAO;QACL,iBAAiB;QACjB,oBAAoB;KACrB,CAAA;AACH,CAAC;AA7BD,wCA6BC","sourcesContent":["import { join } from 'path'\nimport { Readable, pipeline as pipelineCallback } from 'stream'\nimport { promisify } from 'util'\nimport { STORAGE_PROVIDERS } from '../../../env'\nimport { createS3, type S3Options } from './s3'\nimport { createLocal, LocalOptions } from './local'\n\nconst pipeline = promisify(pipelineCallback)\nconst TURBO_CACHE_FOLDER_NAME = 'turborepocache' as const\n\ntype ProviderOptions = Partial<LocalOptions> & Omit<S3Options, 'bucket'>\n\nexport function createLocation(provider: STORAGE_PROVIDERS, providerOptions: ProviderOptions) {\n const { path = TURBO_CACHE_FOLDER_NAME, accessKey, secretKey, region, endpoint } = providerOptions\n const location =\n provider === STORAGE_PROVIDERS.LOCAL\n ? createLocal({ path })\n : createS3({ accessKey, secretKey, bucket: path, region, endpoint })\n\n async function getCachedArtifact(artifactId: string, teamId: string) {\n return new Promise((resolve, reject) => {\n const artifactPath = join(teamId, artifactId)\n location.exists(artifactPath, (err, exists) => {\n if (err) {\n return reject(err)\n }\n if (!exists) {\n return reject(new Error(`Artifact ${artifactPath} doesn't exist.`))\n }\n resolve(location.createReadStream(artifactPath))\n })\n })\n }\n\n async function createCachedArtifact(artifactId: string, teamId: string, artifact: Readable) {\n return pipeline(artifact, location.createWriteStream(join(teamId, artifactId)))\n }\n return {\n getCachedArtifact,\n createCachedArtifact,\n }\n}\n\ndeclare module 'fastify' {\n interface FastifyInstance {\n location: {\n getCachedArtifact: ReturnType<typeof createLocation>['getCachedArtifact']\n createCachedArtifact: ReturnType<typeof createLocation>['createCachedArtifact']\n }\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/remote-cache/storage/index.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAC3B,mCAA+D;AAC/D,+BAAgC;AAChC,sCAAgD;AAChD,6BAA+C;AAC/C,mCAAmD;AAEnD,MAAM,QAAQ,GAAG,IAAA,gBAAS,EAAC,iBAAgB,CAAC,CAAA;AAC5C,MAAM,uBAAuB,GAAG,gBAAyB,CAAA;AAIzD,SAAgB,cAAc,CAAC,QAA2B,EAAE,eAAgC;IAC1F,MAAM,EAAE,IAAI,GAAG,uBAAuB,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAA;IACpE,MAAM,QAAQ,GACZ,QAAQ,KAAK,uBAAiB,CAAC,KAAK;QAClC,CAAC,CAAC,IAAA,mBAAW,EAAC,EAAE,IAAI,EAAE,CAAC;QACvB,CAAC,CAAC,IAAA,aAAQ,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAE1C,KAAK,UAAU,iBAAiB,CAAC,UAAkB,EAAE,MAAc;QACjE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAA;YAC7C,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;gBAC5C,IAAI,GAAG,EAAE;oBACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;iBACnB;gBACD,IAAI,CAAC,MAAM,EAAE;oBACX,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,YAAY,iBAAiB,CAAC,CAAC,CAAA;iBACpE;gBACD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAA;YAClD,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,UAAU,oBAAoB,CAAC,UAAkB,EAAE,MAAc,EAAE,QAAkB;QACxF,OAAO,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjF,CAAC;IACD,OAAO;QACL,iBAAiB;QACjB,oBAAoB;KACrB,CAAA;AACH,CAAC;AA7BD,wCA6BC","sourcesContent":["import { join } from 'path'\nimport { Readable, pipeline as pipelineCallback } from 'stream'\nimport { promisify } from 'util'\nimport { STORAGE_PROVIDERS } from '../../../env'\nimport { createS3, type S3Options } from './s3'\nimport { createLocal, LocalOptions } from './local'\n\nconst pipeline = promisify(pipelineCallback)\nconst TURBO_CACHE_FOLDER_NAME = 'turborepocache' as const\n\ntype ProviderOptions = Partial<LocalOptions> & Omit<S3Options, 'bucket'>\n\nexport function createLocation(provider: STORAGE_PROVIDERS, providerOptions: ProviderOptions) {\n const { path = TURBO_CACHE_FOLDER_NAME, endpoint } = providerOptions\n const location =\n provider === STORAGE_PROVIDERS.LOCAL\n ? createLocal({ path })\n : createS3({ bucket: path, endpoint })\n\n async function getCachedArtifact(artifactId: string, teamId: string) {\n return new Promise((resolve, reject) => {\n const artifactPath = join(teamId, artifactId)\n location.exists(artifactPath, (err, exists) => {\n if (err) {\n return reject(err)\n }\n if (!exists) {\n return reject(new Error(`Artifact ${artifactPath} doesn't exist.`))\n }\n resolve(location.createReadStream(artifactPath))\n })\n })\n }\n\n async function createCachedArtifact(artifactId: string, teamId: string, artifact: Readable) {\n return pipeline(artifact, location.createWriteStream(join(teamId, artifactId)))\n }\n return {\n getCachedArtifact,\n createCachedArtifact,\n }\n}\n\ndeclare module 'fastify' {\n interface FastifyInstance {\n location: {\n getCachedArtifact: ReturnType<typeof createLocation>['getCachedArtifact']\n createCachedArtifact: ReturnType<typeof createLocation>['createCachedArtifact']\n }\n }\n}\n"]}
@@ -4,16 +4,8 @@ exports.createS3 = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const s3_blob_store_1 = (0, tslib_1.__importDefault)(require("s3-blob-store"));
6
6
  const aws_sdk_1 = (0, tslib_1.__importDefault)(require("aws-sdk"));
7
- function createS3({ accessKey, secretKey, bucket, region, endpoint }) {
8
- if (!accessKey || !secretKey || !(region || endpoint)) {
9
- throw new Error(`To use S3 storage "accessKey (S3_ACCESS_KEY)", "secretKey (S3_SECRET_KEY)", and one of "region (S3_REGION)" and "endpoint (S3_ENDPOINT)" parameters are mandatory.`);
10
- }
7
+ function createS3({ bucket, endpoint }) {
11
8
  const client = new aws_sdk_1.default.S3({
12
- credentials: {
13
- accessKeyId: accessKey,
14
- secretAccessKey: secretKey,
15
- },
16
- ...(region ? { region } : {}),
17
9
  ...(endpoint ? { endpoint: new aws_sdk_1.default.Endpoint(endpoint) } : {}),
18
10
  ...(process.env.NODE_ENV === 'test' ? { sslEnabled: false, s3ForcePathStyle: true } : {}),
19
11
  });
@@ -1 +1 @@
1
- {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../../../src/plugins/remote-cache/storage/s3.ts"],"names":[],"mappings":";;;;AAAA,+EAA8B;AAC9B,mEAAyB;AASzB,SAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAa;IACpF,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,EAAE;QACrD,MAAM,IAAI,KAAK,CACb,oKAAoK,CACrK,CAAA;KACF;IAED,MAAM,MAAM,GAAG,IAAI,iBAAG,CAAC,EAAE,CAAC;QACxB,WAAW,EAAE;YACX,WAAW,EAAE,SAAS;YACtB,eAAe,EAAE,SAAS;SAC3B;QACD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,iBAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1F,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,IAAA,uBAAE,EAAC;QAClB,MAAM;QACN,MAAM;KACP,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AACjB,CAAC;AAvBD,4BAuBC","sourcesContent":["import s3 from 's3-blob-store'\nimport aws from 'aws-sdk'\n\nexport interface S3Options {\n accessKey?: string\n secretKey?: string\n region?: string\n endpoint?: string\n bucket: string\n}\nexport function createS3({ accessKey, secretKey, bucket, region, endpoint }: S3Options) {\n if (!accessKey || !secretKey || !(region || endpoint)) {\n throw new Error(\n `To use S3 storage \"accessKey (S3_ACCESS_KEY)\", \"secretKey (S3_SECRET_KEY)\", and one of \"region (S3_REGION)\" and \"endpoint (S3_ENDPOINT)\" parameters are mandatory.`,\n )\n }\n\n const client = new aws.S3({\n credentials: {\n accessKeyId: accessKey,\n secretAccessKey: secretKey,\n },\n ...(region ? { region } : {}),\n ...(endpoint ? { endpoint: new aws.Endpoint(endpoint) } : {}),\n ...(process.env.NODE_ENV === 'test' ? { sslEnabled: false, s3ForcePathStyle: true } : {}),\n })\n\n const location = s3({\n client,\n bucket,\n })\n\n return location\n}\n"]}
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../../../src/plugins/remote-cache/storage/s3.ts"],"names":[],"mappings":";;;;AAAA,+EAA8B;AAC9B,mEAAyB;AAMzB,SAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAa;IACtD,MAAM,MAAM,GAAG,IAAI,iBAAG,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,iBAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1F,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,IAAA,uBAAE,EAAC;QAClB,MAAM;QACN,MAAM;KACP,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AACjB,CAAC;AAZD,4BAYC","sourcesContent":["import s3 from 's3-blob-store'\nimport aws from 'aws-sdk'\n\nexport interface S3Options {\n endpoint?: string\n bucket: string\n}\nexport function createS3({ bucket, endpoint }: S3Options) {\n const client = new aws.S3({\n ...(endpoint ? { endpoint: new aws.Endpoint(endpoint) } : {}),\n ...(process.env.NODE_ENV === 'test' ? { sslEnabled: false, s3ForcePathStyle: true } : {}),\n })\n\n const location = s3({\n client,\n bucket,\n })\n\n return location\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "turborepo-remote-cache",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Turborepo remote cache server",
5
5
  "main": "build",
6
6
  "author": "Maksim Sinik <maksim@sinik.it>",
@@ -74,9 +74,9 @@
74
74
  }
75
75
  },
76
76
  "bugs": {
77
- "url": "https://github.com/nucleode/typescript-microservice-starter/issues"
77
+ "url": "https://github.com/fox1t/turborepo-remote-cache/issues"
78
78
  },
79
- "homepage": "https://github.com/nucleode/typescript-microservice-starter#readme",
79
+ "homepage": "https://github.com/fox1t/turborepo-remote-cache#readme",
80
80
  "directories": {
81
81
  "test": "test"
82
82
  },