@open-mercato/shared 0.4.2-canary-c02407ff85
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/build.mjs +101 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +7 -0
- package/dist/lib/api/crud.js +47 -0
- package/dist/lib/api/crud.js.map +7 -0
- package/dist/lib/api/scoped.js +140 -0
- package/dist/lib/api/scoped.js.map +7 -0
- package/dist/lib/auth/jwt.js +34 -0
- package/dist/lib/auth/jwt.js.map +7 -0
- package/dist/lib/auth/server.js +157 -0
- package/dist/lib/auth/server.js.map +7 -0
- package/dist/lib/boolean.js +22 -0
- package/dist/lib/boolean.js.map +7 -0
- package/dist/lib/bootstrap/appResolver.js +43 -0
- package/dist/lib/bootstrap/appResolver.js.map +7 -0
- package/dist/lib/bootstrap/dynamicLoader.js +108 -0
- package/dist/lib/bootstrap/dynamicLoader.js.map +7 -0
- package/dist/lib/bootstrap/factory.js +59 -0
- package/dist/lib/bootstrap/factory.js.map +7 -0
- package/dist/lib/bootstrap/index.js +11 -0
- package/dist/lib/bootstrap/index.js.map +7 -0
- package/dist/lib/bootstrap/types.js +1 -0
- package/dist/lib/bootstrap/types.js.map +7 -0
- package/dist/lib/cache/segments.js +36 -0
- package/dist/lib/cache/segments.js.map +7 -0
- package/dist/lib/cli/progress.js +46 -0
- package/dist/lib/cli/progress.js.map +7 -0
- package/dist/lib/commands/command-bus.js +285 -0
- package/dist/lib/commands/command-bus.js.map +7 -0
- package/dist/lib/commands/customFieldSnapshots.js +66 -0
- package/dist/lib/commands/customFieldSnapshots.js.map +7 -0
- package/dist/lib/commands/helpers.js +98 -0
- package/dist/lib/commands/helpers.js.map +7 -0
- package/dist/lib/commands/index.js +8 -0
- package/dist/lib/commands/index.js.map +7 -0
- package/dist/lib/commands/operationMetadata.js +32 -0
- package/dist/lib/commands/operationMetadata.js.map +7 -0
- package/dist/lib/commands/registry.js +43 -0
- package/dist/lib/commands/registry.js.map +7 -0
- package/dist/lib/commands/scope.js +44 -0
- package/dist/lib/commands/scope.js.map +7 -0
- package/dist/lib/commands/types.js +8 -0
- package/dist/lib/commands/types.js.map +7 -0
- package/dist/lib/crud/cache-stats.js +98 -0
- package/dist/lib/crud/cache-stats.js.map +7 -0
- package/dist/lib/crud/cache.js +175 -0
- package/dist/lib/crud/cache.js.map +7 -0
- package/dist/lib/crud/custom-fields-client.js +52 -0
- package/dist/lib/crud/custom-fields-client.js.map +7 -0
- package/dist/lib/crud/custom-fields.js +467 -0
- package/dist/lib/crud/custom-fields.js.map +7 -0
- package/dist/lib/crud/errors.js +24 -0
- package/dist/lib/crud/errors.js.map +7 -0
- package/dist/lib/crud/exporters.js +154 -0
- package/dist/lib/crud/exporters.js.map +7 -0
- package/dist/lib/crud/factory.js +1311 -0
- package/dist/lib/crud/factory.js.map +7 -0
- package/dist/lib/crud/types.js +1 -0
- package/dist/lib/crud/types.js.map +7 -0
- package/dist/lib/custom-fields/normalize.js +36 -0
- package/dist/lib/custom-fields/normalize.js.map +7 -0
- package/dist/lib/data/engine.js +396 -0
- package/dist/lib/data/engine.js.map +7 -0
- package/dist/lib/db/escapeLikePattern.js +5 -0
- package/dist/lib/db/escapeLikePattern.js.map +7 -0
- package/dist/lib/db/mikro.js +82 -0
- package/dist/lib/db/mikro.js.map +7 -0
- package/dist/lib/di/container.js +94 -0
- package/dist/lib/di/container.js.map +7 -0
- package/dist/lib/email/send.js +12 -0
- package/dist/lib/email/send.js.map +7 -0
- package/dist/lib/encryption/aes.js +58 -0
- package/dist/lib/encryption/aes.js.map +7 -0
- package/dist/lib/encryption/customFieldValues.js +49 -0
- package/dist/lib/encryption/customFieldValues.js.map +7 -0
- package/dist/lib/encryption/entityFields.js +26 -0
- package/dist/lib/encryption/entityFields.js.map +7 -0
- package/dist/lib/encryption/entityIds.js +80 -0
- package/dist/lib/encryption/entityIds.js.map +7 -0
- package/dist/lib/encryption/find.js +45 -0
- package/dist/lib/encryption/find.js.map +7 -0
- package/dist/lib/encryption/indexDoc.js +69 -0
- package/dist/lib/encryption/indexDoc.js.map +7 -0
- package/dist/lib/encryption/kms.js +282 -0
- package/dist/lib/encryption/kms.js.map +7 -0
- package/dist/lib/encryption/subscriber.js +330 -0
- package/dist/lib/encryption/subscriber.js.map +7 -0
- package/dist/lib/encryption/tenantDataEncryptionService.js +252 -0
- package/dist/lib/encryption/tenantDataEncryptionService.js.map +7 -0
- package/dist/lib/encryption/toggles.js +18 -0
- package/dist/lib/encryption/toggles.js.map +7 -0
- package/dist/lib/entities/naming.js +9 -0
- package/dist/lib/entities/naming.js.map +7 -0
- package/dist/lib/entities/system-entities.js +43 -0
- package/dist/lib/entities/system-entities.js.map +7 -0
- package/dist/lib/frontend/organizationEvents.js +41 -0
- package/dist/lib/frontend/organizationEvents.js.map +7 -0
- package/dist/lib/frontend/useOrganizationScope.js +32 -0
- package/dist/lib/frontend/useOrganizationScope.js.map +7 -0
- package/dist/lib/hotkeys/index.js +128 -0
- package/dist/lib/hotkeys/index.js.map +7 -0
- package/dist/lib/i18n/app-dictionaries.js +17 -0
- package/dist/lib/i18n/app-dictionaries.js.map +7 -0
- package/dist/lib/i18n/config.js +7 -0
- package/dist/lib/i18n/config.js.map +7 -0
- package/dist/lib/i18n/context.js +50 -0
- package/dist/lib/i18n/context.js.map +7 -0
- package/dist/lib/i18n/server.js +68 -0
- package/dist/lib/i18n/server.js.map +7 -0
- package/dist/lib/i18n/translate.js +45 -0
- package/dist/lib/i18n/translate.js.map +7 -0
- package/dist/lib/indexers/error-log.js +82 -0
- package/dist/lib/indexers/error-log.js.map +7 -0
- package/dist/lib/indexers/status-log.js +80 -0
- package/dist/lib/indexers/status-log.js.map +7 -0
- package/dist/lib/lib/auth/jwt.js +34 -0
- package/dist/lib/lib/auth/jwt.js.map +7 -0
- package/dist/lib/lib/auth/server.js +77 -0
- package/dist/lib/lib/auth/server.js.map +7 -0
- package/dist/lib/lib/email/send.js +12 -0
- package/dist/lib/lib/email/send.js.map +7 -0
- package/dist/lib/lib/i18n/config.js +7 -0
- package/dist/lib/lib/i18n/config.js.map +7 -0
- package/dist/lib/lib/i18n/context.js +31 -0
- package/dist/lib/lib/i18n/context.js.map +7 -0
- package/dist/lib/lib/utils.js +9 -0
- package/dist/lib/lib/utils.js.map +7 -0
- package/dist/lib/location/countries.js +68 -0
- package/dist/lib/location/countries.js.map +7 -0
- package/dist/lib/modules/index.js +6 -0
- package/dist/lib/modules/index.js.map +7 -0
- package/dist/lib/modules/registry.js +18 -0
- package/dist/lib/modules/registry.js.map +7 -0
- package/dist/lib/openapi/crud.js +137 -0
- package/dist/lib/openapi/crud.js.map +7 -0
- package/dist/lib/openapi/generator.js +1131 -0
- package/dist/lib/openapi/generator.js.map +7 -0
- package/dist/lib/openapi/index.js +10 -0
- package/dist/lib/openapi/index.js.map +7 -0
- package/dist/lib/openapi/sanitize.js +110 -0
- package/dist/lib/openapi/sanitize.js.map +7 -0
- package/dist/lib/openapi/types.js +1 -0
- package/dist/lib/openapi/types.js.map +7 -0
- package/dist/lib/profiler/index.js +258 -0
- package/dist/lib/profiler/index.js.map +7 -0
- package/dist/lib/query/engine.js +729 -0
- package/dist/lib/query/engine.js.map +7 -0
- package/dist/lib/query/join-utils.js +195 -0
- package/dist/lib/query/join-utils.js.map +7 -0
- package/dist/lib/query/types.js +9 -0
- package/dist/lib/query/types.js.map +7 -0
- package/dist/lib/search/config.js +32 -0
- package/dist/lib/search/config.js.map +7 -0
- package/dist/lib/search/tokenize.js +34 -0
- package/dist/lib/search/tokenize.js.map +7 -0
- package/dist/lib/slugify.js +24 -0
- package/dist/lib/slugify.js.map +7 -0
- package/dist/lib/testing/bootstrap.js +51 -0
- package/dist/lib/testing/bootstrap.js.map +7 -0
- package/dist/lib/testing/index.js +17 -0
- package/dist/lib/testing/index.js.map +7 -0
- package/dist/lib/testing/renderWithProviders.js +15 -0
- package/dist/lib/testing/renderWithProviders.js.map +7 -0
- package/dist/lib/url.js +12 -0
- package/dist/lib/url.js.map +7 -0
- package/dist/lib/utils.js +13 -0
- package/dist/lib/utils.js.map +7 -0
- package/dist/lib/version.js +7 -0
- package/dist/lib/version.js.map +7 -0
- package/dist/modules/dashboard/widgets.js +1 -0
- package/dist/modules/dashboard/widgets.js.map +7 -0
- package/dist/modules/dsl.js +30 -0
- package/dist/modules/dsl.js.map +7 -0
- package/dist/modules/entities/kinds.js +22 -0
- package/dist/modules/entities/kinds.js.map +7 -0
- package/dist/modules/entities/options.js +26 -0
- package/dist/modules/entities/options.js.map +7 -0
- package/dist/modules/entities/validation.js +102 -0
- package/dist/modules/entities/validation.js.map +7 -0
- package/dist/modules/entities/validators.js +88 -0
- package/dist/modules/entities/validators.js.map +7 -0
- package/dist/modules/entities.js +1 -0
- package/dist/modules/entities.js.map +7 -0
- package/dist/modules/navigation/sidebarPreferences.js +50 -0
- package/dist/modules/navigation/sidebarPreferences.js.map +7 -0
- package/dist/modules/perspectives/types.js +1 -0
- package/dist/modules/perspectives/types.js.map +7 -0
- package/dist/modules/registry.js +96 -0
- package/dist/modules/registry.js.map +7 -0
- package/dist/modules/search.js +15 -0
- package/dist/modules/search.js.map +7 -0
- package/dist/modules/vector.js +1 -0
- package/dist/modules/vector.js.map +7 -0
- package/dist/modules/widgets/injection-loader.js +180 -0
- package/dist/modules/widgets/injection-loader.js.map +7 -0
- package/dist/modules/widgets/injection.js +1 -0
- package/dist/modules/widgets/injection.js.map +7 -0
- package/dist/security/features.js +23 -0
- package/dist/security/features.js.map +7 -0
- package/dist/types/pg.d.js +1 -0
- package/dist/types/pg.d.js.map +7 -0
- package/dist/types/react-email.d.js +1 -0
- package/dist/types/react-email.d.js.map +7 -0
- package/dist/types/resend.d.js +1 -0
- package/dist/types/resend.d.js.map +7 -0
- package/jest.config.cjs +22 -0
- package/package.json +88 -0
- package/src/index.ts +0 -0
- package/src/lib/api/__tests__/scoped.test.ts +38 -0
- package/src/lib/api/crud.ts +59 -0
- package/src/lib/api/scoped.ts +239 -0
- package/src/lib/auth/jwt.ts +39 -0
- package/src/lib/auth/server.ts +199 -0
- package/src/lib/boolean.ts +17 -0
- package/src/lib/bootstrap/appResolver.ts +85 -0
- package/src/lib/bootstrap/dynamicLoader.ts +177 -0
- package/src/lib/bootstrap/factory.ts +108 -0
- package/src/lib/bootstrap/index.ts +23 -0
- package/src/lib/bootstrap/types.ts +31 -0
- package/src/lib/cache/segments.ts +56 -0
- package/src/lib/cli/progress.ts +55 -0
- package/src/lib/commands/__tests__/command-bus.test.ts +84 -0
- package/src/lib/commands/__tests__/helpers.test.ts +42 -0
- package/src/lib/commands/command-bus.ts +349 -0
- package/src/lib/commands/customFieldSnapshots.ts +86 -0
- package/src/lib/commands/helpers.ts +143 -0
- package/src/lib/commands/index.ts +4 -0
- package/src/lib/commands/operationMetadata.ts +40 -0
- package/src/lib/commands/registry.ts +46 -0
- package/src/lib/commands/scope.ts +59 -0
- package/src/lib/commands/types.ts +63 -0
- package/src/lib/crud/__tests__/crud-factory.test.ts +333 -0
- package/src/lib/crud/__tests__/custom-fields.test.ts +150 -0
- package/src/lib/crud/cache-stats.ts +127 -0
- package/src/lib/crud/cache.ts +205 -0
- package/src/lib/crud/custom-fields-client.ts +54 -0
- package/src/lib/crud/custom-fields.ts +607 -0
- package/src/lib/crud/errors.ts +23 -0
- package/src/lib/crud/exporters.ts +188 -0
- package/src/lib/crud/factory.ts +1622 -0
- package/src/lib/crud/types.ts +29 -0
- package/src/lib/custom-fields/normalize.ts +45 -0
- package/src/lib/data/engine.ts +562 -0
- package/src/lib/db/escapeLikePattern.ts +2 -0
- package/src/lib/db/mikro.ts +100 -0
- package/src/lib/di/container.ts +105 -0
- package/src/lib/email/send.ts +18 -0
- package/src/lib/encryption/__tests__/customFieldValues.test.ts +63 -0
- package/src/lib/encryption/__tests__/indexDoc.test.ts +115 -0
- package/src/lib/encryption/aes.ts +64 -0
- package/src/lib/encryption/customFieldValues.ts +67 -0
- package/src/lib/encryption/entityFields.ts +39 -0
- package/src/lib/encryption/entityIds.ts +107 -0
- package/src/lib/encryption/find.ts +81 -0
- package/src/lib/encryption/indexDoc.ts +104 -0
- package/src/lib/encryption/kms.ts +337 -0
- package/src/lib/encryption/subscriber.ts +416 -0
- package/src/lib/encryption/tenantDataEncryptionService.ts +313 -0
- package/src/lib/encryption/toggles.ts +15 -0
- package/src/lib/entities/naming.ts +6 -0
- package/src/lib/entities/system-entities.ts +43 -0
- package/src/lib/frontend/organizationEvents.ts +55 -0
- package/src/lib/frontend/useOrganizationScope.ts +30 -0
- package/src/lib/hotkeys/index.ts +168 -0
- package/src/lib/i18n/app-dictionaries.ts +18 -0
- package/src/lib/i18n/config.ts +4 -0
- package/src/lib/i18n/context.tsx +66 -0
- package/src/lib/i18n/server.ts +74 -0
- package/src/lib/i18n/translate.ts +54 -0
- package/src/lib/indexers/error-log.ts +106 -0
- package/src/lib/indexers/status-log.ts +119 -0
- package/src/lib/lib/auth/jwt.ts +39 -0
- package/src/lib/lib/auth/server.ts +94 -0
- package/src/lib/lib/email/send.ts +18 -0
- package/src/lib/lib/i18n/config.ts +4 -0
- package/src/lib/lib/i18n/context.tsx +38 -0
- package/src/lib/lib/utils.ts +6 -0
- package/src/lib/location/countries.ts +97 -0
- package/src/lib/modules/index.ts +1 -0
- package/src/lib/modules/registry.ts +18 -0
- package/src/lib/openapi/crud.ts +218 -0
- package/src/lib/openapi/generator.ts +1311 -0
- package/src/lib/openapi/index.ts +4 -0
- package/src/lib/openapi/sanitize.ts +137 -0
- package/src/lib/openapi/types.ts +79 -0
- package/src/lib/profiler/index.ts +371 -0
- package/src/lib/query/__tests__/engine.test.ts +274 -0
- package/src/lib/query/engine.ts +837 -0
- package/src/lib/query/join-utils.ts +238 -0
- package/src/lib/query/types.ts +121 -0
- package/src/lib/search/config.ts +49 -0
- package/src/lib/search/tokenize.ts +45 -0
- package/src/lib/slugify.ts +28 -0
- package/src/lib/testing/bootstrap.ts +124 -0
- package/src/lib/testing/index.ts +15 -0
- package/src/lib/testing/renderWithProviders.tsx +31 -0
- package/src/lib/url.ts +12 -0
- package/src/lib/utils.ts +17 -0
- package/src/lib/version.ts +5 -0
- package/src/modules/__tests__/dsl.test.ts +35 -0
- package/src/modules/__tests__/registry.test.ts +300 -0
- package/src/modules/dashboard/widgets.ts +57 -0
- package/src/modules/dsl.ts +32 -0
- package/src/modules/entities/__tests__/validation.test.ts +52 -0
- package/src/modules/entities/kinds.ts +20 -0
- package/src/modules/entities/options.ts +36 -0
- package/src/modules/entities/validation.ts +118 -0
- package/src/modules/entities/validators.ts +93 -0
- package/src/modules/entities.ts +102 -0
- package/src/modules/navigation/sidebarPreferences.ts +62 -0
- package/src/modules/perspectives/types.ts +40 -0
- package/src/modules/registry.ts +249 -0
- package/src/modules/search.ts +325 -0
- package/src/modules/vector.ts +122 -0
- package/src/modules/widgets/__tests__/injection.test.ts +48 -0
- package/src/modules/widgets/injection-loader.ts +235 -0
- package/src/modules/widgets/injection.ts +120 -0
- package/src/security/features.ts +22 -0
- package/src/types/pg.d.ts +2 -0
- package/src/types/react-email.d.ts +2 -0
- package/src/types/resend.d.ts +2 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +9 -0
- package/watch.mjs +6 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render } from "@testing-library/react";
|
|
3
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
+
import { I18nProvider } from "@open-mercato/shared/lib/i18n/context";
|
|
5
|
+
function renderWithProviders(ui, options) {
|
|
6
|
+
const { locale = "en", dict = {}, queryClient = new QueryClient(), ...rest } = options ?? {};
|
|
7
|
+
function Wrapper({ children }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(I18nProvider, { locale, dict, children }) });
|
|
9
|
+
}
|
|
10
|
+
return render(ui, { wrapper: Wrapper, ...rest });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
renderWithProviders
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=renderWithProviders.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/testing/renderWithProviders.tsx"],
|
|
4
|
+
"sourcesContent": ["import * as React from 'react'\nimport type { RenderOptions } from '@testing-library/react'\nimport { render } from '@testing-library/react'\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { I18nProvider } from '@open-mercato/shared/lib/i18n/context'\n\ntype ProviderOptions = {\n locale?: string\n dict?: Record<string, unknown>\n queryClient?: QueryClient\n}\n\nexport function renderWithProviders(\n ui: React.ReactElement,\n options?: RenderOptions & ProviderOptions,\n) {\n const { locale = 'en', dict = {}, queryClient = new QueryClient(), ...rest } = options ?? {}\n\n function Wrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {/* @ts-expect-error shared provider accepts loose dict shape */}\n <I18nProvider locale={locale} dict={dict}>\n {children}\n </I18nProvider>\n </QueryClientProvider>\n )\n }\n\n return render(ui, { wrapper: Wrapper, ...rest })\n}\n"],
|
|
5
|
+
"mappings": "AAsBQ;AApBR,SAAS,cAAc;AACvB,SAAS,aAAa,2BAA2B;AACjD,SAAS,oBAAoB;AAQtB,SAAS,oBACd,IACA,SACA;AACA,QAAM,EAAE,SAAS,MAAM,OAAO,CAAC,GAAG,cAAc,IAAI,YAAY,GAAG,GAAG,KAAK,IAAI,WAAW,CAAC;AAE3F,WAAS,QAAQ,EAAE,SAAS,GAAkC;AAC5D,WACE,oBAAC,uBAAoB,QAAQ,aAE3B,8BAAC,gBAAa,QAAgB,MAC3B,UACH,GACF;AAAA,EAEJ;AAEA,SAAO,OAAO,IAAI,EAAE,SAAS,SAAS,GAAG,KAAK,CAAC;AACjD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/lib/url.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function getAppBaseUrl(req) {
|
|
2
|
+
const url = new URL(req.url);
|
|
3
|
+
return process.env.NEXT_PUBLIC_APP_URL || process.env.APP_URL || `${url.protocol}//${url.host}`;
|
|
4
|
+
}
|
|
5
|
+
function toAbsoluteUrl(req, path) {
|
|
6
|
+
return new URL(path, getAppBaseUrl(req)).toString();
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
getAppBaseUrl,
|
|
10
|
+
toAbsoluteUrl
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=url.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/url.ts"],
|
|
4
|
+
"sourcesContent": ["export function getAppBaseUrl(req: Request): string {\n const url = new URL(req.url)\n return (\n process.env.NEXT_PUBLIC_APP_URL ||\n process.env.APP_URL ||\n `${url.protocol}//${url.host}`\n )\n}\n\nexport function toAbsoluteUrl(req: Request, path: string): string {\n return new URL(path, getAppBaseUrl(req)).toString()\n}\n"],
|
|
5
|
+
"mappings": "AAAO,SAAS,cAAc,KAAsB;AAClD,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,SACE,QAAQ,IAAI,uBACZ,QAAQ,IAAI,WACZ,GAAG,IAAI,QAAQ,KAAK,IAAI,IAAI;AAEhC;AAEO,SAAS,cAAc,KAAc,MAAsB;AAChE,SAAO,IAAI,IAAI,MAAM,cAAc,GAAG,CAAC,EAAE,SAAS;AACpD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { clsx } from "clsx";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
function cn(...inputs) {
|
|
4
|
+
return twMerge(clsx(inputs));
|
|
5
|
+
}
|
|
6
|
+
function slugifyTagLabel(label) {
|
|
7
|
+
return label.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || `tag-${Math.random().toString(36).slice(2, 10)}`;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
cn,
|
|
11
|
+
slugifyTagLabel
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/utils.ts"],
|
|
4
|
+
"sourcesContent": ["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport function slugifyTagLabel(label: string): string {\n return (\n label\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80) || `tag-${Math.random().toString(36).slice(2, 10)}`\n )\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;AAEO,SAAS,gBAAgB,OAAuB;AACrD,SACE,MACG,YAAY,EACZ,KAAK,EACL,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE,KAAK,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAErE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/version.ts"],
|
|
4
|
+
"sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.4.2-canary-c02407ff85'\nexport const appVersion = APP_VERSION\n"],
|
|
5
|
+
"mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=widgets.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function entityId(moduleId, entity) {
|
|
2
|
+
return `${moduleId}:${entity}`;
|
|
3
|
+
}
|
|
4
|
+
function linkable(moduleId, entities) {
|
|
5
|
+
return Object.fromEntries(entities.map((e) => [e, entityId(moduleId, e)]));
|
|
6
|
+
}
|
|
7
|
+
function defineLink(base, extension, opts) {
|
|
8
|
+
return { base, extension, ...opts };
|
|
9
|
+
}
|
|
10
|
+
const cf = {
|
|
11
|
+
text: (key, opts = {}) => ({ key, kind: "text", ...opts }),
|
|
12
|
+
multiline: (key, opts = {}) => ({ key, kind: "multiline", ...opts }),
|
|
13
|
+
integer: (key, opts = {}) => ({ key, kind: "integer", ...opts }),
|
|
14
|
+
float: (key, opts = {}) => ({ key, kind: "float", ...opts }),
|
|
15
|
+
boolean: (key, opts = {}) => ({ key, kind: "boolean", ...opts }),
|
|
16
|
+
select: (key, options, opts = {}) => ({ key, kind: "select", options, ...opts }),
|
|
17
|
+
currency: (key, opts = {}) => ({ key, kind: "currency", ...opts }),
|
|
18
|
+
dictionary: (key, dictionaryId, opts = {}) => ({ key, kind: "dictionary", dictionaryId, ...opts })
|
|
19
|
+
};
|
|
20
|
+
function defineFields(entity, fields, source) {
|
|
21
|
+
return { entity, fields, source };
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
cf,
|
|
25
|
+
defineFields,
|
|
26
|
+
defineLink,
|
|
27
|
+
entityId,
|
|
28
|
+
linkable
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=dsl.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/modules/dsl.ts"],
|
|
4
|
+
"sourcesContent": ["import type { CustomFieldDefinition, CustomFieldSet, EntityExtension, EntityId } from '@open-mercato/shared/modules/entities'\n\nexport function entityId(moduleId: string, entity: string): EntityId {\n return `${moduleId}:${entity}`\n}\n\nexport function linkable(moduleId: string, entities: string[]): Record<string, EntityId> {\n return Object.fromEntries(entities.map((e) => [e, entityId(moduleId, e)]))\n}\n\nexport function defineLink(\n base: EntityId,\n extension: EntityId,\n opts: Pick<EntityExtension, 'join' | 'cardinality' | 'required' | 'description'>\n): EntityExtension {\n return { base, extension, ...opts }\n}\n\nexport const cf = {\n text: (key: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind'> = {}): CustomFieldDefinition => ({ key, kind: 'text', ...opts }),\n multiline: (key: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind'> = {}): CustomFieldDefinition => ({ key, kind: 'multiline', ...opts }),\n integer: (key: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind'> = {}): CustomFieldDefinition => ({ key, kind: 'integer', ...opts }),\n float: (key: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind'> = {}): CustomFieldDefinition => ({ key, kind: 'float', ...opts }),\n boolean: (key: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind'> = {}): CustomFieldDefinition => ({ key, kind: 'boolean', ...opts }),\n select: (key: string, options: string[], opts: Omit<CustomFieldDefinition, 'key' | 'kind' | 'options'> = {}): CustomFieldDefinition => ({ key, kind: 'select', options, ...opts }),\n currency: (key: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind'> = {}): CustomFieldDefinition => ({ key, kind: 'currency', ...opts }),\n dictionary: (key: string, dictionaryId: string, opts: Omit<CustomFieldDefinition, 'key' | 'kind' | 'dictionaryId'> = {}): CustomFieldDefinition => ({ key, kind: 'dictionary', dictionaryId, ...opts }),\n}\n\nexport function defineFields(entity: EntityId, fields: CustomFieldDefinition[], source?: string): CustomFieldSet {\n return { entity, fields, source }\n}\n"],
|
|
5
|
+
"mappings": "AAEO,SAAS,SAAS,UAAkB,QAA0B;AACnE,SAAO,GAAG,QAAQ,IAAI,MAAM;AAC9B;AAEO,SAAS,SAAS,UAAkB,UAA8C;AACvF,SAAO,OAAO,YAAY,SAAS,IAAI,CAAC,MAAM,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC,CAAC,CAAC;AAC3E;AAEO,SAAS,WACd,MACA,WACA,MACiB;AACjB,SAAO,EAAE,MAAM,WAAW,GAAG,KAAK;AACpC;AAEO,MAAM,KAAK;AAAA,EAChB,MAAM,CAAC,KAAa,OAAoD,CAAC,OAA8B,EAAE,KAAK,MAAM,QAAQ,GAAG,KAAK;AAAA,EACpI,WAAW,CAAC,KAAa,OAAoD,CAAC,OAA8B,EAAE,KAAK,MAAM,aAAa,GAAG,KAAK;AAAA,EAC9I,SAAS,CAAC,KAAa,OAAoD,CAAC,OAA8B,EAAE,KAAK,MAAM,WAAW,GAAG,KAAK;AAAA,EAC1I,OAAO,CAAC,KAAa,OAAoD,CAAC,OAA8B,EAAE,KAAK,MAAM,SAAS,GAAG,KAAK;AAAA,EACtI,SAAS,CAAC,KAAa,OAAoD,CAAC,OAA8B,EAAE,KAAK,MAAM,WAAW,GAAG,KAAK;AAAA,EAC1I,QAAQ,CAAC,KAAa,SAAmB,OAAgE,CAAC,OAA8B,EAAE,KAAK,MAAM,UAAU,SAAS,GAAG,KAAK;AAAA,EAChL,UAAU,CAAC,KAAa,OAAoD,CAAC,OAA8B,EAAE,KAAK,MAAM,YAAY,GAAG,KAAK;AAAA,EAC5I,YAAY,CAAC,KAAa,cAAsB,OAAqE,CAAC,OAA8B,EAAE,KAAK,MAAM,cAAc,cAAc,GAAG,KAAK;AACvM;AAEO,SAAS,aAAa,QAAkB,QAAiC,QAAiC;AAC/G,SAAO,EAAE,QAAQ,QAAQ,OAAO;AAClC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const CUSTOM_FIELD_KINDS = [
|
|
2
|
+
"text",
|
|
3
|
+
"multiline",
|
|
4
|
+
"integer",
|
|
5
|
+
"float",
|
|
6
|
+
"boolean",
|
|
7
|
+
"select",
|
|
8
|
+
"currency",
|
|
9
|
+
"relation",
|
|
10
|
+
"attachment",
|
|
11
|
+
"dictionary"
|
|
12
|
+
];
|
|
13
|
+
function isCustomFieldKind(x) {
|
|
14
|
+
return CUSTOM_FIELD_KINDS.includes(x);
|
|
15
|
+
}
|
|
16
|
+
const CURRENCY_OPTIONS_URL = "/api/currencies/currencies/options";
|
|
17
|
+
export {
|
|
18
|
+
CURRENCY_OPTIONS_URL,
|
|
19
|
+
CUSTOM_FIELD_KINDS,
|
|
20
|
+
isCustomFieldKind
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=kinds.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/entities/kinds.ts"],
|
|
4
|
+
"sourcesContent": ["export const CUSTOM_FIELD_KINDS = [\n 'text',\n 'multiline',\n 'integer',\n 'float',\n 'boolean',\n 'select',\n 'currency',\n 'relation',\n 'attachment',\n 'dictionary',\n] as const\n\nexport type CustomFieldKind = typeof CUSTOM_FIELD_KINDS[number]\n\nexport function isCustomFieldKind(x: string): x is CustomFieldKind {\n return (CUSTOM_FIELD_KINDS as readonly string[]).includes(x)\n}\n\nexport const CURRENCY_OPTIONS_URL = '/api/currencies/currencies/options'\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,SAAS,kBAAkB,GAAiC;AACjE,SAAQ,mBAAyC,SAAS,CAAC;AAC7D;AAEO,MAAM,uBAAuB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function normalizeCustomFieldOption(option) {
|
|
2
|
+
if (typeof option === "string") {
|
|
3
|
+
const value = option.trim();
|
|
4
|
+
if (!value) return null;
|
|
5
|
+
return { value, label: value };
|
|
6
|
+
}
|
|
7
|
+
if (!option || typeof option !== "object") return null;
|
|
8
|
+
const rawValue = typeof option.value === "string" ? option.value.trim() : "";
|
|
9
|
+
if (!rawValue) return null;
|
|
10
|
+
const rawLabel = typeof option.label === "string" ? option.label.trim() : "";
|
|
11
|
+
return { value: rawValue, label: rawLabel || rawValue };
|
|
12
|
+
}
|
|
13
|
+
function normalizeCustomFieldOptions(options) {
|
|
14
|
+
if (!Array.isArray(options)) return [];
|
|
15
|
+
const normalized = [];
|
|
16
|
+
for (const entry of options) {
|
|
17
|
+
const item = normalizeCustomFieldOption(entry);
|
|
18
|
+
if (item) normalized.push(item);
|
|
19
|
+
}
|
|
20
|
+
return normalized;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
normalizeCustomFieldOption,
|
|
24
|
+
normalizeCustomFieldOptions
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/entities/options.ts"],
|
|
4
|
+
"sourcesContent": ["export type CustomFieldOptionInput =\n | string\n | {\n value?: string | null\n label?: string | null\n }\n | null\n | undefined\n\nexport type CustomFieldOptionDto = {\n value: string\n label: string\n}\n\nexport function normalizeCustomFieldOption(option: CustomFieldOptionInput): CustomFieldOptionDto | null {\n if (typeof option === 'string') {\n const value = option.trim()\n if (!value) return null\n return { value, label: value }\n }\n if (!option || typeof option !== 'object') return null\n const rawValue = typeof option.value === 'string' ? option.value.trim() : ''\n if (!rawValue) return null\n const rawLabel = typeof option.label === 'string' ? option.label.trim() : ''\n return { value: rawValue, label: rawLabel || rawValue }\n}\n\nexport function normalizeCustomFieldOptions(options: unknown): CustomFieldOptionDto[] {\n if (!Array.isArray(options)) return []\n const normalized: CustomFieldOptionDto[] = []\n for (const entry of options) {\n const item = normalizeCustomFieldOption(entry as CustomFieldOptionInput)\n if (item) normalized.push(item)\n }\n return normalized\n}\n"],
|
|
5
|
+
"mappings": "AAcO,SAAS,2BAA2B,QAA6D;AACtG,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,QAAQ,OAAO,KAAK;AAC1B,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,EAAE,OAAO,OAAO,MAAM;AAAA,EAC/B;AACA,MAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,QAAM,WAAW,OAAO,OAAO,UAAU,WAAW,OAAO,MAAM,KAAK,IAAI;AAC1E,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,WAAW,OAAO,OAAO,UAAU,WAAW,OAAO,MAAM,KAAK,IAAI;AAC1E,SAAO,EAAE,OAAO,UAAU,OAAO,YAAY,SAAS;AACxD;AAEO,SAAS,4BAA4B,SAA0C;AACpF,MAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,QAAO,CAAC;AACrC,QAAM,aAAqC,CAAC;AAC5C,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAO,2BAA2B,KAA+B;AACvE,QAAI,KAAM,YAAW,KAAK,IAAI;AAAA,EAChC;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const VALIDATION_RULES = [
|
|
3
|
+
"required",
|
|
4
|
+
"date",
|
|
5
|
+
"integer",
|
|
6
|
+
"float",
|
|
7
|
+
"lt",
|
|
8
|
+
"lte",
|
|
9
|
+
"gt",
|
|
10
|
+
"gte",
|
|
11
|
+
"eq",
|
|
12
|
+
"ne",
|
|
13
|
+
"regex"
|
|
14
|
+
];
|
|
15
|
+
const validationRuleSchema = z.discriminatedUnion("rule", [
|
|
16
|
+
z.object({ rule: z.literal("required"), message: z.string().min(1) }),
|
|
17
|
+
z.object({ rule: z.literal("date"), message: z.string().min(1) }),
|
|
18
|
+
z.object({ rule: z.literal("integer"), message: z.string().min(1) }),
|
|
19
|
+
z.object({ rule: z.literal("float"), message: z.string().min(1) }),
|
|
20
|
+
z.object({ rule: z.literal("lt"), param: z.number(), message: z.string().min(1) }),
|
|
21
|
+
z.object({ rule: z.literal("lte"), param: z.number(), message: z.string().min(1) }),
|
|
22
|
+
z.object({ rule: z.literal("gt"), param: z.number(), message: z.string().min(1) }),
|
|
23
|
+
z.object({ rule: z.literal("gte"), param: z.number(), message: z.string().min(1) }),
|
|
24
|
+
z.object({ rule: z.literal("eq"), param: z.any(), message: z.string().min(1) }),
|
|
25
|
+
z.object({ rule: z.literal("ne"), param: z.any(), message: z.string().min(1) }),
|
|
26
|
+
z.object({ rule: z.literal("regex"), param: z.string().min(1), message: z.string().min(1) })
|
|
27
|
+
]);
|
|
28
|
+
const validationRulesArraySchema = z.array(validationRuleSchema).max(32);
|
|
29
|
+
function evalRule(rule, value, kind) {
|
|
30
|
+
const isEmpty = (v) => v == null || typeof v === "string" && v.trim() === "" || Array.isArray(v) && v.length === 0;
|
|
31
|
+
switch (rule.rule) {
|
|
32
|
+
case "required":
|
|
33
|
+
return isEmpty(value) ? rule.message : null;
|
|
34
|
+
case "date": {
|
|
35
|
+
if (isEmpty(value)) return null;
|
|
36
|
+
const d = new Date(String(value));
|
|
37
|
+
return isNaN(d.getTime()) ? rule.message : null;
|
|
38
|
+
}
|
|
39
|
+
case "integer": {
|
|
40
|
+
if (isEmpty(value)) return null;
|
|
41
|
+
const n = Number(value);
|
|
42
|
+
return Number.isInteger(n) ? null : rule.message;
|
|
43
|
+
}
|
|
44
|
+
case "float": {
|
|
45
|
+
if (isEmpty(value)) return null;
|
|
46
|
+
const n = Number(value);
|
|
47
|
+
return Number.isFinite(n) ? null : rule.message;
|
|
48
|
+
}
|
|
49
|
+
case "lt":
|
|
50
|
+
if (isEmpty(value)) return null;
|
|
51
|
+
return Number(value) < rule.param ? null : rule.message;
|
|
52
|
+
case "lte":
|
|
53
|
+
if (isEmpty(value)) return null;
|
|
54
|
+
return Number(value) <= rule.param ? null : rule.message;
|
|
55
|
+
case "gt":
|
|
56
|
+
if (isEmpty(value)) return null;
|
|
57
|
+
return Number(value) > rule.param ? null : rule.message;
|
|
58
|
+
case "gte":
|
|
59
|
+
if (isEmpty(value)) return null;
|
|
60
|
+
return Number(value) >= rule.param ? null : rule.message;
|
|
61
|
+
case "eq":
|
|
62
|
+
if (isEmpty(value)) return null;
|
|
63
|
+
return value === rule.param ? null : rule.message;
|
|
64
|
+
case "ne":
|
|
65
|
+
if (isEmpty(value)) return null;
|
|
66
|
+
return value !== rule.param ? null : rule.message;
|
|
67
|
+
case "regex":
|
|
68
|
+
if (isEmpty(value)) return null;
|
|
69
|
+
try {
|
|
70
|
+
const re = new RegExp(rule.param);
|
|
71
|
+
return re.test(String(value)) ? null : rule.message;
|
|
72
|
+
} catch {
|
|
73
|
+
return rule.message;
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function validateValuesAgainstDefs(values, defs) {
|
|
80
|
+
const errors = {};
|
|
81
|
+
for (const def of defs) {
|
|
82
|
+
const cfg = def?.configJson || {};
|
|
83
|
+
const rules = Array.isArray(cfg.validation) ? cfg.validation : [];
|
|
84
|
+
if (rules.length === 0) continue;
|
|
85
|
+
const value = values[def.key];
|
|
86
|
+
for (const r of rules) {
|
|
87
|
+
const msg = evalRule(r, value, def.kind);
|
|
88
|
+
if (msg) {
|
|
89
|
+
errors[`cf_${def.key}`] = msg;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { ok: Object.keys(errors).length === 0, fieldErrors: errors };
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
VALIDATION_RULES,
|
|
98
|
+
validateValuesAgainstDefs,
|
|
99
|
+
validationRuleSchema,
|
|
100
|
+
validationRulesArraySchema
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/entities/validation.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\n// Supported rule types for custom fields validation\nexport const VALIDATION_RULES = [\n 'required',\n 'date',\n 'integer',\n 'float',\n 'lt',\n 'lte',\n 'gt',\n 'gte',\n 'eq',\n 'ne',\n 'regex',\n] as const\n\nexport type ValidationRuleKind = typeof VALIDATION_RULES[number]\n\nexport const validationRuleSchema = z.discriminatedUnion('rule', [\n z.object({ rule: z.literal('required'), message: z.string().min(1) }),\n z.object({ rule: z.literal('date'), message: z.string().min(1) }),\n z.object({ rule: z.literal('integer'), message: z.string().min(1) }),\n z.object({ rule: z.literal('float'), message: z.string().min(1) }),\n z.object({ rule: z.literal('lt'), param: z.number(), message: z.string().min(1) }),\n z.object({ rule: z.literal('lte'), param: z.number(), message: z.string().min(1) }),\n z.object({ rule: z.literal('gt'), param: z.number(), message: z.string().min(1) }),\n z.object({ rule: z.literal('gte'), param: z.number(), message: z.string().min(1) }),\n z.object({ rule: z.literal('eq'), param: z.any(), message: z.string().min(1) }),\n z.object({ rule: z.literal('ne'), param: z.any(), message: z.string().min(1) }),\n z.object({ rule: z.literal('regex'), param: z.string().min(1), message: z.string().min(1) }),\n])\n\nexport type ValidationRule = z.infer<typeof validationRuleSchema>\n\nexport const validationRulesArraySchema = z.array(validationRuleSchema).max(32)\n\nexport type CustomFieldDefLike = {\n key: string\n kind: string\n configJson?: any\n}\n\n// Evaluate a single rule against a value\nfunction evalRule(rule: ValidationRule, value: any, kind: string): string | null {\n const isEmpty = (v: any) => v == null || (typeof v === 'string' && v.trim() === '') || (Array.isArray(v) && v.length === 0)\n\n switch (rule.rule) {\n case 'required':\n return isEmpty(value) ? rule.message : null\n case 'date': {\n if (isEmpty(value)) return null\n const d = new Date(String(value))\n return isNaN(d.getTime()) ? rule.message : null\n }\n case 'integer': {\n if (isEmpty(value)) return null\n const n = Number(value)\n return Number.isInteger(n) ? null : rule.message\n }\n case 'float': {\n if (isEmpty(value)) return null\n const n = Number(value)\n return Number.isFinite(n) ? null : rule.message\n }\n case 'lt':\n if (isEmpty(value)) return null\n return Number(value) < (rule as any).param ? null : rule.message\n case 'lte':\n if (isEmpty(value)) return null\n return Number(value) <= (rule as any).param ? null : rule.message\n case 'gt':\n if (isEmpty(value)) return null\n return Number(value) > (rule as any).param ? null : rule.message\n case 'gte':\n if (isEmpty(value)) return null\n return Number(value) >= (rule as any).param ? null : rule.message\n case 'eq':\n if (isEmpty(value)) return null\n return value === (rule as any).param ? null : rule.message\n case 'ne':\n if (isEmpty(value)) return null\n return value !== (rule as any).param ? null : rule.message\n case 'regex':\n if (isEmpty(value)) return null\n try {\n const re = new RegExp((rule as any).param)\n return re.test(String(value)) ? null : rule.message\n } catch {\n // Invalid regex in definition: consider it failed safe and return message\n return rule.message\n }\n default:\n return null\n }\n}\n\nexport function validateValuesAgainstDefs(\n values: Record<string, any>,\n defs: CustomFieldDefLike[],\n): { ok: boolean; fieldErrors: Record<string, string> } {\n const errors: Record<string, string> = {}\n for (const def of defs) {\n const cfg = def?.configJson || {}\n const rules: ValidationRule[] = Array.isArray(cfg.validation) ? cfg.validation : []\n if (rules.length === 0) continue\n const value = values[def.key]\n for (const r of rules) {\n const msg = evalRule(r as any, value, def.kind)\n if (msg) {\n errors[`cf_${def.key}`] = msg\n break\n }\n }\n }\n return { ok: Object.keys(errors).length === 0, fieldErrors: errors }\n}\n\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAGX,MAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,uBAAuB,EAAE,mBAAmB,QAAQ;AAAA,EAC/D,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,UAAU,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EACpE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EAChE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAS,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EACnE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EACjE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,IAAI,GAAG,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EACjF,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EAClF,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,IAAI,GAAG,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EACjF,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EAClF,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,IAAI,GAAG,OAAO,EAAE,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EAC9E,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,IAAI,GAAG,OAAO,EAAE,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EAC9E,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAC7F,CAAC;AAIM,MAAM,6BAA6B,EAAE,MAAM,oBAAoB,EAAE,IAAI,EAAE;AAS9E,SAAS,SAAS,MAAsB,OAAY,MAA6B;AAC/E,QAAM,UAAU,CAAC,MAAW,KAAK,QAAS,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,MAAQ,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW;AAEzH,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,QAAQ,KAAK,IAAI,KAAK,UAAU;AAAA,IACzC,KAAK,QAAQ;AACX,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,YAAM,IAAI,IAAI,KAAK,OAAO,KAAK,CAAC;AAChC,aAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,KAAK,UAAU;AAAA,IAC7C;AAAA,IACA,KAAK,WAAW;AACd,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,YAAM,IAAI,OAAO,KAAK;AACtB,aAAO,OAAO,UAAU,CAAC,IAAI,OAAO,KAAK;AAAA,IAC3C;AAAA,IACA,KAAK,SAAS;AACZ,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,YAAM,IAAI,OAAO,KAAK;AACtB,aAAO,OAAO,SAAS,CAAC,IAAI,OAAO,KAAK;AAAA,IAC1C;AAAA,IACA,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,aAAO,OAAO,KAAK,IAAK,KAAa,QAAQ,OAAO,KAAK;AAAA,IAC3D,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,aAAO,OAAO,KAAK,KAAM,KAAa,QAAQ,OAAO,KAAK;AAAA,IAC5D,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,aAAO,OAAO,KAAK,IAAK,KAAa,QAAQ,OAAO,KAAK;AAAA,IAC3D,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,aAAO,OAAO,KAAK,KAAM,KAAa,QAAQ,OAAO,KAAK;AAAA,IAC5D,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,aAAO,UAAW,KAAa,QAAQ,OAAO,KAAK;AAAA,IACrD,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,aAAO,UAAW,KAAa,QAAQ,OAAO,KAAK;AAAA,IACrD,KAAK;AACH,UAAI,QAAQ,KAAK,EAAG,QAAO;AAC3B,UAAI;AACF,cAAM,KAAK,IAAI,OAAQ,KAAa,KAAK;AACzC,eAAO,GAAG,KAAK,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK;AAAA,MAC9C,QAAQ;AAEN,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,0BACd,QACA,MACsD;AACtD,QAAM,SAAiC,CAAC;AACxC,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,KAAK,cAAc,CAAC;AAChC,UAAM,QAA0B,MAAM,QAAQ,IAAI,UAAU,IAAI,IAAI,aAAa,CAAC;AAClF,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,eAAW,KAAK,OAAO;AACrB,YAAM,MAAM,SAAS,GAAU,OAAO,IAAI,IAAI;AAC9C,UAAI,KAAK;AACP,eAAO,MAAM,IAAI,GAAG,EAAE,IAAI;AAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,IAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG,aAAa,OAAO;AACrE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CUSTOM_FIELD_KINDS } from "./kinds.js";
|
|
3
|
+
import { validationRulesArraySchema } from "./validation.js";
|
|
4
|
+
const entityIdRegex = /^[a-z0-9_]+:[a-z0-9_]+$/;
|
|
5
|
+
const fieldsetCodeRegex = /^[a-z0-9_\-]+$/;
|
|
6
|
+
const upsertCustomEntitySchema = z.object({
|
|
7
|
+
entityId: z.string().regex(
|
|
8
|
+
entityIdRegex,
|
|
9
|
+
"Enter the entity id in the format: module_name:entity_id with your prefered entity and module names"
|
|
10
|
+
),
|
|
11
|
+
label: z.string().min(1).max(200),
|
|
12
|
+
description: z.string().max(2e3).optional().nullable(),
|
|
13
|
+
labelField: z.string().min(1).max(100).regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/).optional(),
|
|
14
|
+
defaultEditor: z.enum(["markdown", "simpleMarkdown", "htmlRichText"]).optional(),
|
|
15
|
+
showInSidebar: z.boolean().default(false),
|
|
16
|
+
isActive: z.boolean().optional()
|
|
17
|
+
});
|
|
18
|
+
const upsertCustomFieldDefSchema = z.object({
|
|
19
|
+
entityId: z.string().regex(entityIdRegex),
|
|
20
|
+
key: z.string().min(1).max(100).regex(/^[a-z0-9_]+$/, "snake_case only"),
|
|
21
|
+
kind: z.enum(CUSTOM_FIELD_KINDS),
|
|
22
|
+
configJson: z.object({
|
|
23
|
+
// optional UI/behavioral hints
|
|
24
|
+
label: z.string().max(200).optional(),
|
|
25
|
+
description: z.string().max(2e3).optional(),
|
|
26
|
+
options: z.array(z.union([z.string(), z.number()])).optional(),
|
|
27
|
+
optionsUrl: z.string().url().optional(),
|
|
28
|
+
multi: z.boolean().optional(),
|
|
29
|
+
editor: z.string().optional(),
|
|
30
|
+
input: z.string().optional(),
|
|
31
|
+
filterable: z.boolean().optional(),
|
|
32
|
+
formEditable: z.boolean().optional(),
|
|
33
|
+
listVisible: z.boolean().optional(),
|
|
34
|
+
priority: z.number().optional(),
|
|
35
|
+
encrypted: z.boolean().optional(),
|
|
36
|
+
relatedEntityId: z.string().optional(),
|
|
37
|
+
dictionaryId: z.string().uuid().optional(),
|
|
38
|
+
dictionaryInlineCreate: z.boolean().optional(),
|
|
39
|
+
// validation rules
|
|
40
|
+
validation: validationRulesArraySchema.optional(),
|
|
41
|
+
fieldset: z.string().regex(fieldsetCodeRegex).optional(),
|
|
42
|
+
group: z.object({
|
|
43
|
+
code: z.string().regex(fieldsetCodeRegex),
|
|
44
|
+
title: z.string().max(200).optional(),
|
|
45
|
+
hint: z.string().max(500).optional()
|
|
46
|
+
}).optional()
|
|
47
|
+
}).passthrough().optional(),
|
|
48
|
+
isActive: z.boolean().optional()
|
|
49
|
+
});
|
|
50
|
+
const customFieldsetGroupSchema = z.object({
|
|
51
|
+
code: z.string().regex(fieldsetCodeRegex),
|
|
52
|
+
title: z.string().max(200).optional(),
|
|
53
|
+
hint: z.string().max(500).optional()
|
|
54
|
+
});
|
|
55
|
+
const customFieldsetSchema = z.object({
|
|
56
|
+
code: z.string().regex(fieldsetCodeRegex),
|
|
57
|
+
label: z.string().min(1).max(255),
|
|
58
|
+
icon: z.string().max(100).optional(),
|
|
59
|
+
description: z.string().max(2e3).optional(),
|
|
60
|
+
groups: z.array(customFieldsetGroupSchema).optional()
|
|
61
|
+
});
|
|
62
|
+
const customFieldEntityConfigSchema = z.object({
|
|
63
|
+
fieldsets: z.array(customFieldsetSchema).max(20).optional(),
|
|
64
|
+
singleFieldsetPerRecord: z.boolean().optional()
|
|
65
|
+
});
|
|
66
|
+
const encryptionFieldRuleSchema = z.object({
|
|
67
|
+
field: z.string().min(1).max(200),
|
|
68
|
+
hashField: z.string().min(1).max(200).optional().nullable()
|
|
69
|
+
});
|
|
70
|
+
const upsertEncryptionMapSchema = z.object({
|
|
71
|
+
entityId: z.string().regex(entityIdRegex),
|
|
72
|
+
tenantId: z.string().uuid().nullable().optional(),
|
|
73
|
+
organizationId: z.string().uuid().nullable().optional(),
|
|
74
|
+
fields: z.array(encryptionFieldRuleSchema).min(1),
|
|
75
|
+
isActive: z.boolean().optional()
|
|
76
|
+
});
|
|
77
|
+
export {
|
|
78
|
+
customFieldEntityConfigSchema,
|
|
79
|
+
customFieldsetGroupSchema,
|
|
80
|
+
customFieldsetSchema,
|
|
81
|
+
encryptionFieldRuleSchema,
|
|
82
|
+
entityIdRegex,
|
|
83
|
+
fieldsetCodeRegex,
|
|
84
|
+
upsertCustomEntitySchema,
|
|
85
|
+
upsertCustomFieldDefSchema,
|
|
86
|
+
upsertEncryptionMapSchema
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/entities/validators.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport { CUSTOM_FIELD_KINDS } from './kinds'\nimport { validationRulesArraySchema } from './validation'\n\nexport const entityIdRegex = /^[a-z0-9_]+:[a-z0-9_]+$/\nexport const fieldsetCodeRegex = /^[a-z0-9_\\-]+$/\n\nexport const upsertCustomEntitySchema = z.object({\n entityId: z.string().regex(\n entityIdRegex,\n 'Enter the entity id in the format: module_name:entity_id with your prefered entity and module names'\n ),\n label: z.string().min(1).max(200),\n description: z.string().max(2000).optional().nullable(),\n labelField: z.string().min(1).max(100).regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/).optional(),\n defaultEditor: z.enum(['markdown','simpleMarkdown','htmlRichText']).optional(),\n showInSidebar: z.boolean().default(false),\n isActive: z.boolean().optional(),\n})\n\nexport const upsertCustomFieldDefSchema = z.object({\n entityId: z.string().regex(entityIdRegex),\n key: z.string().min(1).max(100).regex(/^[a-z0-9_]+$/, 'snake_case only'),\n kind: z.enum(CUSTOM_FIELD_KINDS),\n configJson: z\n .object({\n // optional UI/behavioral hints\n label: z.string().max(200).optional(),\n description: z.string().max(2000).optional(),\n options: z.array(z.union([z.string(), z.number()])).optional(),\n optionsUrl: z.string().url().optional(),\n multi: z.boolean().optional(),\n editor: z.string().optional(),\n input: z.string().optional(),\n filterable: z.boolean().optional(),\n formEditable: z.boolean().optional(),\n listVisible: z.boolean().optional(),\n priority: z.number().optional(),\n encrypted: z.boolean().optional(),\n relatedEntityId: z.string().optional(),\n dictionaryId: z.string().uuid().optional(),\n dictionaryInlineCreate: z.boolean().optional(),\n // validation rules\n validation: validationRulesArraySchema.optional(),\n fieldset: z.string().regex(fieldsetCodeRegex).optional(),\n group: z\n .object({\n code: z.string().regex(fieldsetCodeRegex),\n title: z.string().max(200).optional(),\n hint: z.string().max(500).optional(),\n })\n .optional(),\n })\n .passthrough()\n .optional(),\n isActive: z.boolean().optional(),\n})\n\nexport const customFieldsetGroupSchema = z.object({\n code: z.string().regex(fieldsetCodeRegex),\n title: z.string().max(200).optional(),\n hint: z.string().max(500).optional(),\n})\n\nexport const customFieldsetSchema = z.object({\n code: z.string().regex(fieldsetCodeRegex),\n label: z.string().min(1).max(255),\n icon: z.string().max(100).optional(),\n description: z.string().max(2000).optional(),\n groups: z.array(customFieldsetGroupSchema).optional(),\n})\n\nexport const customFieldEntityConfigSchema = z.object({\n fieldsets: z.array(customFieldsetSchema).max(20).optional(),\n singleFieldsetPerRecord: z.boolean().optional(),\n})\n\nexport const encryptionFieldRuleSchema = z.object({\n field: z.string().min(1).max(200),\n hashField: z.string().min(1).max(200).optional().nullable(),\n})\n\nexport const upsertEncryptionMapSchema = z.object({\n entityId: z.string().regex(entityIdRegex),\n tenantId: z.string().uuid().nullable().optional(),\n organizationId: z.string().uuid().nullable().optional(),\n fields: z.array(encryptionFieldRuleSchema).min(1),\n isActive: z.boolean().optional(),\n})\n\nexport type UpsertCustomEntityInput = z.infer<typeof upsertCustomEntitySchema>\nexport type UpsertCustomFieldDefInput = z.infer<typeof upsertCustomFieldDefSchema>\nexport type UpsertEncryptionMapInput = z.infer<typeof upsertEncryptionMapSchema>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,0BAA0B;AACnC,SAAS,kCAAkC;AAEpC,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAE1B,MAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,UAAU,EAAE,OAAO,EAAE;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAChC,aAAa,EAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EACtD,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,MAAM,0BAA0B,EAAE,SAAS;AAAA,EAClF,eAAe,EAAE,KAAK,CAAC,YAAW,kBAAiB,cAAc,CAAC,EAAE,SAAS;AAAA,EAC7E,eAAe,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACxC,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAEM,MAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa;AAAA,EACxC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,MAAM,gBAAgB,iBAAiB;AAAA,EACvE,MAAM,EAAE,KAAK,kBAAkB;AAAA,EAC/B,YAAY,EACT,OAAO;AAAA;AAAA,IAEN,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,IACpC,aAAa,EAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,IAC3C,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS;AAAA,IAC7D,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,IACtC,OAAO,EAAE,QAAQ,EAAE,SAAS;AAAA,IAC5B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,YAAY,EAAE,QAAQ,EAAE,SAAS;AAAA,IACjC,cAAc,EAAE,QAAQ,EAAE,SAAS;AAAA,IACnC,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,IAClC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,WAAW,EAAE,QAAQ,EAAE,SAAS;AAAA,IAChC,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,IACzC,wBAAwB,EAAE,QAAQ,EAAE,SAAS;AAAA;AAAA,IAE7C,YAAY,2BAA2B,SAAS;AAAA,IAChD,UAAU,EAAE,OAAO,EAAE,MAAM,iBAAiB,EAAE,SAAS;AAAA,IACvD,OAAO,EACJ,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB;AAAA,MACxC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,MACpC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,IACrC,CAAC,EACA,SAAS;AAAA,EACd,CAAC,EACA,YAAY,EACZ,SAAS;AAAA,EACZ,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAEM,MAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACpC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACrC,CAAC;AAEM,MAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAChC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACnC,aAAa,EAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EAC3C,QAAQ,EAAE,MAAM,yBAAyB,EAAE,SAAS;AACtD,CAAC;AAEM,MAAM,gCAAgC,EAAE,OAAO;AAAA,EACpD,WAAW,EAAE,MAAM,oBAAoB,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAC1D,yBAAyB,EAAE,QAAQ,EAAE,SAAS;AAChD,CAAC;AAEM,MAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAChC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS;AAC5D,CAAC;AAEM,MAAM,4BAA4B,EAAE,OAAO;AAAA,EAChD,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa;AAAA,EACxC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EACtD,QAAQ,EAAE,MAAM,yBAAyB,EAAE,IAAI,CAAC;AAAA,EAChD,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=entities.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { slugify } from "../../lib/slugify.js";
|
|
2
|
+
const SIDEBAR_PREFERENCES_VERSION = 2;
|
|
3
|
+
function normalizeSidebarSettings(settings) {
|
|
4
|
+
if (!settings || typeof settings !== "object") {
|
|
5
|
+
return { version: SIDEBAR_PREFERENCES_VERSION, groupOrder: [], groupLabels: {}, itemLabels: {}, hiddenItems: [] };
|
|
6
|
+
}
|
|
7
|
+
const version = typeof settings.version === "number" ? settings.version : SIDEBAR_PREFERENCES_VERSION;
|
|
8
|
+
const groupOrder = Array.isArray(settings.groupOrder) ? settings.groupOrder.filter((v) => typeof v === "string") : [];
|
|
9
|
+
const groupLabels = normalizeRecord(settings.groupLabels);
|
|
10
|
+
const itemLabels = normalizeRecord(settings.itemLabels);
|
|
11
|
+
const hiddenItems = normalizeStringArray(settings.hiddenItems);
|
|
12
|
+
return {
|
|
13
|
+
version,
|
|
14
|
+
groupOrder,
|
|
15
|
+
groupLabels,
|
|
16
|
+
itemLabels,
|
|
17
|
+
hiddenItems
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function normalizeRecord(record) {
|
|
21
|
+
if (!record || typeof record !== "object") return {};
|
|
22
|
+
const out = {};
|
|
23
|
+
for (const [key, value] of Object.entries(record)) {
|
|
24
|
+
if (typeof value !== "string") continue;
|
|
25
|
+
out[key] = value;
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
function normalizeStringArray(values) {
|
|
30
|
+
if (!Array.isArray(values)) return [];
|
|
31
|
+
const seen = /* @__PURE__ */ new Set();
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const value of values) {
|
|
34
|
+
if (typeof value !== "string") continue;
|
|
35
|
+
const trimmed = value.trim();
|
|
36
|
+
if (!trimmed || seen.has(trimmed)) continue;
|
|
37
|
+
seen.add(trimmed);
|
|
38
|
+
out.push(trimmed);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
function slugifySidebarId(source) {
|
|
43
|
+
return slugify(source, { allowedChars: "" }) || "group";
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
SIDEBAR_PREFERENCES_VERSION,
|
|
47
|
+
normalizeSidebarSettings,
|
|
48
|
+
slugifySidebarId
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=sidebarPreferences.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/navigation/sidebarPreferences.ts"],
|
|
4
|
+
"sourcesContent": ["import { slugify } from '../../lib/slugify'\n\nexport const SIDEBAR_PREFERENCES_VERSION = 2\n\nexport type SidebarPreferencesSettings = {\n version: number\n groupOrder?: string[]\n groupLabels?: Record<string, string>\n itemLabels?: Record<string, string>\n hiddenItems?: string[]\n}\n\nexport type SidebarPreferencesPayload = {\n locale: string\n settings: SidebarPreferencesSettings\n}\n\nexport function normalizeSidebarSettings(settings?: SidebarPreferencesSettings | null): SidebarPreferencesSettings {\n if (!settings || typeof settings !== 'object') {\n return { version: SIDEBAR_PREFERENCES_VERSION, groupOrder: [], groupLabels: {}, itemLabels: {}, hiddenItems: [] }\n }\n const version = typeof settings.version === 'number' ? settings.version : SIDEBAR_PREFERENCES_VERSION\n const groupOrder = Array.isArray(settings.groupOrder) ? settings.groupOrder.filter((v): v is string => typeof v === 'string') : []\n const groupLabels = normalizeRecord(settings.groupLabels)\n const itemLabels = normalizeRecord(settings.itemLabels)\n const hiddenItems = normalizeStringArray(settings.hiddenItems)\n return {\n version,\n groupOrder,\n groupLabels,\n itemLabels,\n hiddenItems,\n }\n}\n\nfunction normalizeRecord(record: Record<string, unknown> | undefined): Record<string, string> {\n if (!record || typeof record !== 'object') return {}\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n if (typeof value !== 'string') continue\n out[key] = value\n }\n return out\n}\n\nfunction normalizeStringArray(values: unknown): string[] {\n if (!Array.isArray(values)) return []\n const seen = new Set<string>()\n const out: string[] = []\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (!trimmed || seen.has(trimmed)) continue\n seen.add(trimmed)\n out.push(trimmed)\n }\n return out\n}\n\nexport function slugifySidebarId(source: string): string {\n return slugify(source, { allowedChars: '' }) || 'group'\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,eAAe;AAEjB,MAAM,8BAA8B;AAepC,SAAS,yBAAyB,UAA0E;AACjH,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,WAAO,EAAE,SAAS,6BAA6B,YAAY,CAAC,GAAG,aAAa,CAAC,GAAG,YAAY,CAAC,GAAG,aAAa,CAAC,EAAE;AAAA,EAClH;AACA,QAAM,UAAU,OAAO,SAAS,YAAY,WAAW,SAAS,UAAU;AAC1E,QAAM,aAAa,MAAM,QAAQ,SAAS,UAAU,IAAI,SAAS,WAAW,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAAI,CAAC;AACjI,QAAM,cAAc,gBAAgB,SAAS,WAAW;AACxD,QAAM,aAAa,gBAAgB,SAAS,UAAU;AACtD,QAAM,cAAc,qBAAqB,SAAS,WAAW;AAC7D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,QAAqE;AAC5F,MAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO,CAAC;AACnD,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,OAAO,UAAU,SAAU;AAC/B,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,QAA2B;AACvD,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AACpC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,QAAQ;AAC1B,QAAI,OAAO,UAAU,SAAU;AAC/B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,CAAC,WAAW,KAAK,IAAI,OAAO,EAAG;AACnC,SAAK,IAAI,OAAO;AAChB,QAAI,KAAK,OAAO;AAAA,EAClB;AACA,SAAO;AACT;AAEO,SAAS,iBAAiB,QAAwB;AACvD,SAAO,QAAQ,QAAQ,EAAE,cAAc,GAAG,CAAC,KAAK;AAClD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
function normPath(s) {
|
|
2
|
+
return (s.startsWith("/") ? s : "/" + s).replace(/\/+$/, "") || "/";
|
|
3
|
+
}
|
|
4
|
+
function matchPattern(pattern, pathname) {
|
|
5
|
+
const p = normPath(pattern);
|
|
6
|
+
const u = normPath(pathname);
|
|
7
|
+
const pSegs = p.split("/").slice(1);
|
|
8
|
+
const uSegs = u.split("/").slice(1);
|
|
9
|
+
const params = {};
|
|
10
|
+
let i = 0;
|
|
11
|
+
for (let j = 0; j < pSegs.length; j++, i++) {
|
|
12
|
+
const seg = pSegs[j];
|
|
13
|
+
const mCatchAll = seg.match(/^\[\.\.\.(.+)\]$/);
|
|
14
|
+
const mOptCatch = seg.match(/^\[\[\.\.\.(.+)\]\]$/);
|
|
15
|
+
const mDyn = seg.match(/^\[(.+)\]$/);
|
|
16
|
+
if (mCatchAll) {
|
|
17
|
+
const key = mCatchAll[1];
|
|
18
|
+
if (i >= uSegs.length) return void 0;
|
|
19
|
+
params[key] = uSegs.slice(i);
|
|
20
|
+
i = uSegs.length;
|
|
21
|
+
return i === uSegs.length ? params : void 0;
|
|
22
|
+
} else if (mOptCatch) {
|
|
23
|
+
const key = mOptCatch[1];
|
|
24
|
+
params[key] = i < uSegs.length ? uSegs.slice(i) : [];
|
|
25
|
+
i = uSegs.length;
|
|
26
|
+
return params;
|
|
27
|
+
} else if (mDyn) {
|
|
28
|
+
if (i >= uSegs.length) return void 0;
|
|
29
|
+
params[mDyn[1]] = uSegs[i];
|
|
30
|
+
} else {
|
|
31
|
+
if (i >= uSegs.length || uSegs[i] !== seg) return void 0;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (i !== uSegs.length) return void 0;
|
|
35
|
+
return params;
|
|
36
|
+
}
|
|
37
|
+
function getPattern(r) {
|
|
38
|
+
return r.pattern ?? r.path ?? "/";
|
|
39
|
+
}
|
|
40
|
+
function findFrontendMatch(modules, pathname) {
|
|
41
|
+
for (const m of modules) {
|
|
42
|
+
const routes = m.frontendRoutes ?? [];
|
|
43
|
+
for (const r of routes) {
|
|
44
|
+
const params = matchPattern(getPattern(r), pathname);
|
|
45
|
+
if (params) return { route: r, params };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function findBackendMatch(modules, pathname) {
|
|
50
|
+
for (const m of modules) {
|
|
51
|
+
const routes = m.backendRoutes ?? [];
|
|
52
|
+
for (const r of routes) {
|
|
53
|
+
const params = matchPattern(getPattern(r), pathname);
|
|
54
|
+
if (params) return { route: r, params };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function findApi(modules, method, pathname) {
|
|
59
|
+
for (const m of modules) {
|
|
60
|
+
const apis = m.apis ?? [];
|
|
61
|
+
for (const a of apis) {
|
|
62
|
+
if ("handlers" in a) {
|
|
63
|
+
const params = matchPattern(a.path, pathname);
|
|
64
|
+
const handler = a.handlers[method];
|
|
65
|
+
if (params && handler) return { handler, params, requireAuth: a.requireAuth, requireRoles: a.requireRoles, metadata: a.metadata };
|
|
66
|
+
} else {
|
|
67
|
+
const al = a;
|
|
68
|
+
if (al.method === method && al.path === pathname) {
|
|
69
|
+
return { handler: al.handler, params: {} };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
let _cliModules = null;
|
|
76
|
+
function registerCliModules(modules) {
|
|
77
|
+
if (_cliModules !== null && process.env.NODE_ENV === "development") {
|
|
78
|
+
console.debug("[Bootstrap] CLI modules re-registered (this may occur during HMR)");
|
|
79
|
+
}
|
|
80
|
+
_cliModules = modules;
|
|
81
|
+
}
|
|
82
|
+
function getCliModules() {
|
|
83
|
+
return _cliModules ?? [];
|
|
84
|
+
}
|
|
85
|
+
function hasCliModules() {
|
|
86
|
+
return _cliModules !== null && _cliModules.length > 0;
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
findApi,
|
|
90
|
+
findBackendMatch,
|
|
91
|
+
findFrontendMatch,
|
|
92
|
+
getCliModules,
|
|
93
|
+
hasCliModules,
|
|
94
|
+
registerCliModules
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=registry.js.map
|