@shapio/local 0.5.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/LICENSE +201 -0
- package/dist/advisoryLocks-COlJQc1r.js +4181 -0
- package/dist/advisoryLocks-COlJQc1r.js.map +1 -0
- package/dist/errors-SK0PwPKC.js +26 -0
- package/dist/errors-SK0PwPKC.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +4481 -0
- package/dist/index.js.map +1 -0
- package/dist/migrator-CIKnDfZy.js +4152 -0
- package/dist/migrator-CIKnDfZy.js.map +1 -0
- package/dist/next.d.ts +10 -0
- package/dist/next.js +40 -0
- package/dist/next.js.map +1 -0
- package/dist/nodeRuntime-DzuiHUhY.js +12 -0
- package/dist/nodeRuntime-DzuiHUhY.js.map +1 -0
- package/dist/s3Adapter-BqCKtI3Y.js +143 -0
- package/dist/s3Adapter-BqCKtI3Y.js.map +1 -0
- package/package.json +77 -0
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { shapioTags } from "@shapio/client";
|
|
2
|
+
//#region src/nodeRuntime.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* In-process reads open database connections, which the Edge runtime (Next.js middleware and `runtime = 'edge'`
|
|
5
|
+
* routes, Vercel Edge Functions) cannot. Spelled out so bundlers that inline `process.env.NEXT_RUNTIME` see it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const assertNodeRuntime: () => void;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { shapioTags };
|
|
10
|
+
//# sourceMappingURL=next.d.ts.map
|
package/dist/next.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { t as assertNodeRuntime } from "./nodeRuntime-DzuiHUhY.js";
|
|
2
|
+
import { shapioTags } from "@shapio/client";
|
|
3
|
+
//#region src/next.ts
|
|
4
|
+
/**
|
|
5
|
+
* Next.js helpers for `@shapio/local`. Importing this module from an Edge route fails at once with an
|
|
6
|
+
* explanation (in-process reads need the Node.js runtime).
|
|
7
|
+
*
|
|
8
|
+
* Add the package to `serverExternalPackages` in `next.config.ts`, so Next loads it from `node_modules` once
|
|
9
|
+
* per process instead of bundling a copy per route (each copy would open its own database pool):
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* const nextConfig: NextConfig = { serverExternalPackages: ['@shapio/local'] };
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Caching. In-process reads do not go through `fetch`, so Next's data cache does not see them, and the cache
|
|
16
|
+
* options `@shapio/client` accepts have no effect here. Cache a read where you call it, tagged with
|
|
17
|
+
* `shapioTags`, the same tags HTTP reads carry, so your `/api/revalidate` route's `revalidateTag` calls refresh
|
|
18
|
+
* both. With `cacheComponents` on:
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { cacheTag } from 'next/cache';
|
|
22
|
+
* import { shapioTags } from '@shapio/local/next';
|
|
23
|
+
*
|
|
24
|
+
* export const getArticles = async (locale: string) => {
|
|
25
|
+
* 'use cache';
|
|
26
|
+
* cacheTag(shapioTags.site(), shapioTags.model('articles'));
|
|
27
|
+
* return (await shapio.delivery.list<Article>('articles', { locale })).data;
|
|
28
|
+
* };
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Without `cacheComponents`, wrap the read in `unstable_cache(read, [key], { tags: [...] })` instead.
|
|
32
|
+
* `cacheTag()` cannot be called for you: on Next.js 16.3 it throws unless `cacheComponents` is on (E886) and
|
|
33
|
+
* anywhere outside a `"use cache"` function (E819), including inside `unstable_cache` and plain route
|
|
34
|
+
* handlers.
|
|
35
|
+
*/
|
|
36
|
+
assertNodeRuntime();
|
|
37
|
+
//#endregion
|
|
38
|
+
export { assertNodeRuntime, shapioTags };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=next.js.map
|
package/dist/next.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.js","names":[],"sources":["../src/next.ts"],"sourcesContent":["import { assertNodeRuntime } from './nodeRuntime.js';\n\n/**\n * Next.js helpers for `@shapio/local`. Importing this module from an Edge route fails at once with an\n * explanation (in-process reads need the Node.js runtime).\n *\n * Add the package to `serverExternalPackages` in `next.config.ts`, so Next loads it from `node_modules` once\n * per process instead of bundling a copy per route (each copy would open its own database pool):\n *\n * ```ts\n * const nextConfig: NextConfig = { serverExternalPackages: ['@shapio/local'] };\n * ```\n *\n * Caching. In-process reads do not go through `fetch`, so Next's data cache does not see them, and the cache\n * options `@shapio/client` accepts have no effect here. Cache a read where you call it, tagged with\n * `shapioTags`, the same tags HTTP reads carry, so your `/api/revalidate` route's `revalidateTag` calls refresh\n * both. With `cacheComponents` on:\n *\n * ```ts\n * import { cacheTag } from 'next/cache';\n * import { shapioTags } from '@shapio/local/next';\n *\n * export const getArticles = async (locale: string) => {\n * 'use cache';\n * cacheTag(shapioTags.site(), shapioTags.model('articles'));\n * return (await shapio.delivery.list<Article>('articles', { locale })).data;\n * };\n * ```\n *\n * Without `cacheComponents`, wrap the read in `unstable_cache(read, [key], { tags: [...] })` instead.\n * `cacheTag()` cannot be called for you: on Next.js 16.3 it throws unless `cacheComponents` is on (E886) and\n * anywhere outside a `\"use cache\"` function (E819), including inside `unstable_cache` and plain route\n * handlers.\n */\nassertNodeRuntime();\n\nexport { shapioTags } from '@shapio/client';\nexport { assertNodeRuntime } from './nodeRuntime.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,kBAAkB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/nodeRuntime.ts
|
|
2
|
+
/**
|
|
3
|
+
* In-process reads open database connections, which the Edge runtime (Next.js middleware and `runtime = 'edge'`
|
|
4
|
+
* routes, Vercel Edge Functions) cannot. Spelled out so bundlers that inline `process.env.NEXT_RUNTIME` see it.
|
|
5
|
+
*/
|
|
6
|
+
const assertNodeRuntime = () => {
|
|
7
|
+
if (typeof process !== "undefined" && process.env.NEXT_RUNTIME === "edge" || typeof globalThis.EdgeRuntime !== "undefined") throw new Error("@shapio/local reads the database and runs on the Node.js runtime only. Use it from a Node.js route or page, or read over HTTP with @shapio/client's createClient on the Edge runtime");
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { assertNodeRuntime as t };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=nodeRuntime-DzuiHUhY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeRuntime-DzuiHUhY.js","names":[],"sources":["../src/nodeRuntime.ts"],"sourcesContent":["/**\n * In-process reads open database connections, which the Edge runtime (Next.js middleware and `runtime = 'edge'`\n * routes, Vercel Edge Functions) cannot. Spelled out so bundlers that inline `process.env.NEXT_RUNTIME` see it.\n */\nexport const assertNodeRuntime = (): void => {\n const edge =\n (typeof process !== 'undefined' && process.env.NEXT_RUNTIME === 'edge') ||\n typeof (globalThis as { EdgeRuntime?: unknown }).EdgeRuntime !== 'undefined';\n if (edge) {\n throw new Error(\n '@shapio/local reads the database and runs on the Node.js runtime only. Use it from a Node.js route ' +\n \"or page, or read over HTTP with @shapio/client's createClient on the Edge runtime\",\n );\n }\n};\n"],"mappings":";;;;;AAIA,MAAa,0BAAgC;CAI3C,IAFG,OAAO,YAAY,eAAe,QAAQ,IAAI,iBAAiB,UAChE,OAAQ,WAAyC,gBAAgB,aAEjE,MAAM,IAAI,MACR,sLAEF;AAEJ"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { i as isValidStorageKey, n as ObjectNotFoundError, r as encodeKeyPath, t as InvalidStorageKeyError } from "./errors-SK0PwPKC.js";
|
|
2
|
+
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
3
|
+
import { createPresignedPost } from "@aws-sdk/s3-presigned-post";
|
|
4
|
+
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
5
|
+
//#region ../../apps/api/src/media/contentDisposition.ts
|
|
6
|
+
/**
|
|
7
|
+
* A Content-Disposition value that names the file safely: an ASCII fallback plus the RFC 5987 UTF-8 form,
|
|
8
|
+
* so quotes, semicolons or line breaks in a filename can never inject header parameters.
|
|
9
|
+
*/
|
|
10
|
+
const contentDisposition = (filename, type = "inline") => {
|
|
11
|
+
return `${type}; filename="${filename.replace(/[^\x20-\x7e]/g, "_").replace(/["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(filename)}`;
|
|
12
|
+
};
|
|
13
|
+
/** Types a browser only ever displays passively: opening one directly cannot run script. */
|
|
14
|
+
const PASSIVE_INLINE_TYPE = /^(image\/(png|jpeg|gif|webp|avif|bmp|tiff|x-icon|vnd\.microsoft\.icon)|video\/.+|audio\/.+)$/;
|
|
15
|
+
/**
|
|
16
|
+
* Content-Disposition to store on an object in a bucket. Public objects can be served straight from the
|
|
17
|
+
* bucket or a CDN, where Shapio's sandboxing headers are absent; anything that could run as a page there
|
|
18
|
+
* (SVG, HTML, XML, PDF...) is stored as an attachment, so opening it downloads it. `<img>` tags still show
|
|
19
|
+
* an SVG, since embedding ignores Content-Disposition.
|
|
20
|
+
*/
|
|
21
|
+
const bucketContentDisposition = (contentType) => PASSIVE_INLINE_TYPE.test(contentType.toLowerCase()) ? void 0 : "attachment";
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region ../../apps/api/src/media/s3Adapter.ts
|
|
24
|
+
/** R2 accepts any region name ("auto" by convention); AWS needs the bucket's real region. */
|
|
25
|
+
const DEFAULT_REGION = "us-east-1";
|
|
26
|
+
const isNotFound = (error) => error instanceof S3ServiceException && (error.$metadata.httpStatusCode === 404 || error.name === "NotFound" || error.name === "NoSuchKey");
|
|
27
|
+
const createS3Client = (config) => new S3Client({
|
|
28
|
+
region: config.region ?? DEFAULT_REGION,
|
|
29
|
+
...config.endpoint ? { endpoint: config.endpoint } : {},
|
|
30
|
+
forcePathStyle: config.forcePathStyle,
|
|
31
|
+
...config.accessKeyId && config.secretAccessKey ? { credentials: {
|
|
32
|
+
accessKeyId: config.accessKeyId,
|
|
33
|
+
secretAccessKey: config.secretAccessKey
|
|
34
|
+
} } : {},
|
|
35
|
+
requestChecksumCalculation: "WHEN_REQUIRED",
|
|
36
|
+
responseChecksumValidation: "WHEN_REQUIRED"
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Any S3-compatible service (AWS S3, Cloudflare R2, B2, Spaces, Wasabi, versitygw). Private objects are read
|
|
40
|
+
* through presigned GET URLs; browsers upload straight to the bucket with a presigned POST whose policy
|
|
41
|
+
* limits size and content type, so Shapio never streams upload bytes.
|
|
42
|
+
*/
|
|
43
|
+
const createS3Adapter = ({ config, publicBaseUrl, client }) => {
|
|
44
|
+
const s3 = client ?? createS3Client(config);
|
|
45
|
+
const Bucket = config.bucket;
|
|
46
|
+
const checkKey = (key) => {
|
|
47
|
+
if (!isValidStorageKey(key)) throw new InvalidStorageKeyError(key);
|
|
48
|
+
return key;
|
|
49
|
+
};
|
|
50
|
+
const head = async (key) => {
|
|
51
|
+
try {
|
|
52
|
+
const result = await s3.send(new HeadObjectCommand({
|
|
53
|
+
Bucket,
|
|
54
|
+
Key: checkKey(key)
|
|
55
|
+
}));
|
|
56
|
+
return {
|
|
57
|
+
size: result.ContentLength ?? 0,
|
|
58
|
+
contentType: result.ContentType
|
|
59
|
+
};
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (isNotFound(error)) return;
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
driver: "s3",
|
|
67
|
+
put: async (key, body, { contentType, contentLength }) => {
|
|
68
|
+
await s3.send(new PutObjectCommand({
|
|
69
|
+
Bucket,
|
|
70
|
+
Key: checkKey(key),
|
|
71
|
+
Body: body,
|
|
72
|
+
ContentType: contentType,
|
|
73
|
+
ContentLength: Buffer.isBuffer(body) ? body.length : contentLength,
|
|
74
|
+
ContentDisposition: bucketContentDisposition(contentType)
|
|
75
|
+
}));
|
|
76
|
+
},
|
|
77
|
+
getStream: async (key, range) => {
|
|
78
|
+
try {
|
|
79
|
+
const result = await s3.send(new GetObjectCommand({
|
|
80
|
+
Bucket,
|
|
81
|
+
Key: checkKey(key),
|
|
82
|
+
...range ? { Range: `bytes=${range.start}-${range.end}` } : {}
|
|
83
|
+
}));
|
|
84
|
+
if (!result.Body) throw new ObjectNotFoundError(key);
|
|
85
|
+
return result.Body;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
throw isNotFound(error) ? new ObjectNotFoundError(key, { cause: error }) : error;
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
head,
|
|
91
|
+
exists: async (key) => await head(key) !== void 0,
|
|
92
|
+
delete: async (key) => {
|
|
93
|
+
await s3.send(new DeleteObjectCommand({
|
|
94
|
+
Bucket,
|
|
95
|
+
Key: checkKey(key)
|
|
96
|
+
}));
|
|
97
|
+
},
|
|
98
|
+
signedGetUrl: async (key, { expiresInSeconds, filename, contentType }) => getSignedUrl(s3, new GetObjectCommand({
|
|
99
|
+
Bucket,
|
|
100
|
+
Key: checkKey(key),
|
|
101
|
+
ResponseContentType: contentType,
|
|
102
|
+
ResponseContentDisposition: contentDisposition(filename)
|
|
103
|
+
}), { expiresIn: expiresInSeconds }),
|
|
104
|
+
publicUrl: (key) => publicBaseUrl ? `${publicBaseUrl}/${encodeKeyPath(checkKey(key))}` : void 0,
|
|
105
|
+
presignedUpload: async ({ key, contentType, maxSizeBytes, expiresInSeconds }) => {
|
|
106
|
+
const disposition = bucketContentDisposition(contentType);
|
|
107
|
+
const { url, fields } = await createPresignedPost(s3, {
|
|
108
|
+
Bucket,
|
|
109
|
+
Key: checkKey(key),
|
|
110
|
+
Conditions: [
|
|
111
|
+
[
|
|
112
|
+
"content-length-range",
|
|
113
|
+
1,
|
|
114
|
+
maxSizeBytes
|
|
115
|
+
],
|
|
116
|
+
[
|
|
117
|
+
"eq",
|
|
118
|
+
"$Content-Type",
|
|
119
|
+
contentType
|
|
120
|
+
],
|
|
121
|
+
...disposition ? [[
|
|
122
|
+
"eq",
|
|
123
|
+
"$Content-Disposition",
|
|
124
|
+
disposition
|
|
125
|
+
]] : []
|
|
126
|
+
],
|
|
127
|
+
Fields: {
|
|
128
|
+
"Content-Type": contentType,
|
|
129
|
+
...disposition ? { "Content-Disposition": disposition } : {}
|
|
130
|
+
},
|
|
131
|
+
Expires: expiresInSeconds
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
url,
|
|
135
|
+
fields
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
export { createS3Adapter };
|
|
142
|
+
|
|
143
|
+
//# sourceMappingURL=s3Adapter-BqCKtI3Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3Adapter-BqCKtI3Y.js","names":[],"sources":["../../../apps/api/src/media/contentDisposition.ts","../../../apps/api/src/media/s3Adapter.ts"],"sourcesContent":["/**\n * A Content-Disposition value that names the file safely: an ASCII fallback plus the RFC 5987 UTF-8 form,\n * so quotes, semicolons or line breaks in a filename can never inject header parameters.\n */\nexport const contentDisposition = (filename: string, type: 'inline' | 'attachment' = 'inline'): string => {\n const ascii = filename.replace(/[^\\x20-\\x7e]/g, '_').replace(/[\"\\\\]/g, '_');\n return `${type}; filename=\"${ascii}\"; filename*=UTF-8''${encodeURIComponent(filename)}`;\n};\n\n/** Types a browser only ever displays passively: opening one directly cannot run script. */\nconst PASSIVE_INLINE_TYPE =\n /^(image\\/(png|jpeg|gif|webp|avif|bmp|tiff|x-icon|vnd\\.microsoft\\.icon)|video\\/.+|audio\\/.+)$/;\n\n/**\n * Content-Disposition to store on an object in a bucket. Public objects can be served straight from the\n * bucket or a CDN, where Shapio's sandboxing headers are absent; anything that could run as a page there\n * (SVG, HTML, XML, PDF...) is stored as an attachment, so opening it downloads it. `<img>` tags still show\n * an SVG, since embedding ignores Content-Disposition.\n */\nexport const bucketContentDisposition = (contentType: string): string | undefined =>\n PASSIVE_INLINE_TYPE.test(contentType.toLowerCase()) ? undefined : 'attachment';\n","import type { Readable } from 'node:stream';\nimport {\n DeleteObjectCommand,\n GetObjectCommand,\n HeadObjectCommand,\n PutObjectCommand,\n S3Client,\n S3ServiceException,\n} from '@aws-sdk/client-s3';\nimport { createPresignedPost } from '@aws-sdk/s3-presigned-post';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport type { S3StorageConfig } from '../config/index.js';\nimport { bucketContentDisposition, contentDisposition } from './contentDisposition.js';\nimport { InvalidStorageKeyError, ObjectNotFoundError } from './errors.js';\nimport { encodeKeyPath, isValidStorageKey } from './keys.js';\nimport type { StorageAdapter } from './types.js';\n\n/** R2 accepts any region name (\"auto\" by convention); AWS needs the bucket's real region. */\nconst DEFAULT_REGION = 'us-east-1';\n\nconst isNotFound = (error: unknown): boolean =>\n error instanceof S3ServiceException &&\n (error.$metadata.httpStatusCode === 404 || error.name === 'NotFound' || error.name === 'NoSuchKey');\n\nexport const createS3Client = (config: S3StorageConfig): S3Client =>\n new S3Client({\n region: config.region ?? DEFAULT_REGION,\n ...(config.endpoint ? { endpoint: config.endpoint } : {}),\n forcePathStyle: config.forcePathStyle,\n ...(config.accessKeyId && config.secretAccessKey\n ? { credentials: { accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey } }\n : {}),\n // Only send/validate checksums when an operation requires them: several S3-compatible services\n // (R2, B2 and other gateways) reject the SDK's default streaming CRC32 trailers.\n requestChecksumCalculation: 'WHEN_REQUIRED',\n responseChecksumValidation: 'WHEN_REQUIRED',\n });\n\nexport type S3AdapterOptions = {\n config: S3StorageConfig;\n publicBaseUrl: string | undefined;\n /** Injected in tests; created from `config` otherwise. */\n client?: S3Client;\n};\n\n/**\n * Any S3-compatible service (AWS S3, Cloudflare R2, B2, Spaces, Wasabi, versitygw). Private objects are read\n * through presigned GET URLs; browsers upload straight to the bucket with a presigned POST whose policy\n * limits size and content type, so Shapio never streams upload bytes.\n */\nexport const createS3Adapter = ({ config, publicBaseUrl, client }: S3AdapterOptions): StorageAdapter => {\n const s3 = client ?? createS3Client(config);\n const Bucket = config.bucket;\n const checkKey = (key: string) => {\n if (!isValidStorageKey(key)) {\n throw new InvalidStorageKeyError(key);\n }\n return key;\n };\n\n const head = async (key: string) => {\n try {\n const result = await s3.send(new HeadObjectCommand({ Bucket, Key: checkKey(key) }));\n return { size: result.ContentLength ?? 0, contentType: result.ContentType };\n } catch (error) {\n if (isNotFound(error)) {\n return undefined;\n }\n throw error;\n }\n };\n\n return {\n driver: 's3',\n put: async (key, body, { contentType, contentLength }) => {\n await s3.send(\n new PutObjectCommand({\n Bucket,\n Key: checkKey(key),\n Body: body,\n ContentType: contentType,\n ContentLength: Buffer.isBuffer(body) ? body.length : contentLength,\n ContentDisposition: bucketContentDisposition(contentType),\n }),\n );\n },\n getStream: async (key, range) => {\n try {\n const result = await s3.send(\n new GetObjectCommand({\n Bucket,\n Key: checkKey(key),\n ...(range ? { Range: `bytes=${range.start}-${range.end}` } : {}),\n }),\n );\n if (!result.Body) {\n throw new ObjectNotFoundError(key);\n }\n return result.Body as Readable;\n } catch (error) {\n throw isNotFound(error) ? new ObjectNotFoundError(key, { cause: error }) : error;\n }\n },\n head,\n exists: async (key) => (await head(key)) !== undefined,\n delete: async (key) => {\n await s3.send(new DeleteObjectCommand({ Bucket, Key: checkKey(key) }));\n },\n signedGetUrl: async (key, { expiresInSeconds, filename, contentType }) =>\n getSignedUrl(\n s3,\n new GetObjectCommand({\n Bucket,\n Key: checkKey(key),\n ResponseContentType: contentType,\n ResponseContentDisposition: contentDisposition(filename),\n }),\n { expiresIn: expiresInSeconds },\n ),\n publicUrl: (key) => (publicBaseUrl ? `${publicBaseUrl}/${encodeKeyPath(checkKey(key))}` : undefined),\n presignedUpload: async ({ key, contentType, maxSizeBytes, expiresInSeconds }) => {\n const disposition = bucketContentDisposition(contentType);\n const { url, fields } = await createPresignedPost(s3, {\n Bucket,\n Key: checkKey(key),\n Conditions: [\n ['content-length-range', 1, maxSizeBytes],\n ['eq', '$Content-Type', contentType],\n ...(disposition ? [['eq', '$Content-Disposition', disposition] as ['eq', string, string]] : []),\n ],\n Fields: {\n 'Content-Type': contentType,\n ...(disposition ? { 'Content-Disposition': disposition } : {}),\n },\n Expires: expiresInSeconds,\n });\n return { url, fields };\n },\n };\n};\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shapio/local",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Shapio's delivery API as function calls in your server process: no HTTP hop, same permissions and shapes as @shapio/client.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://shapio.dev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/mybrokengnome/shapio.git",
|
|
10
|
+
"directory": "packages/local"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/mybrokengnome/shapio/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=24"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"@shapio/source": "./src/index.ts",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./next": {
|
|
26
|
+
"@shapio/source": "./src/next.ts",
|
|
27
|
+
"types": "./dist/next.d.ts",
|
|
28
|
+
"default": "./dist/next.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@shapio/client": "0.5.0",
|
|
36
|
+
"@shapio/schema": "0.5.0",
|
|
37
|
+
"kysely": "0.29.6",
|
|
38
|
+
"pg": "8.23.1",
|
|
39
|
+
"pino": "10.3.1",
|
|
40
|
+
"typebox": "1.3.34"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@aws-sdk/client-s3": "^3.1143.0",
|
|
44
|
+
"@aws-sdk/s3-presigned-post": "^3.1143.0",
|
|
45
|
+
"@aws-sdk/s3-request-presigner": "^3.1143.0",
|
|
46
|
+
"mysql2": "^3.24.5"
|
|
47
|
+
},
|
|
48
|
+
"peerDependenciesMeta": {
|
|
49
|
+
"@aws-sdk/client-s3": {
|
|
50
|
+
"optional": true
|
|
51
|
+
},
|
|
52
|
+
"@aws-sdk/s3-presigned-post": {
|
|
53
|
+
"optional": true
|
|
54
|
+
},
|
|
55
|
+
"@aws-sdk/s3-request-presigner": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"mysql2": {
|
|
59
|
+
"optional": true
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@shapio/cms": "0.5.0",
|
|
64
|
+
"@types/node": "24.19.1",
|
|
65
|
+
"@types/pg": "8.23.1",
|
|
66
|
+
"tsdown": "0.23.0",
|
|
67
|
+
"typescript": "6.0.3",
|
|
68
|
+
"vitest": "5.0.3"
|
|
69
|
+
},
|
|
70
|
+
"publishConfig": {
|
|
71
|
+
"access": "public"
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"build": "tsdown",
|
|
75
|
+
"typecheck": "tsc -p tsconfig.json"
|
|
76
|
+
}
|
|
77
|
+
}
|