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 +25 -8
- package/build/app.js +1 -1
- package/build/app.js.map +1 -1
- package/build/cli.js +0 -0
- package/build/env.js +5 -3
- package/build/env.js.map +1 -1
- package/build/plugins/remote-cache/index.js +0 -3
- package/build/plugins/remote-cache/index.js.map +1 -1
- package/build/plugins/remote-cache/storage/index.js +2 -2
- package/build/plugins/remote-cache/storage/index.js.map +1 -1
- package/build/plugins/remote-cache/storage/s3.js +1 -9
- package/build/plugins/remote-cache/storage/s3.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
 [](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/build.yml) [](https://hub.docker.com/r/fox1t/turborepo-remote-cache)
|
|
4
|
+
 [](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/build.yml) [](https://github.com/fox1t/turborepo-remote-cache/actions/workflows/docker-build.yml) [](https://hub.docker.com/r/fox1t/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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
[](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;
|
|
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
|
-
}, {
|
|
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;
|
|
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,
|
|
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,
|
|
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)({
|
|
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,
|
|
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({
|
|
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;
|
|
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.
|
|
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/
|
|
77
|
+
"url": "https://github.com/fox1t/turborepo-remote-cache/issues"
|
|
78
78
|
},
|
|
79
|
-
"homepage": "https://github.com/
|
|
79
|
+
"homepage": "https://github.com/fox1t/turborepo-remote-cache#readme",
|
|
80
80
|
"directories": {
|
|
81
81
|
"test": "test"
|
|
82
82
|
},
|