@selvajs/platform 0.21.0-beta.2 → 1.0.0-beta.4
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 +10 -7
- package/dist/access/index.d.ts +1 -2
- package/dist/access/index.js +1 -2
- package/dist/access/rules.d.ts +11 -12
- package/dist/access/rules.js +27 -23
- package/dist/apiTokens/index.d.ts +2 -3
- package/dist/apiTokens/index.js +2 -3
- package/dist/apiTokens/interface.d.ts +0 -1
- package/dist/apiTokens/interface.js +0 -1
- package/dist/apiTokens/scope.d.ts +3 -2
- package/dist/apiTokens/scope.js +9 -5
- package/dist/apiTokens/types.d.ts +7 -2
- package/dist/apiTokens/types.js +10 -5
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/index.js +0 -1
- package/dist/auth/interface.d.ts +4 -23
- package/dist/auth/interface.js +0 -1
- package/dist/auth/types.d.ts +4 -2
- package/dist/auth/types.js +0 -1
- package/dist/bindings/index.d.ts +0 -1
- package/dist/bindings/index.js +0 -1
- package/dist/bindings/interface.d.ts +0 -1
- package/dist/bindings/interface.js +0 -1
- package/dist/computeServer/index.d.ts +1 -7
- package/dist/computeServer/index.js +2 -8
- package/dist/computeServer/interface.d.ts +9 -6
- package/dist/computeServer/interface.js +0 -1
- package/dist/computeServer/public.d.ts +6 -0
- package/dist/computeServer/public.js +2 -0
- package/dist/computeServer/secrets.d.ts +12 -6
- package/dist/computeServer/secrets.js +35 -15
- package/dist/computeServer/types.d.ts +5 -2
- package/dist/computeServer/types.js +4 -1
- package/dist/computeServer/utils.d.ts +17 -6
- package/dist/computeServer/utils.js +31 -21
- package/dist/config.d.ts +1 -2
- package/dist/config.js +0 -1
- package/dist/context.d.ts +12 -1
- package/dist/context.js +51 -2
- package/dist/data/index.d.ts +0 -1
- package/dist/data/index.js +0 -1
- package/dist/data/interface.d.ts +0 -1
- package/dist/data/interface.js +0 -1
- package/dist/definitions/index.d.ts +2 -3
- package/dist/definitions/index.js +2 -3
- package/dist/definitions/interface.d.ts +0 -1
- package/dist/definitions/interface.js +0 -1
- package/dist/definitions/paths.d.ts +0 -1
- package/dist/definitions/paths.js +1 -12
- package/dist/definitions/schemas.d.ts +2 -21
- package/dist/definitions/schemas.js +10 -19
- package/dist/definitions/types.d.ts +12 -4
- package/dist/definitions/types.js +1 -3
- package/dist/errors/interface.d.ts +1 -2
- package/dist/errors/interface.js +0 -1
- package/dist/errors.d.ts +8 -1
- package/dist/errors.js +11 -1
- package/dist/events/audit.d.ts +1 -2
- package/dist/events/audit.js +0 -1
- package/dist/events/index.d.ts +0 -1
- package/dist/events/index.js +0 -1
- package/dist/events/interface.d.ts +0 -1
- package/dist/events/interface.js +0 -1
- package/dist/index.d.ts +18 -61
- package/dist/index.js +18 -24
- package/dist/invites/index.d.ts +0 -1
- package/dist/invites/index.js +0 -1
- package/dist/invites/interface.d.ts +5 -6
- package/dist/invites/interface.js +0 -1
- package/dist/invites/types.d.ts +0 -1
- package/dist/invites/types.js +0 -1
- package/dist/logging/interface.d.ts +0 -1
- package/dist/logging/interface.js +0 -1
- package/dist/metrics/interface.d.ts +0 -1
- package/dist/metrics/interface.js +0 -1
- package/dist/notifications/index.d.ts +0 -1
- package/dist/notifications/index.js +0 -1
- package/dist/notifications/interface.d.ts +1 -3
- package/dist/notifications/interface.js +1 -3
- package/dist/notifications/types.d.ts +0 -1
- package/dist/notifications/types.js +0 -1
- package/dist/organizations/index.d.ts +2 -3
- package/dist/organizations/index.js +1 -2
- package/dist/organizations/interface.d.ts +3 -5
- package/dist/organizations/interface.js +0 -1
- package/dist/organizations/paths.d.ts +1 -6
- package/dist/organizations/paths.js +2 -20
- package/dist/organizations/schemas.d.ts +5 -7
- package/dist/organizations/schemas.js +20 -13
- package/dist/organizations/types.d.ts +0 -1
- package/dist/organizations/types.js +0 -1
- package/dist/pagination.d.ts +11 -3
- package/dist/pagination.js +15 -1
- package/dist/permissions/index.d.ts +2 -2
- package/dist/permissions/index.js +2 -2
- package/dist/permissions/interface.d.ts +4 -4
- package/dist/permissions/interface.js +0 -1
- package/dist/permissions/types.d.ts +0 -1
- package/dist/permissions/types.js +0 -1
- package/dist/platformProjects/index.d.ts +1 -3
- package/dist/platformProjects/index.js +1 -2
- package/dist/platformProjects/interface.d.ts +0 -1
- package/dist/platformProjects/interface.js +0 -1
- package/dist/platformProjects/schemas.d.ts +0 -1
- package/dist/platformProjects/schemas.js +0 -1
- package/dist/platformProjects/types.d.ts +3 -2
- package/dist/platformProjects/types.js +0 -1
- package/dist/projects/index.d.ts +0 -1
- package/dist/projects/index.js +0 -1
- package/dist/projects/interface.d.ts +0 -1
- package/dist/projects/interface.js +0 -1
- package/dist/projects/schemas.d.ts +0 -1
- package/dist/projects/schemas.js +0 -1
- package/dist/projects/types.d.ts +0 -1
- package/dist/projects/types.js +0 -1
- package/dist/shareLinks/index.d.ts +0 -1
- package/dist/shareLinks/index.js +0 -1
- package/dist/shareLinks/interface.d.ts +6 -3
- package/dist/shareLinks/interface.js +0 -1
- package/dist/shareLinks/schemas.d.ts +0 -1
- package/dist/shareLinks/schemas.js +4 -2
- package/dist/shareLinks/types.d.ts +0 -1
- package/dist/shareLinks/types.js +0 -1
- package/dist/solveCache/interface.d.ts +2 -3
- package/dist/solveCache/interface.js +0 -1
- package/dist/storage/assetClasses.d.ts +4 -8
- package/dist/storage/assetClasses.js +6 -21
- package/dist/storage/cacheBust.d.ts +0 -1
- package/dist/storage/cacheBust.js +5 -3
- package/dist/storage/image.d.ts +8 -5
- package/dist/storage/image.js +74 -12
- package/dist/storage/index.d.ts +2 -4
- package/dist/storage/index.js +2 -3
- package/dist/storage/interface.d.ts +11 -3
- package/dist/storage/interface.js +0 -1
- package/dist/storage/safeKey.d.ts +7 -0
- package/dist/storage/safeKey.js +12 -0
- package/dist/testing/index.d.ts +5 -2
- package/dist/testing/index.js +3 -2
- package/dist/testing/suites/apiTokenStoreSuite.d.ts +0 -1
- package/dist/testing/suites/apiTokenStoreSuite.js +0 -1
- package/dist/testing/suites/auditQuerySuite.d.ts +18 -0
- package/dist/testing/suites/auditQuerySuite.js +73 -0
- package/dist/testing/suites/authProviderSuite.d.ts +14 -3
- package/dist/testing/suites/authProviderSuite.js +57 -32
- package/dist/testing/suites/computeServerStoreSuite.d.ts +1 -2
- package/dist/testing/suites/computeServerStoreSuite.js +68 -4
- package/dist/testing/suites/definitionStoreSuite.d.ts +2 -1
- package/dist/testing/suites/definitionStoreSuite.js +48 -16
- package/dist/testing/suites/emailLinkAuthSuite.d.ts +2 -5
- package/dist/testing/suites/emailLinkAuthSuite.js +1 -9
- package/dist/testing/suites/eventSinkSuite.d.ts +0 -1
- package/dist/testing/suites/eventSinkSuite.js +9 -1
- package/dist/testing/suites/helpers.d.ts +5 -1
- package/dist/testing/suites/helpers.js +7 -1
- package/dist/testing/suites/inviteStoreSuite.d.ts +0 -1
- package/dist/testing/suites/inviteStoreSuite.js +17 -7
- package/dist/testing/suites/oauthAuthSuite.d.ts +18 -0
- package/dist/testing/suites/oauthAuthSuite.js +26 -0
- package/dist/testing/suites/orgStoreSuite.d.ts +5 -1
- package/dist/testing/suites/orgStoreSuite.js +26 -7
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts +0 -5
- package/dist/testing/suites/platformPermissionStoreSuite.js +12 -63
- package/dist/testing/suites/platformProjectGrantStoreSuite.d.ts +0 -1
- package/dist/testing/suites/platformProjectGrantStoreSuite.js +0 -5
- package/dist/testing/suites/projectStoreSuite.d.ts +5 -1
- package/dist/testing/suites/projectStoreSuite.js +6 -6
- package/dist/testing/suites/shareLinkStoreSuite.d.ts +2 -1
- package/dist/testing/suites/shareLinkStoreSuite.js +22 -25
- package/dist/testing/suites/solveMetricSinkSuite.d.ts +0 -1
- package/dist/testing/suites/solveMetricSinkSuite.js +2 -2
- package/dist/testing/suites/storageProviderSuite.d.ts +0 -1
- package/dist/testing/suites/storageProviderSuite.js +15 -10
- package/dist/testing/suites/userProfileStoreSuite.d.ts +1 -2
- package/dist/testing/suites/userProfileStoreSuite.js +42 -7
- package/dist/userProfile/index.d.ts +2 -2
- package/dist/userProfile/index.js +2 -2
- package/dist/userProfile/interface.d.ts +5 -6
- package/dist/userProfile/interface.js +0 -1
- package/dist/userProfile/types.d.ts +2 -1
- package/dist/userProfile/types.js +2 -1
- package/dist/utils/audit.d.ts +0 -1
- package/dist/utils/audit.js +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -1
- package/package.json +7 -6
- package/dist/access/index.d.ts.map +0 -1
- package/dist/access/index.js.map +0 -1
- package/dist/access/rules.d.ts.map +0 -1
- package/dist/access/rules.js.map +0 -1
- package/dist/apiTokens/index.d.ts.map +0 -1
- package/dist/apiTokens/index.js.map +0 -1
- package/dist/apiTokens/interface.d.ts.map +0 -1
- package/dist/apiTokens/interface.js.map +0 -1
- package/dist/apiTokens/scope.d.ts.map +0 -1
- package/dist/apiTokens/scope.js.map +0 -1
- package/dist/apiTokens/types.d.ts.map +0 -1
- package/dist/apiTokens/types.js.map +0 -1
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/interface.d.ts.map +0 -1
- package/dist/auth/interface.js.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/bindings/index.d.ts.map +0 -1
- package/dist/bindings/index.js.map +0 -1
- package/dist/bindings/interface.d.ts.map +0 -1
- package/dist/bindings/interface.js.map +0 -1
- package/dist/computeServer/index.d.ts.map +0 -1
- package/dist/computeServer/index.js.map +0 -1
- package/dist/computeServer/interface.d.ts.map +0 -1
- package/dist/computeServer/interface.js.map +0 -1
- package/dist/computeServer/secrets.d.ts.map +0 -1
- package/dist/computeServer/secrets.js.map +0 -1
- package/dist/computeServer/types.d.ts.map +0 -1
- package/dist/computeServer/types.js.map +0 -1
- package/dist/computeServer/utils.d.ts.map +0 -1
- package/dist/computeServer/utils.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js.map +0 -1
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/data/interface.d.ts.map +0 -1
- package/dist/data/interface.js.map +0 -1
- package/dist/definitions/index.d.ts.map +0 -1
- package/dist/definitions/index.js.map +0 -1
- package/dist/definitions/interface.d.ts.map +0 -1
- package/dist/definitions/interface.js.map +0 -1
- package/dist/definitions/paths.d.ts.map +0 -1
- package/dist/definitions/paths.js.map +0 -1
- package/dist/definitions/schemas.d.ts.map +0 -1
- package/dist/definitions/schemas.js.map +0 -1
- package/dist/definitions/types.d.ts.map +0 -1
- package/dist/definitions/types.js.map +0 -1
- package/dist/errors/interface.d.ts.map +0 -1
- package/dist/errors/interface.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/events/audit.d.ts.map +0 -1
- package/dist/events/audit.js.map +0 -1
- package/dist/events/index.d.ts.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/events/interface.d.ts.map +0 -1
- package/dist/events/interface.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invites/index.d.ts.map +0 -1
- package/dist/invites/index.js.map +0 -1
- package/dist/invites/interface.d.ts.map +0 -1
- package/dist/invites/interface.js.map +0 -1
- package/dist/invites/types.d.ts.map +0 -1
- package/dist/invites/types.js.map +0 -1
- package/dist/logging/interface.d.ts.map +0 -1
- package/dist/logging/interface.js.map +0 -1
- package/dist/metrics/interface.d.ts.map +0 -1
- package/dist/metrics/interface.js.map +0 -1
- package/dist/notifications/index.d.ts.map +0 -1
- package/dist/notifications/index.js.map +0 -1
- package/dist/notifications/interface.d.ts.map +0 -1
- package/dist/notifications/interface.js.map +0 -1
- package/dist/notifications/types.d.ts.map +0 -1
- package/dist/notifications/types.js.map +0 -1
- package/dist/organizations/index.d.ts.map +0 -1
- package/dist/organizations/index.js.map +0 -1
- package/dist/organizations/interface.d.ts.map +0 -1
- package/dist/organizations/interface.js.map +0 -1
- package/dist/organizations/paths.d.ts.map +0 -1
- package/dist/organizations/paths.js.map +0 -1
- package/dist/organizations/schemas.d.ts.map +0 -1
- package/dist/organizations/schemas.js.map +0 -1
- package/dist/organizations/types.d.ts.map +0 -1
- package/dist/organizations/types.js.map +0 -1
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js.map +0 -1
- package/dist/permissions/index.d.ts.map +0 -1
- package/dist/permissions/index.js.map +0 -1
- package/dist/permissions/interface.d.ts.map +0 -1
- package/dist/permissions/interface.js.map +0 -1
- package/dist/permissions/types.d.ts.map +0 -1
- package/dist/permissions/types.js.map +0 -1
- package/dist/platformProjects/index.d.ts.map +0 -1
- package/dist/platformProjects/index.js.map +0 -1
- package/dist/platformProjects/interface.d.ts.map +0 -1
- package/dist/platformProjects/interface.js.map +0 -1
- package/dist/platformProjects/schemas.d.ts.map +0 -1
- package/dist/platformProjects/schemas.js.map +0 -1
- package/dist/platformProjects/types.d.ts.map +0 -1
- package/dist/platformProjects/types.js.map +0 -1
- package/dist/projects/index.d.ts.map +0 -1
- package/dist/projects/index.js.map +0 -1
- package/dist/projects/interface.d.ts.map +0 -1
- package/dist/projects/interface.js.map +0 -1
- package/dist/projects/schemas.d.ts.map +0 -1
- package/dist/projects/schemas.js.map +0 -1
- package/dist/projects/types.d.ts.map +0 -1
- package/dist/projects/types.js.map +0 -1
- package/dist/shareLinks/index.d.ts.map +0 -1
- package/dist/shareLinks/index.js.map +0 -1
- package/dist/shareLinks/interface.d.ts.map +0 -1
- package/dist/shareLinks/interface.js.map +0 -1
- package/dist/shareLinks/schemas.d.ts.map +0 -1
- package/dist/shareLinks/schemas.js.map +0 -1
- package/dist/shareLinks/types.d.ts.map +0 -1
- package/dist/shareLinks/types.js.map +0 -1
- package/dist/solveCache/interface.d.ts.map +0 -1
- package/dist/solveCache/interface.js.map +0 -1
- package/dist/storage/assetClasses.d.ts.map +0 -1
- package/dist/storage/assetClasses.js.map +0 -1
- package/dist/storage/cacheBust.d.ts.map +0 -1
- package/dist/storage/cacheBust.js.map +0 -1
- package/dist/storage/image.d.ts.map +0 -1
- package/dist/storage/image.js.map +0 -1
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/interface.d.ts.map +0 -1
- package/dist/storage/interface.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing/suites/apiTokenStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/apiTokenStoreSuite.js.map +0 -1
- package/dist/testing/suites/authProviderSuite.d.ts.map +0 -1
- package/dist/testing/suites/authProviderSuite.js.map +0 -1
- package/dist/testing/suites/computeServerStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/computeServerStoreSuite.js.map +0 -1
- package/dist/testing/suites/definitionStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/definitionStoreSuite.js.map +0 -1
- package/dist/testing/suites/emailLinkAuthSuite.d.ts.map +0 -1
- package/dist/testing/suites/emailLinkAuthSuite.js.map +0 -1
- package/dist/testing/suites/eventSinkSuite.d.ts.map +0 -1
- package/dist/testing/suites/eventSinkSuite.js.map +0 -1
- package/dist/testing/suites/helpers.d.ts.map +0 -1
- package/dist/testing/suites/helpers.js.map +0 -1
- package/dist/testing/suites/inviteStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/inviteStoreSuite.js.map +0 -1
- package/dist/testing/suites/orgStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/orgStoreSuite.js.map +0 -1
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js.map +0 -1
- package/dist/testing/suites/platformProjectGrantStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/platformProjectGrantStoreSuite.js.map +0 -1
- package/dist/testing/suites/projectStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/projectStoreSuite.js.map +0 -1
- package/dist/testing/suites/shareLinkStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/shareLinkStoreSuite.js.map +0 -1
- package/dist/testing/suites/solveMetricSinkSuite.d.ts.map +0 -1
- package/dist/testing/suites/solveMetricSinkSuite.js.map +0 -1
- package/dist/testing/suites/storageProviderSuite.d.ts.map +0 -1
- package/dist/testing/suites/storageProviderSuite.js.map +0 -1
- package/dist/testing/suites/userProfileStoreSuite.d.ts.map +0 -1
- package/dist/testing/suites/userProfileStoreSuite.js.map +0 -1
- package/dist/userProfile/index.d.ts.map +0 -1
- package/dist/userProfile/index.js.map +0 -1
- package/dist/userProfile/interface.d.ts.map +0 -1
- package/dist/userProfile/interface.js.map +0 -1
- package/dist/userProfile/types.d.ts.map +0 -1
- package/dist/userProfile/types.js.map +0 -1
- package/dist/utils/audit.d.ts.map +0 -1
- package/dist/utils/audit.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { PlatformPermission } from './types.js';
|
|
2
|
-
export { PlatformPermissionSchema, ALL_PLATFORM_PERMISSIONS } from './types.js';
|
|
2
|
+
export { PlatformPermissionSchema, ALL_PLATFORM_PERMISSIONS, OPERATOR_PLATFORM_PERMISSIONS } from './types.js';
|
|
3
3
|
export type { IPlatformPermissionStore } from './interface.js';
|
|
4
|
-
|
|
4
|
+
export { assertCanManagePermissions, assertCanReadPermissions, assertCanReadPermissionsBatch } from '../context.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { PlatformPermissionSchema, ALL_PLATFORM_PERMISSIONS } from './types.js';
|
|
2
|
-
|
|
1
|
+
export { PlatformPermissionSchema, ALL_PLATFORM_PERMISSIONS, OPERATOR_PLATFORM_PERMISSIONS } from './types.js';
|
|
2
|
+
export { assertCanManagePermissions, assertCanReadPermissions, assertCanReadPermissionsBatch } from '../context.js';
|
|
@@ -27,7 +27,9 @@ export interface IPlatformPermissionStore {
|
|
|
27
27
|
set(ctx: RequestContext, userId: string, permissions: readonly PlatformPermission[]): Promise<UserManagementResult>;
|
|
28
28
|
/**
|
|
29
29
|
* True if at least one *enabled* user holds `instance_admin`. Adapters
|
|
30
|
-
* must exclude disabled users
|
|
30
|
+
* must exclude disabled users. One that can't see the disabled flag, like local,
|
|
31
|
+
* relies on the routes: disabling revokes `instance_admin` first, and a disabled
|
|
32
|
+
* user can't be granted it.
|
|
31
33
|
*/
|
|
32
34
|
hasInstanceAdmin(ctx: RequestContext): Promise<boolean>;
|
|
33
35
|
/**
|
|
@@ -45,8 +47,7 @@ export interface IPlatformPermissionStore {
|
|
|
45
47
|
* write: on a fresh single-tenant install with no
|
|
46
48
|
* `BOOTSTRAP_INSTANCE_ADMIN_EMAIL` configured, any signer is eligible, so
|
|
47
49
|
* two people signing in at the same moment both observe "no admin" and both
|
|
48
|
-
* become permanent platform admins.
|
|
49
|
-
* is what makes that true rather than aspirational.
|
|
50
|
+
* become permanent platform admins. This is what makes first signer win.
|
|
50
51
|
*
|
|
51
52
|
* Same shape as the sole-admin invariant (`set`), pointing the other way:
|
|
52
53
|
* that one refuses to drop the last admin, this one refuses to create a
|
|
@@ -54,4 +55,3 @@ export interface IPlatformPermissionStore {
|
|
|
54
55
|
*/
|
|
55
56
|
claimFirstInstanceAdmin(ctx: RequestContext, userId: string, permissions: readonly PlatformPermission[]): Promise<boolean>;
|
|
56
57
|
}
|
|
57
|
-
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -23,4 +23,3 @@ export declare const ALL_PLATFORM_PERMISSIONS: readonly PlatformPermission[];
|
|
|
23
23
|
* `manage_api_tokens` is granted to ordinary users, who have no business there.
|
|
24
24
|
*/
|
|
25
25
|
export declare const OPERATOR_PLATFORM_PERMISSIONS: readonly PlatformPermission[];
|
|
26
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -22,4 +22,3 @@ export const ALL_PLATFORM_PERMISSIONS = PlatformPermissionSchema.options;
|
|
|
22
22
|
* `manage_api_tokens` is granted to ordinary users, who have no business there.
|
|
23
23
|
*/
|
|
24
24
|
export const OPERATOR_PLATFORM_PERMISSIONS = ALL_PLATFORM_PERMISSIONS.filter((p) => p !== 'manage_api_tokens');
|
|
25
|
-
//# sourceMappingURL=types.js.map
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export type { PlatformProjectGrant
|
|
1
|
+
export type { PlatformProjectGrant } from './types.js';
|
|
2
2
|
export type { IPlatformProjectGrantStore } from './interface.js';
|
|
3
|
-
export { PlatformProjectGrantSchema, PlatformProjectGranteeTypeSchema } from './schemas.js';
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { PlatformProjectGranteeTypeSchema } from './schemas.js';
|
|
3
|
+
export type PlatformProjectGranteeType = z.infer<typeof PlatformProjectGranteeTypeSchema>;
|
|
2
4
|
/**
|
|
3
5
|
* Grants view-only or view+solve access to a `platform`-visibility project
|
|
4
6
|
* for an org or an individual user, without creating project membership rows.
|
|
@@ -16,4 +18,3 @@ export interface PlatformProjectGrant {
|
|
|
16
18
|
createdBy: string;
|
|
17
19
|
createdAt: string;
|
|
18
20
|
}
|
|
19
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/projects/index.d.ts
CHANGED
|
@@ -2,4 +2,3 @@ export type { Project, ProjectMember } from './types.js';
|
|
|
2
2
|
export type { IProjectStore } from './interface.js';
|
|
3
3
|
export type { ProjectVisibility, ProjectRole } from './schemas.js';
|
|
4
4
|
export { ProjectVisibilitySchema, ProjectRoleSchema, validateProjectFlags } from './schemas.js';
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/projects/index.js
CHANGED
|
@@ -38,4 +38,3 @@ export interface IProjectStore {
|
|
|
38
38
|
updateProjectMemberRole(ctx: RequestContext, projectId: string, userId: string, role: ProjectRole): Promise<void>;
|
|
39
39
|
removeProjectMember(ctx: RequestContext, projectId: string, userId: string): Promise<void>;
|
|
40
40
|
}
|
|
41
|
-
//# sourceMappingURL=interface.d.ts.map
|
package/dist/projects/schemas.js
CHANGED
package/dist/projects/types.d.ts
CHANGED
package/dist/projects/types.js
CHANGED
package/dist/shareLinks/index.js
CHANGED
|
@@ -6,7 +6,8 @@ import type { OrgShareLink, ShareLink } from './types.js';
|
|
|
6
6
|
* (definitionId, channel). The store sees only the HMAC hash; the raw token
|
|
7
7
|
* is generated and shown to the minter at the route layer.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* List and token reads treat a revoked or expired link as gone. `getById` does
|
|
10
|
+
* not, so a caller can tell a dead link from a missing one.
|
|
10
11
|
*/
|
|
11
12
|
export interface IShareLinkStore {
|
|
12
13
|
/** Caller has already hashed the raw token. */
|
|
@@ -29,7 +30,10 @@ export interface IShareLinkStore {
|
|
|
29
30
|
getById(ctx: RequestContext, id: string): Promise<ShareLink | null>;
|
|
30
31
|
/** Returns null when the link doesn't exist, is revoked, or its parent definition is soft-deleted. */
|
|
31
32
|
getByTokenHash(ctx: RequestContext, tokenHash: string): Promise<ShareLink | null>;
|
|
32
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Soft-delete (set `revokedAt`). Idempotent: emits once, and a repeat is a no-op.
|
|
35
|
+
* Throws `ProviderError` when the caller may not revoke it.
|
|
36
|
+
*/
|
|
33
37
|
revoke(ctx: RequestContext, id: string): Promise<void>;
|
|
34
38
|
/**
|
|
35
39
|
* Atomic check-and-increment; must be a single statement, since
|
|
@@ -38,4 +42,3 @@ export interface IShareLinkStore {
|
|
|
38
42
|
*/
|
|
39
43
|
tryIncrementSolveCount(ctx: RequestContext, id: string): Promise<number | null>;
|
|
40
44
|
}
|
|
41
|
-
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -8,8 +8,10 @@ export const CreateShareLinkInputSchema = z.object({
|
|
|
8
8
|
channel: DefinitionChannelSchema.default('live'),
|
|
9
9
|
name: z.string().max(128).optional(),
|
|
10
10
|
allowSolve: z.boolean().default(true),
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Null is the minter's deliberate "uncap" choice. Omitted stays undefined here:
|
|
13
|
+
* the mint handler applies `DEFAULT_SHARE_LINK_MAX_SOLVES`.
|
|
14
|
+
*/
|
|
12
15
|
maxSolves: z.number().int().min(1).nullable().optional(),
|
|
13
16
|
expiresAt: z.iso.datetime().nullable().optional()
|
|
14
17
|
});
|
|
15
|
-
//# sourceMappingURL=schemas.js.map
|
package/dist/shareLinks/types.js
CHANGED
|
@@ -6,8 +6,8 @@ import type { RequestContext } from '../context.js';
|
|
|
6
6
|
*
|
|
7
7
|
* Design contract:
|
|
8
8
|
*
|
|
9
|
-
* - **Async
|
|
10
|
-
*
|
|
9
|
+
* - **Async.** The in-memory backend returns promises too, so a network store
|
|
10
|
+
* (Redis) fits without any call site changing shape.
|
|
11
11
|
* - **Entries are opaque bytes** — the pre-gzipped response envelope plus a
|
|
12
12
|
* small metadata header. The backend never inspects them, so a hit stays
|
|
13
13
|
* near-CPU-free in either backend and there's no serialization drift between
|
|
@@ -81,4 +81,3 @@ export declare class NoopSolveResultCache implements ISolveResultCache {
|
|
|
81
81
|
get(_ctx: RequestContext, _key: SolveCacheKey): Promise<Uint8Array | null>;
|
|
82
82
|
set(_ctx: RequestContext, _key: SolveCacheKey, _bytes: Uint8Array, _opts: SolveCacheSetOptions): Promise<void>;
|
|
83
83
|
}
|
|
84
|
-
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
* entry in {@link ASSET_CLASSES} rather than a new route.
|
|
5
5
|
*
|
|
6
6
|
* - `public` — anyone, including logged-out visitors (branding: logo, favicon).
|
|
7
|
-
* - `org` — members of the owning org only; route resolves orgId from the path.
|
|
8
7
|
* - `project` — members of the owning project only; route resolves the
|
|
9
8
|
* definition guid to its project (cover images, per-definition blobs).
|
|
10
9
|
*/
|
|
11
|
-
export type AssetVisibility = 'public' | '
|
|
10
|
+
export type AssetVisibility = 'public' | 'project';
|
|
12
11
|
/**
|
|
13
12
|
* What scope id the route must authorize against. `none` for public assets
|
|
14
|
-
* (no scope to check); `
|
|
13
|
+
* (no scope to check); `project` carries the guid extracted from the path.
|
|
15
14
|
*/
|
|
16
|
-
export type AssetScope = 'none' | '
|
|
15
|
+
export type AssetScope = 'none' | 'project';
|
|
17
16
|
export interface AssetClass {
|
|
18
17
|
/** Stable identifier — for logging and tests, not user-facing. */
|
|
19
18
|
readonly id: string;
|
|
@@ -21,7 +20,7 @@ export interface AssetClass {
|
|
|
21
20
|
readonly scope: AssetScope;
|
|
22
21
|
/**
|
|
23
22
|
* Anchored matcher for this class's storage paths. Capture group 1 (when
|
|
24
|
-
* present) is the scope id
|
|
23
|
+
* present) is the scope id the route authorizes against.
|
|
25
24
|
*/
|
|
26
25
|
readonly pattern: RegExp;
|
|
27
26
|
}
|
|
@@ -46,6 +45,3 @@ export declare const ASSET_CLASSES: readonly AssetClass[];
|
|
|
46
45
|
* captures an id (e.g. `org-branding` captures orgId but is public).
|
|
47
46
|
*/
|
|
48
47
|
export declare function classifyAssetPath(storagePath: string): AssetMatch | null;
|
|
49
|
-
/** True when the path belongs to a `public` asset class (CDN-servable, no auth). */
|
|
50
|
-
export declare function isPublicAssetPath(storagePath: string): boolean;
|
|
51
|
-
//# sourceMappingURL=assetClasses.d.ts.map
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { ALL_ORG_ASSET_KINDS } from '../organizations/schemas.js';
|
|
2
|
-
import {
|
|
2
|
+
import { UUID_REGEX } from '../definitions/schemas.js';
|
|
3
|
+
import { SAFE_SEGMENT } from './safeKey.js';
|
|
3
4
|
// Built from the schema enum so a new branding kind extends this pattern automatically.
|
|
4
5
|
const BRANDING_KINDS = ALL_ORG_ASSET_KINDS.join('|');
|
|
5
|
-
|
|
6
|
-
// instead of silently 404ing legit covers.
|
|
7
|
-
const COVER_EXTS = COVER_IMAGE_EXTENSIONS.map((ext) => ext.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
|
|
8
|
-
// SAFE_SEGMENT mirrors the assertSafeKey alphabet in the path helpers
|
|
9
|
-
// (traversal/empty segments are rejected separately by hasUnsafeSegment);
|
|
10
|
-
// GUID is kept in sync with UUID_REGEX in definitions/schemas.ts.
|
|
11
|
-
const SAFE_SEGMENT = String.raw `[A-Za-z0-9._-]+`;
|
|
12
|
-
const GUID = String.raw `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`;
|
|
6
|
+
const GUID = UUID_REGEX.source.slice(1, -1);
|
|
13
7
|
/**
|
|
14
8
|
* The closed registry of servable asset classes. Patterns are mutually
|
|
15
9
|
* exclusive by prefix, order doesn't matter. Anything matching no class is
|
|
@@ -22,17 +16,13 @@ export const ASSET_CLASSES = [
|
|
|
22
16
|
scope: 'none',
|
|
23
17
|
pattern: new RegExp(String.raw `^orgs\/(${SAFE_SEGMENT})\/branding\/(?:${BRANDING_KINDS})\.webp$`)
|
|
24
18
|
},
|
|
25
|
-
{
|
|
26
|
-
id: 'org-private',
|
|
27
|
-
visibility: 'org',
|
|
28
|
-
scope: 'org',
|
|
29
|
-
pattern: new RegExp(String.raw `^orgs\/(${SAFE_SEGMENT})\/private\/${SAFE_SEGMENT}$`)
|
|
30
|
-
},
|
|
31
19
|
{
|
|
32
20
|
id: 'definition-cover',
|
|
33
21
|
visibility: 'project',
|
|
34
22
|
scope: 'project',
|
|
35
|
-
|
|
23
|
+
// `put` transcodes every cover and `definitionPaths.image` names it, so this is
|
|
24
|
+
// the only cover that can exist.
|
|
25
|
+
pattern: new RegExp(String.raw `^definitions\/(${GUID})\/cover\.webp$`, 'i')
|
|
36
26
|
}
|
|
37
27
|
];
|
|
38
28
|
/**
|
|
@@ -72,8 +62,3 @@ export function classifyAssetPath(storagePath) {
|
|
|
72
62
|
}
|
|
73
63
|
return null;
|
|
74
64
|
}
|
|
75
|
-
/** True when the path belongs to a `public` asset class (CDN-servable, no auth). */
|
|
76
|
-
export function isPublicAssetPath(storagePath) {
|
|
77
|
-
return classifyAssetPath(storagePath)?.class.visibility === 'public';
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=assetClasses.js.map
|
|
@@ -21,7 +21,9 @@ export function withCacheBust(url, token) {
|
|
|
21
21
|
const value = String(token).trim();
|
|
22
22
|
if (value === '')
|
|
23
23
|
return url;
|
|
24
|
-
const
|
|
25
|
-
|
|
24
|
+
const hash = url.indexOf('#');
|
|
25
|
+
const base = hash === -1 ? url : url.slice(0, hash);
|
|
26
|
+
const fragment = hash === -1 ? '' : url.slice(hash);
|
|
27
|
+
const sep = base.includes('?') ? '&' : '?';
|
|
28
|
+
return `${base}${sep}v=${encodeURIComponent(value)}${fragment}`;
|
|
26
29
|
}
|
|
27
|
-
//# sourceMappingURL=cacheBust.js.map
|
package/dist/storage/image.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared image-transcoding helper for `IStorageProvider` implementations.
|
|
3
|
-
* Normalizes uploads to WebP (
|
|
4
|
-
* bandwidth, and the viewer path stay predictable.
|
|
3
|
+
* Normalizes uploads to WebP (at most 1200px on either side, quality 85) so
|
|
4
|
+
* storage, bandwidth, and the viewer path stay predictable.
|
|
5
5
|
*
|
|
6
6
|
* `sharp` is a dynamic import, not a hard dependency of this package —
|
|
7
7
|
* providers that need transcoding install it themselves.
|
|
8
8
|
*/
|
|
9
9
|
export declare const IMAGE_MAX_WIDTH = 1200;
|
|
10
10
|
export declare const IMAGE_WEBP_QUALITY = 85;
|
|
11
|
+
export declare const MAX_CONCURRENT_TRANSCODES = 2;
|
|
11
12
|
export interface TranscodeResult {
|
|
12
13
|
data: Uint8Array;
|
|
13
14
|
contentType: string;
|
|
14
15
|
/** Possibly-rewritten path (non-webp inputs become `.webp`). */
|
|
15
16
|
path: string;
|
|
16
17
|
}
|
|
17
|
-
/** True if the input
|
|
18
|
+
/** True if the input is an image to process. The content type decides, unless it says nothing. */
|
|
18
19
|
export declare function isImageUpload(contentType: string | undefined, storagePath: string): boolean;
|
|
19
20
|
/**
|
|
20
21
|
* Rewrites a path's extension to `.webp`; unchanged for non-image extensions.
|
|
@@ -26,7 +27,9 @@ export declare function toWebpPath(storagePath: string): string;
|
|
|
26
27
|
* Transcodes images to WebP; passes non-images through unchanged, so
|
|
27
28
|
* providers can call this unconditionally before `put`.
|
|
28
29
|
*
|
|
29
|
-
* Throws
|
|
30
|
+
* Throws `ProviderError(422)` for bytes it won't process, and a plain error if
|
|
31
|
+
* `sharp` isn't installed, which is a config problem rather than a bad upload.
|
|
30
32
|
*/
|
|
31
33
|
export declare function transcodeImageIfNeeded(data: Uint8Array, contentType: string | undefined, storagePath: string): Promise<TranscodeResult>;
|
|
32
|
-
|
|
34
|
+
/** Runs `fn` when a slot is free. A finishing transcode hands its slot straight to the next. */
|
|
35
|
+
export declare function withTranscodeSlot<T>(fn: () => Promise<T>): Promise<T>;
|
package/dist/storage/image.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared image-transcoding helper for `IStorageProvider` implementations.
|
|
3
|
-
* Normalizes uploads to WebP (
|
|
4
|
-
* bandwidth, and the viewer path stay predictable.
|
|
3
|
+
* Normalizes uploads to WebP (at most 1200px on either side, quality 85) so
|
|
4
|
+
* storage, bandwidth, and the viewer path stay predictable.
|
|
5
5
|
*
|
|
6
6
|
* `sharp` is a dynamic import, not a hard dependency of this package —
|
|
7
7
|
* providers that need transcoding install it themselves.
|
|
8
8
|
*/
|
|
9
|
+
import { ProviderError } from '../errors.js';
|
|
9
10
|
export const IMAGE_MAX_WIDTH = 1200;
|
|
10
11
|
export const IMAGE_WEBP_QUALITY = 85;
|
|
11
|
-
|
|
12
|
+
// A small upload can decode to gigabytes or burn seconds of CPU: the size cap on
|
|
13
|
+
// the request says nothing about either. 60 MP covers a phone camera's full frame.
|
|
14
|
+
const MAX_INPUT_PIXELS = 60_000_000;
|
|
15
|
+
const TRANSCODE_TIMEOUT_SECONDS = 10;
|
|
16
|
+
export const MAX_CONCURRENT_TRANSCODES = 2;
|
|
17
|
+
// What `metadata()` found in the bytes, whatever the client declared.
|
|
18
|
+
const ALLOWED_FORMATS = new Set(['jpeg', 'png', 'webp', 'gif', 'tiff', 'svg']);
|
|
19
|
+
/** True if the input is an image to process. The content type decides, unless it says nothing. */
|
|
12
20
|
export function isImageUpload(contentType, storagePath) {
|
|
13
|
-
if (contentType
|
|
14
|
-
return
|
|
21
|
+
if (contentType && contentType !== 'application/octet-stream') {
|
|
22
|
+
return contentType.startsWith('image/');
|
|
23
|
+
}
|
|
15
24
|
return /\.(webp|png|jpe?g|gif|bmp|tif?f|svg)$/i.test(storagePath);
|
|
16
25
|
}
|
|
17
26
|
/**
|
|
@@ -26,29 +35,83 @@ export function toWebpPath(storagePath) {
|
|
|
26
35
|
* Transcodes images to WebP; passes non-images through unchanged, so
|
|
27
36
|
* providers can call this unconditionally before `put`.
|
|
28
37
|
*
|
|
29
|
-
* Throws
|
|
38
|
+
* Throws `ProviderError(422)` for bytes it won't process, and a plain error if
|
|
39
|
+
* `sharp` isn't installed, which is a config problem rather than a bad upload.
|
|
30
40
|
*/
|
|
31
41
|
export async function transcodeImageIfNeeded(data, contentType, storagePath) {
|
|
32
42
|
if (!isImageUpload(contentType, storagePath)) {
|
|
33
43
|
return { data, contentType: contentType ?? 'application/octet-stream', path: storagePath };
|
|
34
44
|
}
|
|
35
45
|
const sharp = await loadSharp();
|
|
36
|
-
const compressed = await sharp
|
|
37
|
-
.resize({ width: IMAGE_MAX_WIDTH, withoutEnlargement: true })
|
|
38
|
-
.webp({ quality: IMAGE_WEBP_QUALITY })
|
|
39
|
-
.toBuffer();
|
|
46
|
+
const compressed = await withTranscodeSlot(() => rasterize(sharp, Buffer.from(data), contentType, storagePath));
|
|
40
47
|
return {
|
|
41
48
|
data: new Uint8Array(compressed),
|
|
42
49
|
contentType: 'image/webp',
|
|
43
50
|
path: toWebpPath(storagePath)
|
|
44
51
|
};
|
|
45
52
|
}
|
|
53
|
+
async function rasterize(sharp, input, contentType, storagePath) {
|
|
54
|
+
try {
|
|
55
|
+
// Unlimited here: this only reads the header, and sharp's own limit would hide
|
|
56
|
+
// the reason from the check below.
|
|
57
|
+
const header = sharp(input, { limitInputPixels: false });
|
|
58
|
+
const { format, width = 0, height = 0 } = await header.metadata();
|
|
59
|
+
// SVG is the expensive format, so it has to be asked for: a route that only
|
|
60
|
+
// checks the declared type must not let one in as a PNG.
|
|
61
|
+
const declaredSvg = contentType === 'image/svg+xml' || /\.svg$/i.test(storagePath);
|
|
62
|
+
if (!ALLOWED_FORMATS.has(format) || (format === 'svg' && !declaredSvg)) {
|
|
63
|
+
throw new ProviderError(`Unsupported image format: ${format}`, 422);
|
|
64
|
+
}
|
|
65
|
+
if (width * height > MAX_INPUT_PIXELS) {
|
|
66
|
+
throw new ProviderError('Image has too many pixels', 422);
|
|
67
|
+
}
|
|
68
|
+
return await sharp(input, { limitInputPixels: MAX_INPUT_PIXELS })
|
|
69
|
+
.autoOrient()
|
|
70
|
+
.resize({
|
|
71
|
+
width: IMAGE_MAX_WIDTH,
|
|
72
|
+
height: IMAGE_MAX_WIDTH,
|
|
73
|
+
fit: 'inside',
|
|
74
|
+
withoutEnlargement: true
|
|
75
|
+
})
|
|
76
|
+
.webp({ quality: IMAGE_WEBP_QUALITY })
|
|
77
|
+
.timeout({ seconds: TRANSCODE_TIMEOUT_SECONDS })
|
|
78
|
+
.toBuffer();
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
if (err instanceof ProviderError)
|
|
82
|
+
throw err;
|
|
83
|
+
throw new ProviderError('The image could not be read', 422);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
let activeTranscodes = 0;
|
|
87
|
+
const waitingTranscodes = [];
|
|
88
|
+
/** Runs `fn` when a slot is free. A finishing transcode hands its slot straight to the next. */
|
|
89
|
+
export async function withTranscodeSlot(fn) {
|
|
90
|
+
if (activeTranscodes < MAX_CONCURRENT_TRANSCODES) {
|
|
91
|
+
activeTranscodes += 1;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
await new Promise((resolve) => waitingTranscodes.push(resolve));
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
return await fn();
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
const next = waitingTranscodes.shift();
|
|
101
|
+
if (next)
|
|
102
|
+
next();
|
|
103
|
+
else
|
|
104
|
+
activeTranscodes -= 1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Not a literal: a browser build of the root barrel would try to resolve it.
|
|
108
|
+
const SHARP_MODULE = 'sharp';
|
|
46
109
|
let cachedSharp = null;
|
|
47
110
|
async function loadSharp() {
|
|
48
111
|
if (cachedSharp)
|
|
49
112
|
return cachedSharp;
|
|
50
113
|
try {
|
|
51
|
-
const mod = (await import(
|
|
114
|
+
const mod = (await import(/* @vite-ignore */ SHARP_MODULE));
|
|
52
115
|
cachedSharp = mod.default ?? mod;
|
|
53
116
|
return cachedSharp;
|
|
54
117
|
}
|
|
@@ -56,4 +119,3 @@ async function loadSharp() {
|
|
|
56
119
|
throw new Error('Image transcoding requires `sharp` to be installed. Add it as a dependency in your provider package.', { cause: err });
|
|
57
120
|
}
|
|
58
121
|
}
|
|
59
|
-
//# sourceMappingURL=image.js.map
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export type { IStorageProvider } from './interface.js';
|
|
2
|
-
export {
|
|
2
|
+
export { transcodeImageIfNeeded } from './image.js';
|
|
3
3
|
export type { TranscodeResult } from './image.js';
|
|
4
|
-
export { ASSET_CLASSES, classifyAssetPath
|
|
5
|
-
export type { AssetVisibility, AssetScope, AssetClass, AssetMatch } from './assetClasses.js';
|
|
4
|
+
export { ASSET_CLASSES, classifyAssetPath } from './assetClasses.js';
|
|
6
5
|
export { withCacheBust } from './cacheBust.js';
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/storage/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { ASSET_CLASSES, classifyAssetPath
|
|
1
|
+
export { transcodeImageIfNeeded } from './image.js';
|
|
2
|
+
export { ASSET_CLASSES, classifyAssetPath } from './assetClasses.js';
|
|
3
3
|
export { withCacheBust } from './cacheBust.js';
|
|
4
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -10,10 +10,19 @@
|
|
|
10
10
|
export interface IStorageProvider {
|
|
11
11
|
/** Returns null if the path does not exist. */
|
|
12
12
|
get(path: string): Promise<Uint8Array | null>;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Stores the bytes, replacing what is there, and returns the path they landed
|
|
15
|
+
* at. Images go through `transcodeImageIfNeeded` first: they are stored as WebP
|
|
16
|
+
* and a `.png` or similar path becomes `.webp`, so read back with the returned
|
|
17
|
+
* path. Throws `ProviderError(422)` for an image the transcoder refuses.
|
|
18
|
+
*/
|
|
19
|
+
put(path: string, data: Uint8Array, contentType?: string): Promise<string>;
|
|
14
20
|
/** No-op if the path does not exist. */
|
|
15
21
|
delete(path: string): Promise<void>;
|
|
16
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Delete every file under the directory `prefix`, so `a/b` does not reach
|
|
24
|
+
* `a/bc`. Throws on an empty prefix or `/`, which would name the whole store.
|
|
25
|
+
*/
|
|
17
26
|
deletePrefix(prefix: string): Promise<void>;
|
|
18
27
|
/**
|
|
19
28
|
* Public URL for a stored file. Local: a relative API path; S3/CDN: a
|
|
@@ -21,4 +30,3 @@ export interface IStorageProvider {
|
|
|
21
30
|
*/
|
|
22
31
|
getPublicUrl(path: string): string;
|
|
23
32
|
}
|
|
24
|
-
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Alphabet of one storage path segment, as regex source. Covers GUIDs and sanitized refs. */
|
|
2
|
+
export declare const SAFE_SEGMENT: string;
|
|
3
|
+
/**
|
|
4
|
+
* Blocks traversal, separators, NUL and empty segments, so a malicious id can't
|
|
5
|
+
* escape its prefix. The alphabet admits `.` and `..`, so those need their own check.
|
|
6
|
+
*/
|
|
7
|
+
export declare function assertSafeKey(value: string, label: string): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Alphabet of one storage path segment, as regex source. Covers GUIDs and sanitized refs. */
|
|
2
|
+
export const SAFE_SEGMENT = String.raw `[A-Za-z0-9._-]+`;
|
|
3
|
+
const SAFE_SEGMENT_ONLY = new RegExp(`^${SAFE_SEGMENT}$`);
|
|
4
|
+
/**
|
|
5
|
+
* Blocks traversal, separators, NUL and empty segments, so a malicious id can't
|
|
6
|
+
* escape its prefix. The alphabet admits `.` and `..`, so those need their own check.
|
|
7
|
+
*/
|
|
8
|
+
export function assertSafeKey(value, label) {
|
|
9
|
+
if (!value || !SAFE_SEGMENT_ONLY.test(value) || value === '.' || value === '..') {
|
|
10
|
+
throw new Error(`Unsafe ${label}: ${JSON.stringify(value)}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export { runAuthProviderConformance } from './suites/authProviderSuite.js';
|
|
1
|
+
export { runAuthCoreConformance, runAuthProviderConformance, runPasswordAuthConformance } from './suites/authProviderSuite.js';
|
|
2
2
|
export type { AuthProviderConformanceOptions } from './suites/authProviderSuite.js';
|
|
3
|
+
export { runOAuthAuthConformance } from './suites/oauthAuthSuite.js';
|
|
4
|
+
export type { OAuthAuthConformanceOptions } from './suites/oauthAuthSuite.js';
|
|
5
|
+
export { runAuditQueryConformance } from './suites/auditQuerySuite.js';
|
|
6
|
+
export type { AuditQueryConformanceOptions } from './suites/auditQuerySuite.js';
|
|
3
7
|
export { runEmailLinkAuthConformance } from './suites/emailLinkAuthSuite.js';
|
|
4
8
|
export type { EmailLinkAuthConformanceOptions } from './suites/emailLinkAuthSuite.js';
|
|
5
9
|
export { runDefinitionStoreConformance } from './suites/definitionStoreSuite.js';
|
|
@@ -28,4 +32,3 @@ export { runPlatformProjectGrantStoreConformance } from './suites/platformProjec
|
|
|
28
32
|
export type { PlatformProjectGrantStoreConformanceOptions } from './suites/platformProjectGrantStoreSuite.js';
|
|
29
33
|
export { runApiTokenStoreConformance } from './suites/apiTokenStoreSuite.js';
|
|
30
34
|
export type { ApiTokenStoreConformanceOptions, ApiTokenTestScope } from './suites/apiTokenStoreSuite.js';
|
|
31
|
-
//# sourceMappingURL=index.d.ts.map
|