@ya-accelerators/web-backend-framework 0.0.102 → 0.0.104
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/@types/error.d.ts +7 -3
- package/@types/general.d.ts +11 -7
- package/dist/connector/google-auth/index.d.ts +14 -1
- package/dist/connector/google-auth/index.js +12 -7
- package/dist/connector/google-auth/index.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/internal/federation/index.d.ts +8 -2
- package/dist/internal/federation/index.js +45 -4
- package/dist/internal/federation/index.js.map +1 -1
- package/dist/server/trpc/declaration/index.d.ts +5 -1
- package/dist/server/uploads/index.js +1 -1
- package/dist/server/uploads/index.js.map +1 -1
- package/package.json +2 -2
package/@types/error.d.ts
CHANGED
package/@types/general.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
type
|
|
3
|
-
type
|
|
4
|
-
type
|
|
1
|
+
declare global {
|
|
2
|
+
type JsonPrimitive = string | number | boolean
|
|
3
|
+
type JsonObject = { [key: string]: JsonValue }
|
|
4
|
+
type JsonArray = JsonValue[]
|
|
5
|
+
type JsonValue = JsonPrimitive | JsonObject | JsonArray
|
|
5
6
|
|
|
6
|
-
type EmptyObject = Record<string, never>
|
|
7
|
-
const Empty: EmptyObject
|
|
7
|
+
type EmptyObject = Record<string, never>
|
|
8
|
+
const Empty: EmptyObject
|
|
8
9
|
|
|
9
|
-
type Simplify<T> = { [K in keyof T]: T[K] } & {}
|
|
10
|
+
type Simplify<T> = { [K in keyof T]: T[K] } & {}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import type { AuthClient } from 'google-auth-library';
|
|
2
|
+
import { awsSecurityCredentialsSupplier } from '../../internal/federation/index.ts';
|
|
3
|
+
type GoogleCloudAwsClientOptions = {
|
|
4
|
+
type: string;
|
|
5
|
+
audience: string;
|
|
6
|
+
subject_token_type: string;
|
|
7
|
+
token_url: string;
|
|
8
|
+
service_account_impersonation_url: string;
|
|
9
|
+
credential_source?: undefined;
|
|
10
|
+
aws_security_credentials_supplier: typeof awsSecurityCredentialsSupplier;
|
|
11
|
+
scopes: string[];
|
|
12
|
+
};
|
|
2
13
|
export declare const googleCloudAuth: (wifConfigBase64: string) => {
|
|
3
14
|
authClient: () => Promise<AuthClient>;
|
|
15
|
+
awsClientOptions: () => GoogleCloudAwsClientOptions;
|
|
4
16
|
bearer: () => Promise<string>;
|
|
5
17
|
};
|
|
6
|
-
export declare const googleIdTokenAuth: (wifConfigBase64: string, audience: string, forHost
|
|
18
|
+
export declare const googleIdTokenAuth: (wifConfigBase64: string, audience: string, forHost: string) => {
|
|
7
19
|
bearer: () => Promise<string>;
|
|
8
20
|
withAuth: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
9
21
|
};
|
|
@@ -17,3 +29,4 @@ export declare const googleImpersonatedAuth: (wifConfigBase64: string, { label,
|
|
|
17
29
|
serviceAccountEmail: string;
|
|
18
30
|
}>;
|
|
19
31
|
};
|
|
32
|
+
export {};
|
|
@@ -6,6 +6,12 @@ const REFRESH_SKEW_MS = 5 * 60 * 1000;
|
|
|
6
6
|
export const googleCloudAuth = (wifConfigBase64) => {
|
|
7
7
|
let client;
|
|
8
8
|
let inflight;
|
|
9
|
+
const createAwsClientOptions = () => ({
|
|
10
|
+
...parseWifConfig(wifConfigBase64, 'googleCloudAuth'),
|
|
11
|
+
credential_source: undefined,
|
|
12
|
+
aws_security_credentials_supplier: awsSecurityCredentialsSupplier,
|
|
13
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
14
|
+
});
|
|
9
15
|
const authClient = async () => {
|
|
10
16
|
if (client !== undefined) {
|
|
11
17
|
return client;
|
|
@@ -13,12 +19,7 @@ export const googleCloudAuth = (wifConfigBase64) => {
|
|
|
13
19
|
if (inflight === undefined) {
|
|
14
20
|
inflight = (async () => {
|
|
15
21
|
const { AwsClient } = await import('google-auth-library');
|
|
16
|
-
return new AwsClient(
|
|
17
|
-
...parseWifConfig(wifConfigBase64, 'googleCloudAuth'),
|
|
18
|
-
credential_source: undefined,
|
|
19
|
-
aws_security_credentials_supplier: awsSecurityCredentialsSupplier,
|
|
20
|
-
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
21
|
-
});
|
|
22
|
+
return new AwsClient(createAwsClientOptions());
|
|
22
23
|
})().finally(() => {
|
|
23
24
|
inflight = undefined;
|
|
24
25
|
});
|
|
@@ -28,6 +29,7 @@ export const googleCloudAuth = (wifConfigBase64) => {
|
|
|
28
29
|
};
|
|
29
30
|
return {
|
|
30
31
|
authClient,
|
|
32
|
+
awsClientOptions: createAwsClientOptions,
|
|
31
33
|
bearer: async () => {
|
|
32
34
|
const { token } = await (await authClient()).getAccessToken().catch((e) => {
|
|
33
35
|
logger.error('google-auth', { op: 'access-token', error: e });
|
|
@@ -43,6 +45,9 @@ export const googleCloudAuth = (wifConfigBase64) => {
|
|
|
43
45
|
// `forHost` (host[:port]) host-binds the Bearer that `withAuth` forwards: it is attached only to a fetch
|
|
44
46
|
// whose target host matches, so an unrelated outbound fetch inside the closure never receives the credential.
|
|
45
47
|
export const googleIdTokenAuth = (wifConfigBase64, audience, forHost) => {
|
|
48
|
+
if (typeof forHost !== 'string' || forHost.trim() === '') {
|
|
49
|
+
throw new Error('googleIdTokenAuth: forHost is required');
|
|
50
|
+
}
|
|
46
51
|
let cached;
|
|
47
52
|
let inflight;
|
|
48
53
|
const fetchIdToken = async () => {
|
|
@@ -74,7 +79,7 @@ export const googleIdTokenAuth = (wifConfigBase64, audience, forHost) => {
|
|
|
74
79
|
};
|
|
75
80
|
return {
|
|
76
81
|
bearer,
|
|
77
|
-
withAuth: async (fn) => runWithRequestHeaders({ authorization: await bearer() }, fn,
|
|
82
|
+
withAuth: async (fn) => runWithRequestHeaders({ authorization: await bearer() }, fn, { forHost }),
|
|
78
83
|
};
|
|
79
84
|
};
|
|
80
85
|
export const googleImpersonatedAuth = (wifConfigBase64, { label, lifetime, targetScopes }) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connector/google-auth/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,EAAE,8BAA8B,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACvH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,MAAM,gBAAgB,GAAG,IAAI,CAAA;AAC7B,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connector/google-auth/index.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const constants: {
|
|
|
2
2
|
OAUTH_DEV_REDIRECTOR_URL: string;
|
|
3
3
|
UPLOADS_PREFIX: string;
|
|
4
4
|
UPLOADS_EXPIRE_DAYS: number;
|
|
5
|
+
UPLOAD_TOKEN_LENGTH: number;
|
|
5
6
|
UPLOAD_FILENAME_MAX_LENGTH: number;
|
|
6
7
|
UPLOAD_CONTENT_TYPE_MAX_LENGTH: number;
|
|
7
8
|
UPLOAD_STORED_CONTENT_TYPE: string;
|
package/dist/constants.js
CHANGED
|
@@ -2,6 +2,7 @@ export const constants = {
|
|
|
2
2
|
OAUTH_DEV_REDIRECTOR_URL: 'https://jbilvarnjxcewv7spngtoaowia0krqmu.lambda-url.eu-north-1.on.aws/',
|
|
3
3
|
UPLOADS_PREFIX: '_uploads/',
|
|
4
4
|
UPLOADS_EXPIRE_DAYS: 1,
|
|
5
|
+
UPLOAD_TOKEN_LENGTH: 43,
|
|
5
6
|
UPLOAD_FILENAME_MAX_LENGTH: 255,
|
|
6
7
|
UPLOAD_CONTENT_TYPE_MAX_LENGTH: 255,
|
|
7
8
|
UPLOAD_STORED_CONTENT_TYPE: 'application/octet-stream',
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,wBAAwB,EAAE,wEAAwE;IAClG,cAAc,EAAE,WAAW;IAC3B,mBAAmB,EAAE,CAAC;IACtB,0BAA0B,EAAE,GAAG;IAC/B,8BAA8B,EAAE,GAAG;IACnC,0BAA0B,EAAE,0BAA0B;IAEtD,4GAA4G;IAC5G,6GAA6G;IAC7G,4GAA4G;IAC5G,+CAA+C;IAC/C,uBAAuB,EAAE;QACvB,YAAY;QACZ,WAAW;QACX,WAAW;QACX,cAAc;QACd,YAAY;QACZ,YAAY;KACJ;IAEV,mGAAmG;IACnG,uGAAuG;IACvG,sGAAsG;IACtG,yDAAyD;IACzD,iBAAiB,EAAE;QACjB,eAAe;QACf,qBAAqB;QACrB,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,QAAQ;QACR,SAAS;QACT,SAAS;QACT,OAAO;QACP,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,WAAW;QACX,SAAS;QACT,SAAS;QACT,KAAK;QACL,QAAQ;QACR,OAAO;QACP,UAAU;QACV,WAAW;QACX,aAAa;QACb,OAAO;QACP,MAAM;QACN,cAAc;QACd,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,YAAY;QACZ,UAAU;QACV,UAAU;QACV,KAAK;QACL,kBAAkB;QAClB,oBAAoB;QACpB,wBAAwB;QACxB,YAAY;QACZ,SAAS;QACT,WAAW;QACX,aAAa;QACb,WAAW;QACX,aAAa;QACb,kBAAkB;QAClB,UAAU;QACV,YAAY;QACZ,mBAAmB;KACX;IAEV,qGAAqG;IACrG,4DAA4D;IAC5D,mBAAmB,EAAE,CAAC,IAAI,CAAU;IAEpC,qGAAqG;IACrG,yBAAyB;IACzB,iCAAiC,EAAE,CAAC,MAAM,CAAU;CACrD,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,wBAAwB,EAAE,wEAAwE;IAClG,cAAc,EAAE,WAAW;IAC3B,mBAAmB,EAAE,CAAC;IACtB,mBAAmB,EAAE,EAAE;IACvB,0BAA0B,EAAE,GAAG;IAC/B,8BAA8B,EAAE,GAAG;IACnC,0BAA0B,EAAE,0BAA0B;IAEtD,4GAA4G;IAC5G,6GAA6G;IAC7G,4GAA4G;IAC5G,+CAA+C;IAC/C,uBAAuB,EAAE;QACvB,YAAY;QACZ,WAAW;QACX,WAAW;QACX,cAAc;QACd,YAAY;QACZ,YAAY;KACJ;IAEV,mGAAmG;IACnG,uGAAuG;IACvG,sGAAsG;IACtG,yDAAyD;IACzD,iBAAiB,EAAE;QACjB,eAAe;QACf,qBAAqB;QACrB,QAAQ;QACR,YAAY;QACZ,WAAW;QACX,QAAQ;QACR,SAAS;QACT,SAAS;QACT,OAAO;QACP,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,WAAW;QACX,SAAS;QACT,SAAS;QACT,KAAK;QACL,QAAQ;QACR,OAAO;QACP,UAAU;QACV,WAAW;QACX,aAAa;QACb,OAAO;QACP,MAAM;QACN,cAAc;QACd,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,YAAY;QACZ,UAAU;QACV,UAAU;QACV,KAAK;QACL,kBAAkB;QAClB,oBAAoB;QACpB,wBAAwB;QACxB,YAAY;QACZ,SAAS;QACT,WAAW;QACX,aAAa;QACb,WAAW;QACX,aAAa;QACb,kBAAkB;QAClB,UAAU;QACV,YAAY;QACZ,mBAAmB;KACX;IAEV,qGAAqG;IACrG,4DAA4D;IAC5D,mBAAmB,EAAE,CAAC,IAAI,CAAU;IAEpC,qGAAqG;IACrG,yBAAyB;IACzB,iCAAiC,EAAE,CAAC,MAAM,CAAU;CACrD,CAAA"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AwsClientOptions } from 'google-auth-library';
|
|
2
1
|
export declare const awsSecurityCredentialsSupplier: {
|
|
3
2
|
getAwsRegion: () => Promise<"eu-central-1" | "eu-north-1" | "eu-south-1" | "eu-south-2" | "eu-west-1" | "eu-west-3">;
|
|
4
3
|
getAwsSecurityCredentials: () => Promise<{
|
|
@@ -7,8 +6,15 @@ export declare const awsSecurityCredentialsSupplier: {
|
|
|
7
6
|
token: string | undefined;
|
|
8
7
|
}>;
|
|
9
8
|
};
|
|
10
|
-
export declare const parseWifConfig: (base64: string, label: string) =>
|
|
9
|
+
export declare const parseWifConfig: (base64: string, label: string) => {
|
|
10
|
+
type: string;
|
|
11
|
+
audience: string;
|
|
12
|
+
subject_token_type: string;
|
|
13
|
+
token_url: string;
|
|
11
14
|
service_account_impersonation_url: string;
|
|
15
|
+
credential_source: Record<string, unknown> & {
|
|
16
|
+
environment_id: string;
|
|
17
|
+
};
|
|
12
18
|
};
|
|
13
19
|
export declare const impersonatedClient: ({ wifConfigBase64, label, lifetime, targetScopes, }: {
|
|
14
20
|
wifConfigBase64: string;
|
|
@@ -11,12 +11,53 @@ export const awsSecurityCredentialsSupplier = {
|
|
|
11
11
|
},
|
|
12
12
|
};
|
|
13
13
|
export const parseWifConfig = (base64, label) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const parsed = JSON.parse(Buffer.from(base64, 'base64').toString('utf8'));
|
|
15
|
+
if ('subjectTokenType' in parsed ||
|
|
16
|
+
'tokenUrl' in parsed ||
|
|
17
|
+
'serviceAccountImpersonationUrl' in parsed ||
|
|
18
|
+
'credentialSource' in parsed) {
|
|
19
|
+
throw new Error(`${label}: WIF config contains unsupported aliases`);
|
|
20
|
+
}
|
|
21
|
+
if (parsed.type !== 'external_account') {
|
|
22
|
+
throw new Error(`${label}: WIF config missing type`);
|
|
23
|
+
}
|
|
24
|
+
if (typeof parsed.audience !== 'string' || parsed.audience.length === 0) {
|
|
25
|
+
throw new Error(`${label}: WIF config missing audience`);
|
|
26
|
+
}
|
|
27
|
+
if (parsed.subject_token_type !== 'urn:ietf:params:aws:token-type:aws4_request') {
|
|
28
|
+
throw new Error(`${label}: WIF config missing subject_token_type`);
|
|
29
|
+
}
|
|
30
|
+
if (parsed.token_url !== 'https://sts.googleapis.com/v1/token') {
|
|
31
|
+
throw new Error(`${label}: WIF config missing token_url`);
|
|
32
|
+
}
|
|
33
|
+
if (typeof parsed.service_account_impersonation_url !== 'string') {
|
|
34
|
+
throw new Error(`${label}: WIF config missing service_account_impersonation_url`);
|
|
35
|
+
}
|
|
36
|
+
const prefix = 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/';
|
|
37
|
+
const suffix = ':generateAccessToken';
|
|
38
|
+
if (!parsed.service_account_impersonation_url.startsWith(prefix) ||
|
|
39
|
+
!parsed.service_account_impersonation_url.endsWith(suffix)) {
|
|
40
|
+
throw new Error(`${label}: WIF config missing service_account_impersonation_url`);
|
|
41
|
+
}
|
|
42
|
+
const serviceAccount = parsed.service_account_impersonation_url.slice(prefix.length, -suffix.length);
|
|
43
|
+
if (!/^\d{21}$/.test(serviceAccount) &&
|
|
44
|
+
!/^[a-z][a-z0-9-]{4,28}[a-z0-9]@[a-z][a-z0-9-]{4,28}[a-z0-9]\.iam\.gserviceaccount\.com$/.test(serviceAccount)) {
|
|
17
45
|
throw new Error(`${label}: WIF config missing service_account_impersonation_url`);
|
|
18
46
|
}
|
|
19
|
-
|
|
47
|
+
if (typeof parsed.credential_source !== 'object' ||
|
|
48
|
+
parsed.credential_source === null ||
|
|
49
|
+
!('environment_id' in parsed.credential_source) ||
|
|
50
|
+
parsed.credential_source.environment_id !== 'aws1') {
|
|
51
|
+
throw new Error(`${label}: WIF config missing credential_source.environment_id`);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
type: parsed.type,
|
|
55
|
+
audience: parsed.audience,
|
|
56
|
+
subject_token_type: parsed.subject_token_type,
|
|
57
|
+
token_url: parsed.token_url,
|
|
58
|
+
service_account_impersonation_url: parsed.service_account_impersonation_url,
|
|
59
|
+
credential_source: { environment_id: parsed.credential_source.environment_id },
|
|
60
|
+
};
|
|
20
61
|
};
|
|
21
62
|
export const impersonatedClient = async ({ wifConfigBase64, label, lifetime, targetScopes, }) => {
|
|
22
63
|
const { AwsClient, Impersonated } = await import('google-auth-library');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/federation/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/federation/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,10 @@ export declare namespace Auth {
|
|
|
11
11
|
readonly kind: 'auth-none';
|
|
12
12
|
readonly reason: Reason;
|
|
13
13
|
};
|
|
14
|
+
type Unimplemented<Reason extends string> = {
|
|
15
|
+
readonly kind: 'auth-unimplemented';
|
|
16
|
+
readonly reason: Reason;
|
|
17
|
+
};
|
|
14
18
|
}
|
|
15
19
|
export declare namespace Ropa {
|
|
16
20
|
type Activity<Key extends string> = {
|
|
@@ -22,7 +26,7 @@ export declare namespace Ropa {
|
|
|
22
26
|
readonly reason: Reason;
|
|
23
27
|
};
|
|
24
28
|
}
|
|
25
|
-
export type AuthDeclaration = Auth.Tier<string> | Auth.Upstream<string> | Auth.None<string>;
|
|
29
|
+
export type AuthDeclaration = Auth.Tier<string> | Auth.Upstream<string> | Auth.None<string> | Auth.Unimplemented<string>;
|
|
26
30
|
export type RopaDeclaration<Key extends string> = Ropa.Activity<Key> | Ropa.None<string>;
|
|
27
31
|
export type DeclarationRequired = {
|
|
28
32
|
readonly __declarationRequired: never;
|
|
@@ -18,7 +18,7 @@ export const mint = async (bucket) => {
|
|
|
18
18
|
if (!allowed) {
|
|
19
19
|
throwTooManyRequestsError('upload rate limit exceeded');
|
|
20
20
|
}
|
|
21
|
-
const token = Util.
|
|
21
|
+
const token = Util.createOTP(constants.UPLOAD_TOKEN_LENGTH, false);
|
|
22
22
|
await redis.set(tokenKey(token), bucket, UPLOAD_TOKEN_TTL_SEC);
|
|
23
23
|
return { token, url: `${defaultEnv.BASE_URL}/_uploads` };
|
|
24
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/uploads/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,8BAA8B,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EACL,yBAAyB,EACzB,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,eAAe,GAAG,EAAE,CAAA;AAC1B,MAAM,sBAAsB,GAAG,EAAE,CAAA;AACjC,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,CAAA;AAEnC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,eAAe,KAAK,EAAE,CAAA;AAE1D,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC;QACvD,GAAG,EAAE,oBAAoB,UAAU,CAAC,OAAO,EAAE;QAC7C,GAAG,EAAE,eAAe;QACpB,SAAS,EAAE,sBAAsB;KAClC,CAAC,CAAA;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,yBAAyB,CAAC,4BAA4B,CAAC,CAAA;IACzD,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/uploads/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ya-accelerators/web-backend-framework",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.104",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "YA Technologies OÜ",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"test:integration": "jest --testPathPatterns=integration"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@aws-sdk/client-s3": "^3.
|
|
50
|
+
"@aws-sdk/client-s3": "^3.1105.0",
|
|
51
51
|
"@aws-sdk/credential-provider-node": "^3.972.78",
|
|
52
52
|
"@prisma/adapter-mariadb": "^7.9.1",
|
|
53
53
|
"@prisma/extension-read-replicas": "^0.5.0",
|