First commit

This commit is contained in:
Sachin
2025-12-16 22:26:18 +05:30
commit 03ed187ebe
122 changed files with 68601 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
"lynkedup-pro",
"lynkedup-foundation",
"api-bff",
"sdk-playground"
]
}
+87
View File
@@ -0,0 +1,87 @@
module.exports = {
root: true,
ignorePatterns: ['**/*'],
plugins: ['@nx'],
extends: ['@react-native'],
overrides: [
{
files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
rules: {
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
// Domain Purity: Domain layers can only depend on other domain layers or types
{
sourceTag: 'type:domain',
onlyDependOnLibsWithTags: ['type:domain', 'type:types', 'scope:shared']
},
// Data layer can depend on domain and core infrastructure
{
sourceTag: 'type:data',
onlyDependOnLibsWithTags: [
'type:domain',
'type:types',
'scope:core',
'scope:shared'
]
},
// UI layer can depend on data and domain
{
sourceTag: 'type:ui',
onlyDependOnLibsWithTags: [
'type:data',
'type:domain',
'type:types',
'scope:shared'
]
},
// Platform-specific rules
{
sourceTag: 'platform:shared',
notDependOnLibsWithTags: ['platform:rn', 'platform:node']
},
// Vertical isolation: Features cannot depend on other features
{
sourceTag: 'scope:feature',
notDependOnLibsWithTags: ['scope:feature']
},
// Core SDKs can only depend on other core SDKs or shared
{
sourceTag: 'scope:core',
onlyDependOnLibsWithTags: ['scope:core', 'scope:shared', 'type:types']
}
]
}
]
}
},
{
files: ['*.ts', '*.tsx'],
extends: ['@nx/typescript'],
rules: {
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/explicit-function-return-type': 'warn'
}
},
{
files: ['*.js', '*.jsx'],
extends: ['@nx/javascript'],
rules: {}
},
{
files: ['*.spec.ts', '*.spec.tsx', '*.spec.js', '*.spec.jsx'],
env: {
jest: true
},
rules: {}
}
]
};
+4
View File
@@ -0,0 +1,4 @@
node_modules
/apps/lynkedup-pro
/apps/lynkedup-foundation
/apps/sdk-playground
+10
View File
@@ -0,0 +1,10 @@
module.exports = {
'**/*.{ts,tsx,js,jsx}': [
'eslint',
'prettier --write'
],
'**/*.{json,md,yml,yaml}': [
'prettier --write'
],
'**/*.ts?(x)': () => 'nx affected -t typecheck'
};
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+23
View File
@@ -0,0 +1,23 @@
{
"name": "nx-cloud-client-bundle",
"version": "0.0.1",
"type": "commonjs",
"main": "index.js",
"author": "Victor Savkin",
"license": "proprietary",
"dependencies": {
"axios": "1.1.3",
"enquirer": "2.4.1",
"dotenv": "~10.0.0",
"node-machine-id": "^1.1.12",
"tar": "6.1.11",
"strip-json-comments": "^5.0.1",
"chalk": "4.1.2",
"yargs-parser": ">=21.1.1",
"fs-extra": "^11.1.0",
"open": "~8.4.0",
"ini": "4.1.3",
"yaml": "2.6.1",
"semver": "7.5.4"
}
}
+414
View File
@@ -0,0 +1,414 @@
<html>
<head>
<title>Nx Cloud login</title>
<style>
*,
:before,
:after {
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family:
ui-sans-serif,
system-ui,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji',
Segoe UI Symbol,
'Noto Color Emoji';
font-feature-settings: normal;
font-variation-settings: normal;
-webkit-tap-highlight-color: transparent;
line-height: inherit;
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
box-sizing: border-box;
border-width: 0;
border-style: solid;
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
/*border-bottom-width: 1px;*/
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-20 {
margin-top: 5rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-14 {
height: 3.5rem;
}
.h-5 {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.min-h-full {
min-height: 100%;
}
.w-5 {
width: 1.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-auto {
width: auto;
}
.max-w-7xl {
max-width: 80rem;
}
.flex-shrink-0 {
flex-shrink: 0;
}
.flex-col {
flex-direction: column;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.gap-4 {
gap: 1rem;
}
.gap-8 {
gap: 2rem;
}
.border-b {
border-bottom-width: 1px;
}
.border-t {
border-top-width: 1px;
}
.border-slate-100 {
--tw-border-opacity: 1;
border-color: rgb(241 245 249 / var(--tw-border-opacity));
}
.border-slate-200 {
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-8 {
padding: 2rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.px-40 {
padding-left: 10rem;
padding-right: 10rem;
}
.py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.text-wrap {
max-width: 100%;
word-wrap: break-word;
}
.font-bold {
font-weight: 700;
}
.font-semibold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.leading-7 {
line-height: 1.75rem;
}
.text-slate-400 {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
.text-slate-700 {
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
}
.text-slate-900 {
--tw-text-opacity: 1;
color: rgb(15 23 42 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.opacity-50 {
opacity: 0.5;
}
.opacity-25 {
opacity: 0.3;
}
.transition {
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke, opacity, box-shadow, transform,
filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
}
body {
min-height: 100%;
height: 100%;
}
a {
color: inherit;
text-decoration: inherit;
}
.hover\:opacity-100:hover {
opacity: 1;
}
@media (min-width: 640px) {
.sm\:-my-px {
margin-top: -1px;
margin-bottom: -1px;
}
.sm\:ml-6 {
margin-left: 1.5rem;
}
.sm\:flex {
display: flex;
}
.sm\:truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sm\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.sm\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.sm\:tracking-tight {
letter-spacing: -0.025em;
}
}
@media (min-width: 768px) {
.md\:grid {
display: grid;
}
.md\:grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.md\:gap-4 {
gap: 1rem;
}
.md\:p-2 {
padding: 0.5rem;
}
}
@media (min-width: 1024px) {
.lg\:flex {
display: flex;
}
.lg\:px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
}
</style>
</head>
<body>
<div class="min-h-full">
<nav class="border-b border-slate-200 bg-white">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-14 justify-between">
<div class="flex">
<div class="flex flex-shrink-0 items-center">
<a href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-6 w-6"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
</div>
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8"></div>
</div>
</div>
</div>
</nav>
<div class="py-10">
<div
class="mx-auto flex max-w-7xl flex-col items-start justify-center gap-2 px-40"
>
<h1
class="text-2xl leading-7 font-bold text-slate-900 sm:truncate sm:text-3xl sm:tracking-tight"
>
Your workspace is connected to Nx Cloud
</h1>
<div>
<p class="mb-2">You may now close this window.</p>
</div>
</div>
</div>
<footer
class="mt-20 flex border-t border-slate-100 dark:border-slate-800"
>
<nav
role="menu"
aria-labelledby="bottom-navigation"
class="mx-auto flex w-auto max-w-7xl items-center px-4 text-slate-400 dark:text-slate-600"
>
<div class="flex items-center gap-4 p-8 opacity-50">
<a title="Nx Cloud" href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-5 w-5"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
<p class="text-xs transition">&copy; 2024 - Nx Cloud</p>
</div>
<section
class="hidden gap-8 p-8 text-xs opacity-25 transition hover:opacity-100 md:grid md:grid-cols-4 md:gap-4 md:p-2 lg:flex"
>
<a href="https://nx.app/terms" title="Terms of Service"
>Terms of Service</a
><a href="https://nx.app/privacy" title="Privacy Policy"
>Privacy Policy</a
><a
href="https://status.nx.app"
title="Status"
target="_blank"
rel="noopener"
>Status</a
><a
href="https://nx.dev/ci/intro/ci-with-nx?utm_source=nx.app"
title="Docs"
>Docs</a
><a href="mailto:cloud-support@nrwl.io" title="Contact Nx Cloud"
>Contact Nx Cloud</a
><a href="https://nx.dev/pricing?utm_source=nx.app" title="Pricing"
>Pricing</a
><a href="https://nx.dev/company?utm_source=nx.app" title="Company"
>Company</a
><a
href="https://twitter.com/nxdevtools"
title="@NxDevTools"
target="_blank"
rel="noopener"
>@NxDevTools</a
>
</section>
</nav>
</footer>
</div>
</body>
</html>
+432
View File
@@ -0,0 +1,432 @@
<html>
<head>
<title>Nx Cloud login</title>
<style>
*,
:before,
:after {
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family:
ui-sans-serif,
system-ui,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji',
Segoe UI Symbol,
'Noto Color Emoji';
font-feature-settings: normal;
font-variation-settings: normal;
-webkit-tap-highlight-color: transparent;
line-height: inherit;
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
box-sizing: border-box;
border-width: 0;
border-style: solid;
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
/*border-bottom-width: 1px;*/
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-20 {
margin-top: 5rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-14 {
height: 3.5rem;
}
.h-5 {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.min-h-full {
min-height: 100%;
}
.w-5 {
width: 1.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-auto {
width: auto;
}
.max-w-7xl {
max-width: 80rem;
}
.flex-shrink-0 {
flex-shrink: 0;
}
.flex-col {
flex-direction: column;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.gap-4 {
gap: 1rem;
}
.gap-8 {
gap: 2rem;
}
.border-b {
border-bottom-width: 1px;
}
.border-t {
border-top-width: 1px;
}
.border-slate-100 {
--tw-border-opacity: 1;
border-color: rgb(241 245 249 / var(--tw-border-opacity));
}
.border-slate-200 {
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-8 {
padding: 2rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.px-40 {
padding-left: 10rem;
padding-right: 10rem;
}
.py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.font-bold {
font-weight: 700;
}
.font-semibold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.leading-7 {
line-height: 1.75rem;
}
.text-slate-400 {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
.text-slate-700 {
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
}
.text-slate-900 {
--tw-text-opacity: 1;
color: rgb(15 23 42 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.opacity-50 {
opacity: 0.5;
}
.opacity-25 {
opacity: 0.3;
}
.transition {
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke, opacity, box-shadow, transform,
filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
}
body {
min-height: 100%;
height: 100%;
}
a {
color: inherit;
text-decoration: inherit;
}
.hover\:opacity-100:hover {
opacity: 1;
}
@media (min-width: 640px) {
.sm\:-my-px {
margin-top: -1px;
margin-bottom: -1px;
}
.sm\:ml-6 {
margin-left: 1.5rem;
}
.sm\:flex {
display: flex;
}
.sm\:truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sm\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.sm\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.sm\:tracking-tight {
letter-spacing: -0.025em;
}
}
@media (min-width: 768px) {
.md\:grid {
display: grid;
}
.md\:grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.md\:gap-4 {
gap: 1rem;
}
.md\:p-2 {
padding: 0.5rem;
}
}
@media (min-width: 1024px) {
.lg\:flex {
display: flex;
}
.lg\:px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
}
</style>
<script>
function startCountdown() {
let countdownElement = document.getElementById('countdown');
let countdown = 5;
let interval = setInterval(function () {
countdownElement.innerHTML = countdown;
countdown--;
if (countdown < 0) {
clearInterval(interval);
window.location.href = '{{ redirectUrl }}'; // Replace with your redirect URL
}
}, 1000);
}
</script>
</head>
<body onload="startCountdown()">
<div class="min-h-full">
<nav class="border-b border-slate-200 bg-white">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-14 justify-between">
<div class="flex">
<div class="flex flex-shrink-0 items-center">
<a href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-6 w-6"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
</div>
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8"></div>
</div>
</div>
</div>
</nav>
<div class="py-10">
<div
class="mx-auto flex max-w-7xl flex-col items-start justify-center gap-2 px-40"
>
<h1
class="text-2xl leading-7 font-bold text-slate-900 sm:truncate sm:text-3xl sm:tracking-tight"
>
Nx Cloud Login
</h1>
<div>
<p class="mb-2">
You will be redirected to
<a class="font-semibold underline" href="{{ redirectUrl }}"
>Nx Cloud</a
>
in <span id="countdown">5</span> seconds.
</p>
</div>
</div>
</div>
<footer
class="mt-20 flex border-t border-slate-100 dark:border-slate-800"
>
<nav
role="menu"
aria-labelledby="bottom-navigation"
class="mx-auto flex w-auto max-w-7xl items-center px-4 text-slate-400 dark:text-slate-600"
>
<div class="flex items-center gap-4 p-8 opacity-50">
<a title="Nx Cloud" href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-5 w-5"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
<p class="text-xs transition">&copy; 2024 - Nx Cloud</p>
</div>
<section
class="hidden gap-8 p-8 text-xs opacity-25 transition hover:opacity-100 md:grid md:grid-cols-4 md:gap-4 md:p-2 lg:flex"
>
<a href="https://nx.app/terms" title="Terms of Service"
>Terms of Service</a
><a href="https://nx.app/privacy" title="Privacy Policy"
>Privacy Policy</a
><a
href="https://status.nx.app"
title="Status"
target="_blank"
rel="noopener"
>Status</a
><a
href="https://nx.dev/ci/intro/ci-with-nx?utm_source=nx.app"
title="Docs"
>Docs</a
><a href="mailto:cloud-support@nrwl.io" title="Contact Nx Cloud"
>Contact Nx Cloud</a
><a href="https://nx.dev/pricing?utm_source=nx.app" title="Pricing"
>Pricing</a
><a href="https://nx.dev/company?utm_source=nx.app" title="Company"
>Company</a
><a
href="https://twitter.com/nxdevtools"
title="@NxDevTools"
target="_blank"
rel="noopener"
>@NxDevTools</a
>
</section>
</nav>
</footer>
</div>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
1760800828171
+1874
View File
File diff suppressed because it is too large Load Diff
+652
View File
@@ -0,0 +1,652 @@
{
"version": "6.0",
"nxVersion": "18.3.5",
"deps": {
"@changesets/cli": "^2.27.1",
"@nx/devkit": "^18.0.0",
"@nx/eslint-plugin": "^18.0.0",
"@nx/js": "^18.0.0",
"@nx/react": "^18.0.0",
"@nx/react-native": "^18.0.0",
"@nx/workspace": "^18.0.0",
"@react-native/eslint-config": "^0.74.0",
"@react-native/metro-config": "^0.74.0",
"@types/jest": "^29.5.0",
"@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"commitlint": "^18.0.0",
"eslint": "^8.57.0",
"husky": "^8.0.3",
"jest": "^29.5.0",
"lint-staged": "^15.0.0",
"nx": "^18.0.0",
"prettier": "^3.0.0",
"typescript": "^5.3.0"
},
"pathMappings": {
"@core/security": [
"packages/core/security/src/index.ts"
],
"@core/storage": [
"packages/core/storage/src/index.ts"
],
"@core/sync": [
"packages/core/sync/src/index.ts"
],
"@core/policy-client": [
"packages/core/policy-client/src/index.ts"
],
"@core/bff-client": [
"packages/core/bff-client/src/index.ts"
],
"@core/runtime": [
"packages/core/runtime/src/index.ts"
],
"@core/trust": [
"packages/core/trust/src/index.ts"
],
"@core/consent": [
"packages/core/consent/src/index.ts"
],
"@core/analytics": [
"packages/core/analytics/src/index.ts"
],
"@feature-auth/domain": [
"packages/feature-auth/domain/src/index.ts"
],
"@feature-auth/data": [
"packages/feature-auth/data/src/index.ts"
],
"@feature-auth/ui-rn": [
"packages/feature-auth/ui-rn/src/index.ts"
],
"@feature-tasks/domain": [
"packages/feature-tasks/domain/src/index.ts"
],
"@feature-tasks/data": [
"packages/feature-tasks/data/src/index.ts"
],
"@feature-tasks/ui-rn": [
"packages/feature-tasks/ui-rn/src/index.ts"
],
"@feature-messaging/domain": [
"packages/feature-messaging/domain/src/index.ts"
],
"@feature-messaging/data": [
"packages/feature-messaging/data/src/index.ts"
],
"@feature-messaging/ui-rn": [
"packages/feature-messaging/ui-rn/src/index.ts"
],
"@feature-memberships/domain": [
"packages/feature-memberships/domain/src/index.ts"
],
"@feature-memberships/data": [
"packages/feature-memberships/data/src/index.ts"
],
"@feature-memberships/ui-rn": [
"packages/feature-memberships/ui-rn/src/index.ts"
],
"@feature-media/domain": [
"packages/feature-media/domain/src/index.ts"
],
"@feature-media/data": [
"packages/feature-media/data/src/index.ts"
],
"@feature-media/ui-rn": [
"packages/feature-media/ui-rn/src/index.ts"
],
"@feature-location/domain": [
"packages/feature-location/domain/src/index.ts"
],
"@feature-location/data": [
"packages/feature-location/data/src/index.ts"
],
"@feature-location/ui-rn": [
"packages/feature-location/ui-rn/src/index.ts"
],
"@feature-notes/domain": [
"packages/feature-notes/domain/src/index.ts"
],
"@feature-notes/data": [
"packages/feature-notes/data/src/index.ts"
],
"@feature-notes/ui-rn": [
"packages/feature-notes/ui-rn/src/index.ts"
],
"@shared/types": [
"packages/shared/types/src/index.ts"
],
"@shared/ui-kit": [
"packages/shared/ui-kit/src/index.ts"
],
"@shared/config": [
"packages/shared/config/src/index.ts"
]
},
"nxJsonPlugins": [],
"pluginsConfig": {
"@nx/js": {
"analyzeSourceFiles": false
}
},
"fileMap": {
"nonProjectFiles": [
{
"file": ".eslintrc.js",
"hash": "6372876982733906818"
},
{
"file": "best_practices.md",
"hash": "13191109570395651909"
},
{
"file": "package.json",
"hash": "14022645582724659125"
},
{
"file": "pnpm-workspace.yaml",
"hash": "15678249485940398519"
},
{
"file": "nx.json",
"hash": "7190034546379248901"
},
{
"file": "README.md",
"hash": "9564418273127800770"
},
{
"file": "commitlint.config.js",
"hash": "14643968542317944080"
},
{
"file": ".prettierrc",
"hash": "6701623579076507172"
},
{
"file": ".changeset/config.json",
"hash": "5450583423988949661"
},
{
"file": ".gitignore",
"hash": "13404745306227114823"
},
{
"file": ".lintstagedrc.js",
"hash": "9788226683263305028"
},
{
"file": "tsconfig.base.json",
"hash": "26248645546931930"
},
{
"file": "pnpm-lock.yaml",
"hash": "6511353211495792909"
},
{
"file": "packages/feature-auth/README.playbook.md",
"hash": "17685308393363108776"
}
],
"projectFileMap": {
"@feature/messaging/domain": [
{
"file": "packages/feature-messaging/domain/package.json",
"hash": "9875617774836831940"
},
{
"file": "packages/feature-messaging/domain/src/index.ts",
"hash": "8685286682513873922"
}
],
"api-bff": [
{
"file": "apps/api-bff/package.json",
"hash": "14667623210490070355"
},
{
"file": "apps/api-bff/src/config.ts",
"hash": "1666143201087972188"
},
{
"file": "apps/api-bff/src/context.ts",
"hash": "3315328324625214844"
},
{
"file": "apps/api-bff/src/graphql/resolvers.ts",
"hash": "16403994371408522013"
},
{
"file": "apps/api-bff/src/graphql/schema.ts",
"hash": "14257578884273712011"
},
{
"file": "apps/api-bff/src/main.ts",
"hash": "14713350618091080358"
},
{
"file": "apps/api-bff/src/middleware/auth.ts",
"hash": "8220961574387728078"
},
{
"file": "apps/api-bff/src/middleware/dpop.ts",
"hash": "4201954442417082965"
},
{
"file": "apps/api-bff/src/middleware/policy.ts",
"hash": "5236659951017462352"
},
{
"file": "apps/api-bff/src/plugins/rateLimit.ts",
"hash": "8945600931265228754"
},
{
"file": "apps/api-bff/src/plugins/security.ts",
"hash": "6908454775761975436"
},
{
"file": "apps/api-bff/src/shims.d.ts",
"hash": "7971519764566029563"
},
{
"file": "apps/api-bff/src/utils/logger.ts",
"hash": "3008962482417721975"
}
],
"@feature/tasks/data": [
{
"file": "packages/feature-tasks/data/package.json",
"hash": "11899127117492053346"
},
{
"file": "packages/feature-tasks/data/src/index.ts",
"hash": "3225159343067048056"
}
],
"@feature/media/domain": [
{
"file": "packages/feature-media/domain/package.json",
"hash": "17062343893163365254"
},
{
"file": "packages/feature-media/domain/src/index.ts",
"hash": "11464852676641054833"
}
],
"sdk-playground": [
{
"file": "apps/sdk-playground/package.json",
"hash": "326704958530458291",
"deps": [
"@feature/auth/domain",
"@feature/auth/data",
"@feature/auth/ui-rn",
"@feature/tasks/domain",
"@feature/tasks/data",
"@feature/tasks/ui-rn",
"@feature/messaging/domain",
"@feature/messaging/data",
"@feature/messaging/ui-rn",
"@core/security",
"@core/storage",
"@core/sync",
"@core/runtime",
"@core/trust",
"@core/policy-client",
"@shared/ui-kit",
"@shared/config"
]
}
],
"@core/trust": [
{
"file": "packages/core/trust/package.json",
"hash": "11344062427660613690"
},
{
"file": "packages/core/trust/src/index.ts",
"hash": "4685083431920099583"
}
],
"@feature/auth/ui-rn": [
{
"file": "packages/feature-auth/ui-rn/package.json",
"hash": "10455731927735274696"
},
{
"file": "packages/feature-auth/ui-rn/src/index.ts",
"hash": "381949698741574035"
}
],
"@feature/notes/ui-rn": [
{
"file": "packages/feature-notes/ui-rn/package.json",
"hash": "3425145873390375585"
},
{
"file": "packages/feature-notes/ui-rn/src/index.ts",
"hash": "17482866679153039022"
}
],
"@feature/location/ui-rn": [
{
"file": "packages/feature-location/ui-rn/package.json",
"hash": "11710272314659156318"
},
{
"file": "packages/feature-location/ui-rn/src/index.ts",
"hash": "8200514550807411225"
}
],
"@feature/messaging/data": [
{
"file": "packages/feature-messaging/data/package.json",
"hash": "10890954125212475529"
},
{
"file": "packages/feature-messaging/data/src/index.ts",
"hash": "11852960011049571049"
}
],
"@core/analytics": [
{
"file": "packages/core/analytics/package.json",
"hash": "6997073056337771573"
},
{
"file": "packages/core/analytics/src/index.ts",
"hash": "13079790016634135464"
}
],
"@feature/tasks/domain": [
{
"file": "packages/feature-tasks/domain/package.json",
"hash": "7968421340001780022"
},
{
"file": "packages/feature-tasks/domain/src/index.ts",
"hash": "7513693024026576213"
}
],
"@core/storage": [
{
"file": "packages/core/storage/package.json",
"hash": "1852809778144580552",
"deps": [
"@core/security"
]
},
{
"file": "packages/core/storage/src/StorageCore.ts",
"hash": "7146683357452469950"
},
{
"file": "packages/core/storage/src/index.ts",
"hash": "8517838638969559200"
},
{
"file": "packages/core/storage/src/types.ts",
"hash": "2812932207384491835"
}
],
"@feature/location/domain": [
{
"file": "packages/feature-location/domain/package.json",
"hash": "15194052582581122561"
},
{
"file": "packages/feature-location/domain/src/index.ts",
"hash": "3235115917934848004"
}
],
"@feature/notes/domain": [
{
"file": "packages/feature-notes/domain/package.json",
"hash": "2781267393011564746"
},
{
"file": "packages/feature-notes/domain/src/index.ts",
"hash": "15540426896796287860"
}
],
"@shared/ui-kit": [
{
"file": "packages/shared/ui-kit/package.json",
"hash": "361889283475743605"
},
{
"file": "packages/shared/ui-kit/src/index.ts",
"hash": "1495522589135463161"
}
],
"@core/security": [
{
"file": "packages/core/security/package.json",
"hash": "8924048311028988599"
},
{
"file": "packages/core/security/src/DPoPService.ts",
"hash": "10390908045962685343"
},
{
"file": "packages/core/security/src/SecurityCore.ts",
"hash": "3826594692922136891"
},
{
"file": "packages/core/security/src/index.ts",
"hash": "596490254292345753"
},
{
"file": "packages/core/security/src/types.ts",
"hash": "8154128090190173393"
}
],
"@feature/memberships/ui-rn": [
{
"file": "packages/feature-memberships/ui-rn/package.json",
"hash": "3464485720477174187"
},
{
"file": "packages/feature-memberships/ui-rn/src/index.ts",
"hash": "10244998141591208299"
}
],
"@shared/types": [
{
"file": "packages/shared/types/package.json",
"hash": "14468150301333608260"
},
{
"file": "packages/shared/types/src/index.ts",
"hash": "5454463154077490740"
}
],
"@core/sync": [
{
"file": "packages/core/sync/package.json",
"hash": "16260031721964662842"
},
{
"file": "packages/core/sync/src/index.ts",
"hash": "17988048760711089847"
}
],
"@feature/auth/data": [
{
"file": "packages/feature-auth/data/package.json",
"hash": "10771143471172556269"
},
{
"file": "packages/feature-auth/data/src/index.ts",
"hash": "10995026970057222994"
}
],
"lynkedup-pro": [
{
"file": "apps/lynkedup-pro/App.tsx",
"hash": "9844630877106829463"
},
{
"file": "apps/lynkedup-pro/package.json",
"hash": "13599407938796017664",
"deps": [
"@feature/auth/ui-rn",
"@feature/tasks/ui-rn",
"@feature/messaging/ui-rn",
"@feature/memberships/ui-rn",
"@feature/media/ui-rn",
"@feature/location/ui-rn",
"@feature/notes/ui-rn",
"@core/security",
"@core/storage",
"@core/sync",
"@core/runtime",
"@core/trust",
"@shared/ui-kit",
"@shared/config"
]
}
],
"@core/consent": [
{
"file": "packages/core/consent/package.json",
"hash": "2406702405332497792"
},
{
"file": "packages/core/consent/src/index.ts",
"hash": "15398399444077924226"
}
],
"@core/bff-client": [
{
"file": "packages/core/bff-client/package.json",
"hash": "14191312059114809810"
},
{
"file": "packages/core/bff-client/src/index.ts",
"hash": "1963496366619874069"
}
],
"@core/runtime": [
{
"file": "packages/core/runtime/package.json",
"hash": "12029274047704042540"
},
{
"file": "packages/core/runtime/src/index.ts",
"hash": "13435449207607865068"
}
],
"@feature/auth/domain": [
{
"file": "packages/feature-auth/domain/package.json",
"hash": "17800333722898260269"
},
{
"file": "packages/feature-auth/domain/src/entities.ts",
"hash": "628376922343113656"
},
{
"file": "packages/feature-auth/domain/src/index.ts",
"hash": "16373159067630076710"
},
{
"file": "packages/feature-auth/domain/src/interfaces.ts",
"hash": "15907178123305760911"
},
{
"file": "packages/feature-auth/domain/src/usecases/BiometricUseCase.ts",
"hash": "16600743426124629929"
},
{
"file": "packages/feature-auth/domain/src/usecases/LoginUseCase.ts",
"hash": "1002106219325659606"
},
{
"file": "packages/feature-auth/domain/src/usecases/RegistrationUseCase.ts",
"hash": "5953517819967016616"
},
{
"file": "packages/feature-auth/domain/src/usecases/SessionUseCase.ts",
"hash": "15614570693026768161"
}
],
"lynkedup-foundation": [
{
"file": "apps/lynkedup-foundation/App.tsx",
"hash": "17713191757927086337"
},
{
"file": "apps/lynkedup-foundation/package.json",
"hash": "14324450803089748865",
"deps": [
"@core/security",
"@core/storage"
]
}
],
"@core/policy-client": [
{
"file": "packages/core/policy-client/package.json",
"hash": "10097230252047303042"
},
{
"file": "packages/core/policy-client/src/index.ts",
"hash": "7263863394109193832"
}
],
"@feature/messaging/ui-rn": [
{
"file": "packages/feature-messaging/ui-rn/package.json",
"hash": "17304427166648939030"
},
{
"file": "packages/feature-messaging/ui-rn/src/index.ts",
"hash": "3944964343452623300"
}
],
"@feature/tasks/ui-rn": [
{
"file": "packages/feature-tasks/ui-rn/package.json",
"hash": "13268231782288366417"
},
{
"file": "packages/feature-tasks/ui-rn/src/index.ts",
"hash": "13401205232392578550"
}
],
"@feature/memberships/domain": [
{
"file": "packages/feature-memberships/domain/package.json",
"hash": "2043205501934190150"
},
{
"file": "packages/feature-memberships/domain/src/index.ts",
"hash": "16892346130382263542"
}
],
"@feature/media/ui-rn": [
{
"file": "packages/feature-media/ui-rn/package.json",
"hash": "16525178962787410060"
},
{
"file": "packages/feature-media/ui-rn/src/index.ts",
"hash": "3244589877537068955"
}
],
"@shared/config": [
{
"file": "packages/shared/config/package.json",
"hash": "13578451786421307272"
},
{
"file": "packages/shared/config/src/index.ts",
"hash": "5914740374241226574"
}
]
}
}
}
+1
View File
@@ -0,0 +1 @@
6256108439935025365
BIN
View File
Binary file not shown.
+19085
View File
File diff suppressed because it is too large Load Diff
+20249
View File
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
{
"run": {
"command": "nx test",
"startTime": "2025-10-18T15:21:14.003Z",
"endTime": "2025-10-18T15:23:23.778Z",
"inner": false
},
"tasks": [
{
"taskId": "@core/security:test",
"target": "test",
"projectName": "@core/security",
"hash": "1225338222049529083",
"startTime": "2025-10-18T15:21:14.023Z",
"endTime": "2025-10-18T15:23:23.776Z",
"params": "",
"cacheStatus": "cache-miss",
"status": 1
}
]
}
+387
View File
@@ -0,0 +1,387 @@
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:20288) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:19756) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:2060) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:22064) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:2760) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:22576) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:23904) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:6360) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:24972) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:18144) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:22380) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:26016) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:27040) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:10432) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:28300) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:24616) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:28972) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
> nx run @core/security:test
(node:29648) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/security@1.0.0 test
> nx test
'nx' is not recognized as an internal or external command,
operable program or batch file.
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/security failed
Failed tasks:
- @core/security:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\security
npm error workspace @core/security@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\security
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
+332
View File
@@ -0,0 +1,332 @@
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:11848) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:15860) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:16268) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:16760) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:18132) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:18608) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:19152) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:20196) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:9396) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:20860) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:22016) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:13124) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:22572) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:23832) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:24356) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:24900) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:17772) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:22000) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:25924) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:26972) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:27504) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:28264) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:25212) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
> nx run @feature/auth/domain:test
(node:28936) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @feature/auth/domain@1.0.0 test
> nx test
'nx' is not recognized as an internal or external command,
operable program or batch file.
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
 NX  Running target test for project @feature/auth/domain failed
Failed tasks:
- @feature/auth/domain:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
+347
View File
@@ -0,0 +1,347 @@
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:17196) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:22152) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:22424) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:22784) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:23976) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:23584) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:25040) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:17124) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:25652) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:26012) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:27108) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:26728) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:28392) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:21808) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:29388) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
> nx run @core/storage:test
(node:29336) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
> @core/storage@1.0.0 test
> nx test
'nx' is not recognized as an internal or external command,
operable program or batch file.
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
 NX  Running target test for project @core/storage failed
Failed tasks:
- @core/storage:test
Hint: run the command with --verbose for more details.
 NX  Nx Cloud encountered some problems
Invalid Credentials (CI Access Token): A workspace could not be found with the provided CI Access Token. (code: 401)
npm error Lifecycle script `test` failed with error:
npm error code 1
npm error path D:\lynkedup-monorepo\packages\core\storage
npm error workspace @core/storage@1.0.0
npm error location D:\lynkedup-monorepo\packages\core\storage
npm error command failed
npm error command C:\Windows\system32\cmd.exe /d /s /c nx test
+12
View File
@@ -0,0 +1,12 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"endOfLine": "lf",
"arrowParens": "avoid",
"bracketSpacing": true,
"bracketSameLine": false
}
+203
View File
@@ -0,0 +1,203 @@
# LynkedUp Platform
> Mobile-first SDK-based application suite with enterprise-grade security and offline-first capabilities
[![CI Status](https://github.com/lynkedup/monorepo/workflows/CI/badge.svg)](https://github.com/lynkedup/monorepo/actions)
[![License](https://img.shields.io/badge/License-Proprietary-red.svg)](LICENSE)
## 🏗️ Architecture Overview
LynkedUp is built as a **PNPM monorepo** with **Nx orchestration**, featuring:
- **📱 Mobile-First**: React Native applications with native security integrations
- **🔐 Security by Default**: Hardware-backed cryptography, DPoP, SQLCipher encryption
- **📴 Offline-First**: 100% functional offline with conflict-free synchronization
- **🎯 SDK-First Modularity**: Independent, composable SDKs with strict boundaries
- **🛡️ Policy-Aware**: Fine-grained ABAC via Permit.io/OPA
- **🏢 Multi-Tenant**: Organization-level encryption keys and data isolation
```mermaid
graph TD
A[LynkedUp Pro App] --> B[Feature SDKs]
A --> C[Core SDKs]
D[LynkedUp Foundation] --> B
D --> C
B --> E[@feature/auth<br/>@feature/tasks<br/>@feature/messaging]
C --> F[@core/security<br/>@core/storage<br/>@core/sync<br/>@core/policy]
F --> G[Native Layer<br/>SQLCipher • Secure Enclave • StrongBox]
C --> H[GraphQL BFF<br/>Node.js • Permit.io • PostgreSQL]
```
## 🚀 Quick Start
### Prerequisites
- Node.js 18+
- PNPM 8+
- React Native development environment
- Xcode (iOS) / Android Studio (Android)
### Installation
```bash
# Clone and install dependencies
git clone https://github.com/lynkedup/monorepo.git
cd lynkedup-monorepo
pnpm install
# Initialize development environment
pnpm nx run-many -t build
```
### Development
```bash
# Start SDK playground for development
pnpm dev:playground
# Start LynkedUp Pro app
pnpm dev:pro
# Run tests across all packages
pnpm test
# Run only affected tests (recommended)
pnpm affected:test
```
## 📦 Package Structure
```
lynkedup-monorepo/
├── apps/
│ ├── lynkedup-pro/ # Primary React Native app
│ ├── lynkedup-foundation/ # Foundation variant
│ ├── api-bff/ # Node.js GraphQL BFF
│ └── sdk-playground/ # SDK development sandbox
├── packages/
│ ├── core/ # Tier 0: Infrastructure SDKs
│ │ ├── security/ # Hardware-backed crypto, DPoP
│ │ ├── storage/ # Encrypted RxDB/SQLCipher
│ │ ├── sync/ # Offline-first synchronization
│ │ ├── policy-client/ # ABAC policy evaluation
│ │ └── trust/ # Device posture & risk assessment
│ ├── feature-auth/ # Tier 1: Authentication
│ │ ├── domain/ # Pure business logic
│ │ ├── data/ # Repository implementations
│ │ └── ui-rn/ # React Native components
│ ├── feature-tasks/ # Task & project management
│ ├── feature-messaging/ # Unified messaging backbone
│ └── shared/ # Common utilities & types
└── tooling/ # Development tools & mocks
```
## 🔐 Security Features
- **Hardware-Backed Keys**: iOS Secure Enclave & Android StrongBox
- **DPoP Authentication**: RFC 9449 sender-constrained tokens
- **Contextual Encryption**: Organization-specific data encryption keys
- **Cryptographic Erasure**: Remote data destruction via key deletion
- **Device Attestation**: Apple DeviceCheck & Play Integrity integration
- **Policy-Driven Access**: Real-time ABAC enforcement
## 📴 Offline Capabilities
- **Local-First Storage**: Encrypted SQLCipher with reactive queries
- **Durable Outbox Pattern**: Reliable offline mutation queuing
- **CRDT Synchronization**: Conflict-free collaborative data
- **Optimistic UI**: Immediate feedback with eventual consistency
- **Policy Caching**: Local ABAC evaluation with server enforcement
## 🛠️ Development Workflow
### Module Boundaries
The monorepo enforces strict architectural boundaries via ESLint rules:
- **Domain Purity**: Domain layers cannot import infrastructure
- **Vertical Isolation**: Features cannot depend on other features
- **Layered Dependencies**: UI → Data → Domain → Shared
### SDK Development
Each SDK follows clean architecture principles:
1. **Domain Layer**: Pure TypeScript business logic
2. **Data Layer**: Infrastructure adapters (RxDB, GraphQL, native modules)
3. **UI Layer**: React Native components and screens
See individual SDK playbooks in `packages/*/README.playbook.md`.
### Testing Strategy
- **Unit Tests**: High coverage for business logic (Jest)
- **Contract Tests**: GraphQL schema compliance (MSW)
- **Integration Tests**: Cross-SDK interactions
- **E2E Tests**: Complete user flows (Detox)
## 📋 Available Scripts
```bash
# Development
pnpm dev:playground # SDK development sandbox
pnpm dev:pro # LynkedUp Pro app
pnpm dev:foundation # LynkedUp Foundation app
# Quality Assurance
pnpm build # Build all packages
pnpm test # Run all tests
pnpm lint # Lint all packages
pnpm typecheck # TypeScript validation
# Affected Operations (CI/CD)
pnpm affected:build # Build affected packages
pnpm affected:test # Test affected packages
pnpm affected:lint # Lint affected packages
# Release Management
pnpm changeset # Create changeset
pnpm changeset:version # Bump versions
pnpm changeset:publish # Publish to NPM
```
## 🚢 Release Management
This monorepo uses [Changesets](https://github.com/changesets/changesets) for versioning and publishing:
1. **Create Changeset**: `pnpm changeset`
2. **Version Bump**: `pnpm changeset:version`
3. **Publish**: `pnpm changeset:publish`
Only SDK packages are published to NPM. Applications are deployment artifacts.
## 🧪 CI/CD Pipeline
- **SLSA Level 3**: Supply chain security with signed provenance
- **Nx Cloud**: Remote caching for optimal build performance
- **Affected Testing**: Only test/build changed packages
- **Semantic Versioning**: Automated version management
- **Security Scanning**: Dependency and code vulnerability checks
## 📚 Documentation
- **Architecture**: [docs/architecture.md](docs/architecture.md)
- **Security Model**: [docs/security.md](docs/security.md)
- **SDK Playbooks**: `packages/*/README.playbook.md`
- **API Reference**: Generated from TypeScript types
- **GraphQL Schema**: `apps/api-bff/schema.graphql`
## 🤝 Contributing
1. **Create Feature Branch**: `git checkout -b feat/scope-description`
2. **Follow Conventions**: Conventional Commits with proper scopes
3. **Add Changeset**: `pnpm changeset` for public API changes
4. **Quality Gates**: Pre-commit hooks ensure code quality
5. **Pull Request**: Title should match commit convention
## 📄 License
Copyright (c) 2024 LynkedUp Platform. All rights reserved.
This software is proprietary and confidential. Unauthorized copying, distribution, or use is strictly prohibited.
+3
View File
@@ -0,0 +1,3 @@
{
"cases": []
}
+69
View File
@@ -0,0 +1,69 @@
{
"name": "api-bff",
"version": "1.0.0",
"private": true,
"description": "LynkedUp GraphQL Backend for Frontend (BFF)",
"license": "ISC",
"author": "",
"type": "module",
"main": "src/main.ts",
"scripts": {
"build": "tsc",
"start": "node src/main.ts",
"dev": "tsx watch src/main.ts",
"test": "jest",
"lint": "eslint src --ext .ts",
"typecheck": "tsc --noEmit",
"codegen": "graphql-codegen --config codegen.ts",
"db:migrate": "prisma migrate dev",
"db:generate": "prisma generate",
"db:seed": "tsx src/database/seed.ts"
},
"dependencies": {
"@apollo/server": "^4.9.5",
"@as-integrations/fastify": "^2.1.1",
"@fastify/cors": "^8.4.0",
"@fastify/helmet": "^11.1.1",
"@fastify/rate-limit": "^9.0.1",
"@graphql-tools/schema": "^10.0.0",
"@open-policy-agent/opa": "^2.0.0",
"@prisma/client": "^5.6.0",
"@types/express": "^5.0.6",
"axios": "^1.13.2",
"bcrypt": "^5.1.1",
"dataloader": "^2.2.2",
"express": "^5.2.1",
"fastify": "^4.24.3",
"graphql": "^16.8.1",
"graphql-scalars": "^1.22.4",
"jsonwebtoken": "^9.0.2",
"pino": "^8.17.0",
"redis": "^4.6.10",
"uuid": "^9.0.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/typescript": "^4.0.1",
"@graphql-codegen/typescript-resolvers": "^4.0.1",
"@types/bcrypt": "^5.0.2",
"@types/jsonwebtoken": "^9.0.5",
"@types/node": "^20.9.0",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"eslint": "^8.54.0",
"jest": "^29.7.0",
"prisma": "^5.6.0",
"ts-jest": "^29.1.1",
"tsx": "^4.4.0",
"typescript": "^5.2.2"
},
"nx": {
"tags": [
"scope:app",
"type:api",
"platform:node"
]
}
}
+8
View File
@@ -0,0 +1,8 @@
export const config = {
env: (process && process.env && process.env.NODE_ENV) || 'development',
port: Number(process?.env?.PORT) || 4000,
host: process?.env?.HOST || '0.0.0.0',
version: '0.0.0',
cors: { allowedOrigins: ['*'] },
permitio: { pdpUrl: process?.env?.PERMIT_PDP_URL || '', apiKey: process?.env?.PERMIT_API_KEY || '' }
};
+5
View File
@@ -0,0 +1,5 @@
export type Context = any;
export function createContext({ request, reply }: { request?: any; reply?: any }): Context {
return { request, reply } as Context;
}
+5
View File
@@ -0,0 +1,5 @@
export const resolvers = {
Query: {
_empty: () => 'ok'
}
};
+3
View File
@@ -0,0 +1,3 @@
export const typeDefs = `
type Query { _empty: String }
`;
+9
View File
@@ -0,0 +1,9 @@
import express from "express";
import projectsRouter from "./routes/projects";
const app = express();
app.use(express.json());
app.use("/api", projectsRouter);
app.listen(3000, () => console.log("Server running on http://localhost:3000"));
+6
View File
@@ -0,0 +1,6 @@
export const authMiddleware = async (request: any, reply: any) => {
// stub: authenticate request and attach `user` to request in real implementation
request.user = request.user || { sub: 'anonymous' };
};
export default authMiddleware;
+5
View File
@@ -0,0 +1,5 @@
export const dpopMiddleware = async (request: any, reply: any) => {
// stub: validate DPoP headers in real implementation
};
export default dpopMiddleware;
+6
View File
@@ -0,0 +1,6 @@
export const policyMiddleware = async (request: any, reply: any) => {
// stub: evaluate ABAC policies; attach decisions to request
request.policy = { allowed: true };
};
export default policyMiddleware;
@@ -0,0 +1,57 @@
import { Request, Response, NextFunction } from "express";
import { checkAccess } from "../services/authz";
type CrudAction = "create" | "read" | "update" | "delete" | "admin" | "view";
function isNonEmptyString(v: unknown): v is string {
return typeof v === "string" && v.trim().length > 0;
}
export function requireAccess(
getConfig: (req: Request) => {
userId: string;
resourceName: string;
action: CrudAction;
}
) {
return async (req: Request, res: Response, next: NextFunction) => {
try {
const cfg = getConfig(req);
const userId = cfg?.userId;
const resourceName = cfg?.resourceName;
const action = cfg?.action;
// ✅ Validate early (prevents calling OPA with undefined/null)
if (!isNonEmptyString(userId) || !isNonEmptyString(resourceName) || !isNonEmptyString(action)) {
return res.status(400).json({
message: "Missing or invalid authorization inputs",
details: {
userId: userId ?? null,
resourceName: resourceName ?? null,
action: action ?? null,
},
});
}
console.log("AUTHZ INPUT:", { userId, resourceName, action });
// checkAccess MUST build:
// { input: { user: {id:userId}, resource:{name:resourceName}, action } }
const allowed = await checkAccess({ userId, resourceName, action });
console.log("AUTHZ RESULT:", allowed);
if (!allowed) {
return res.status(403).json({ message: "Forbidden: access denied" });
}
return next();
} catch (e: any) {
return res.status(502).json({
message: "Authorization service error",
error: e?.message ?? "Unknown error",
});
}
};
}
+5
View File
@@ -0,0 +1,5 @@
export const rateLimitPlugin = async (server: any, opts: any) => {
// stub: register rate limiting hooks
};
export default rateLimitPlugin;
+5
View File
@@ -0,0 +1,5 @@
export const securityPlugin = async (server: any, opts: any) => {
// stub: set security-related Fastify hooks
};
export default securityPlugin;
+58
View File
@@ -0,0 +1,58 @@
import { Router } from "express";
import { requireAccess } from "../middleware/requireAccess";
const router = Router();
// CREATE (uses payload values)
router.post(
"/projects",
requireAccess((req) => ({
userId: req.body.userId,
resourceName: req.body.resourceName,
action: req.body.action,
})),
async (req, res) => {
res.json({ message: "Project created" });
}
);
// READ (if you still want body-based auth)
router.get(
"/projects/:name",
requireAccess((req) => ({
userId: req.body.userId,
resourceName: req.body.resourceName ?? req.params.name,
action: req.body.action ?? "read",
})),
async (req, res) => {
res.json({ name: req.params.name });
}
);
// UPDATE (body-based)
router.put(
"/projects/:name",
requireAccess((req) => ({
userId: req.body.userId,
resourceName: req.body.resourceName ?? req.params.name,
action: req.body.action ?? "update",
})),
async (req, res) => {
res.json({ message: "Project updated" });
}
);
// DELETE (body-based)
router.delete(
"/projects/:name",
requireAccess((req) => ({
userId: req.body.userId,
resourceName: req.body.resourceName ?? req.params.name,
action: req.body.action ?? "delete",
})),
async (req, res) => {
res.json({ message: "Project deleted" });
}
);
export default router;
+15
View File
@@ -0,0 +1,15 @@
import { opaAllow } from "./opaClient";
export async function checkAccess(params: {
userId: string;
resourceName: string;
action: string;
}): Promise<boolean> {
return opaAllow({
input: {
user: { id: params.userId },
resource: { name: params.resourceName },
action: params.action,
},
});
}
+16
View File
@@ -0,0 +1,16 @@
import axios from "axios";
import { AccessRequest, AccessResponse } from "../types/authz";
const OPA_URL = "http://64.227.108.180:8182/v1/data/authz/access/allow";
export async function opaAllow(payload: AccessRequest): Promise<boolean> {
console.log("OPA REQUEST:", JSON.stringify(payload, null, 2));
const res = await axios.post<AccessResponse>(OPA_URL, payload, {
headers: { "Content-Type": "application/json" },
timeout: 5000,
});
console.log("OPA RESPONSE:", JSON.stringify(res.data, null, 2));
return Boolean(res.data?.result);
}
+38
View File
@@ -0,0 +1,38 @@
/* Minimal external module shims for static analysis. Keep these permissive. */
declare module 'fastify' {
const Fastify: any;
export type FastifyInstance = any;
export default Fastify;
}
declare module '@apollo/server' {
export class ApolloServer<T = any> {
constructor(options?: any);
start?(): Promise<void>;
stop?(): Promise<void>;
}
}
declare module '@as-integrations/fastify' {
const fastifyApollo: any;
export default fastifyApollo;
export const fastifyApolloDrainPlugin: any;
}
declare module '@apollo/server-plugin-landing-page-local-default' {
export const ApolloServerPluginLandingPageLocalDefault: any;
}
declare module '@graphql-tools/schema' {
export function makeExecutableSchema(...args: any[]): any;
}
declare module '@permitio/permit-node' {
export class Permit { constructor(opts?: any); check(...args: any[]): Promise<any>; }
}
declare module '@fastify/cors';
declare module '@fastify/helmet';
declare var process: any;
+12
View File
@@ -0,0 +1,12 @@
package permission
import data.role_permissions
default allow := false
allow if {
some role in input.subject.roles
some permission in role_permissions[role]
permission.action == input.action
permission.object == input.object
}
+7
View File
@@ -0,0 +1,7 @@
{
"subject": {
"roles": [
"admin"
]
}
}
+11
View File
@@ -0,0 +1,11 @@
export interface AccessRequest {
input: {
user: { id: string };
resource: { name: string };
action: string; // "admin" | "view" | "read" | "create" | etc.
};
}
export interface AccessResponse {
result: boolean;
}
+1
View File
@@ -0,0 +1 @@
export const logger = console;
+248
View File
@@ -0,0 +1,248 @@
# 📘 Project Best Practices
## 1. Project Purpose
LynkedUp is a mobile-first, SDK-driven application suite with enterprise-grade security and offline-first capabilities. It is structured as a PNPM monorepo orchestrated by Nx, providing modular Core SDKs (security, storage, sync, policy, trust) and Feature SDKs (auth, tasks, messaging, etc.) consumed by React Native apps and a Node.js GraphQL BFF.
## 2. Project Structure
- Monorepo
- apps/
- lynkedup-pro/ and lynkedup-foundation/: React Native apps demonstrating SDK composition.
- api-bff/: Node.js Fastify + Apollo GraphQL Backend For Frontend.
- sdk-playground/: Development sandbox for SDKs.
- packages/
- core/: Tier-0 infrastructure SDKs (e.g., security, storage, sync, policy-client, runtime, trust).# 📘 Project Best Practices
## 1. Project Purpose
LynkedUp is a mobile-first, SDK-driven application suite with enterprise-grade security and offline-first capabilities. It is structured as a PNPM monorepo orchestrated by Nx, providing modular Core SDKs (security, storage, sync, policy, trust) and Feature SDKs (auth, tasks, messaging, etc.) consumed by React Native apps and a Node.js GraphQL BFF.
## 2. Project Structure
- Monorepo
- apps/
- lynkedup-pro/ and lynkedup-foundation/: React Native apps demonstrating SDK composition.
- api-bff/: Node.js Fastify + Apollo GraphQL Backend For Frontend.
- sdk-playground/: Development sandbox for SDKs.
- packages/
- core/: Tier-0 infrastructure SDKs (e.g., security, storage, sync, policy-client, runtime, trust).
- feature-*/: Tier-1 feature SDKs following clean architecture (domain, data, ui-rn).
- shared/: Common types, config, and UI kit.
- Tooling & Config: Nx, ESLint, Prettier, Changesets, Commitlint.
- Separation of concerns (Clean Architecture conventions)
- Feature SDKs:
- domain/: Pure business logic (use cases, entities, interfaces). No platform or infra dependencies.
- data/: Repositories/adapters that implement domain interfaces and talk to core SDKs and BFF.
- ui-rn/: React Native components and navigation.
- Core SDKs provide foundational services (e.g., SecurityCore, StorageCore) that feature data layers depend on.
- Apps initialize and compose SDKs; they own configuration and feature toggles.
- Entry points & configuration
- apps/api-bff/src/main.ts: Fastify server + Apollo schema wiring and middleware registration.
- apps/*/App.tsx: SDK initialization sequence (Security → Storage → Sync → Runtime → Trust) and navigation bootstrapping.
- packages/*/src/index.ts: Barrel files re-exporting public API for each package.
- tsconfig.base.json: Strict TypeScript with path aliases for all packages.
## 3. Test Strategy
- Framework: Jest (Nx managed). Use per-package unit tests with co-located *.spec.ts(x) files.
- Suggested organization (based on architecture):
- Domain layer: Unit tests for use cases (pure, no I/O). Mock via interfaces.
- Data layer: Contract tests for GraphQL and network using MSW; integration tests with core SDKs.
- Core SDKs: Unit tests for deterministic logic; integration tests for cross-SDK interactions.
- Apps: E2E tests with Detox for key flows.
- Mocking guidelines:
- Mock via domain interfaces (e.g., IAuthRepository, ITrustRepository) rather than concrete classes.
- For GraphQL, prefer MSW to mock network boundaries rather than stubbing internals.
- Use dependency injection to pass fakes/mocks into use cases.
- Coverage expectations:
- Aim high on domain logic (>90%).
- Maintain pragmatic coverage for data/adapters; prefer integration and contract tests.
- CI:
- Use nx affected:test for efficient runs.
## 4. Code Style
- Languages & typing
- TypeScript with strict mode enabled. Prefer precise types and interfaces over any.
- Public APIs should have explicit return types (ESLint warns on missing types).
- Favor async/await over promise chains; avoid top-level side effects.
- Naming conventions
- Classes: PascalCase (e.g., SecurityCore, LoginUseCase).
- Functions/variables: camelCase.
- Files: index.ts as package barrels; core classes often use PascalCase file names (e.g., SecurityCore.ts). Keep barrels aligned with actual exports.
- Packages follow scopes (@core/*, @feature-*/domain|data|ui-rn, @shared/*).
- Formatting
- Prettier: singleQuote, semi, printWidth 100, arrowParens avoid, LF line endings.
- Enforced via lint-staged on staged files.
- Lint rules & boundaries
- ESLint: no-unused-vars (ignore args prefixed with _), explicit-function-return-type warn.
- Module boundaries via @nx/enforce-module-boundaries with tags:
- type:domain → only depend on [type:domain, type:types, scope:shared].
- type:data → depend on [type:domain, type:types, scope:core, scope:shared].
- type:ui → depend on [type:data, type:domain, type:types, scope:shared].
- scope:feature cannot depend on other scope:feature.
- scope:core only depends on [scope:core, scope:shared, type:types].
- platform:shared cannot depend on platform:rn or platform:node.
- Ensure each Nx library is properly tagged to satisfy these constraints.
- Documentation & comments
- Use concise JSDoc for public APIs and to mark FRD references (e.g., F.SC.004).
- Map errors to user-friendly codes/messages at boundaries (see LoginUseCase.handleLoginError).
- Error handling
- Guard methods with ensureInitialized() where applicable (e.g., SecurityCore, StorageCore).
- On server, do not expose internals in production (see BFF formatError).
## 5. Common Patterns
- Clean Architecture layering (UI → Data → Domain → Shared Types) and dependency inversion via interfaces.
- SDK initialization order in apps: Security → Storage → Sync → Runtime → Trust → Feature SDKs.
- Barrel exports (index.ts) per package for a stable public surface.
- GraphQL BFF:
- Fastify plugins for security (helmet, cors) and custom plugins (security, rateLimit).
- Middleware order: DPoP → Auth → Policy (ABAC) before GraphQL handler.
- Dynamic imports for optional dependencies (e.g., Permit.io client).
- Security & cryptography
- Hardware-backed keys, DPoP proof generation, envelope encryption with organizational DEKs.
- Cryptographic erasure and secure wipe via key management.
- Offline-first storage
- Encrypted local DB, schema registry, selective purge by organization, re-keying (planned).
## 6. Do's and Don'ts
- Do
- Initialize core SDKs in the documented order before feature initialization.
- Keep domain logic pure and free from platform or network code.
- Depend on interfaces in domain; implement in data with adapters to core SDKs/BFF.
- Use path aliases from tsconfig.base.json; export public API via index.ts.
- Respect ESLint module boundaries and Nx tags; add proper library tags when creating new packages.
- Map server errors to safe messages in production; log full details server-side only.
- Use MSW for network contract tests; keep unit tests fast and deterministic.
- Follow Conventional Commits with configured scopes and the additional `security` type.
- Keep barrel files accurate and synchronized with actual implementation files.
- Don't
- Import across features (no feature-to-feature dependencies).
- Make domain depend on data/core/platform code.
- Bypass ensureInitialized guards in core SDKs.
- Expose stack traces or sensitive details to clients in production.
- Hardcode secrets or environment-specific values; use config and env vars.
- Introduce Node-specific APIs into React Native code paths.
## 7. Tools & Dependencies
- Tooling
- PNPM workspaces + Nx orchestration (caching, affected commands).
- ESLint + Prettier + lint-staged; commitlint with conventional commits.
- Changesets for versioning and publishing (SDK packages only).
- Key libraries
- Apps: React Native, React Navigation.
- BFF: Fastify, @apollo/server, @graphql-tools/schema, @fastify/cors, @fastify/helmet, optional Permit.io.
- Core SDKs: Security (DPoP, key management, encryption), Storage (encrypted DB, schema registry), Sync/Runtime/Trust (per architecture).
- Setup
- Install: pnpm install; build: pnpm nx run-many -t build.
- Dev scripts: dev:playground, dev:pro, dev:foundation.
- Tests: pnpm test or pnpm affected:test.
- BFF env vars: NODE_ENV, PORT (default 4000), HOST (default 0.0.0.0), PERMIT_PDP_URL, PERMIT_API_KEY.
- Separation of concerns (Clean Architecture conventions)
- Feature SDKs:
- domain/: Pure business logic (use cases, entities, interfaces). No platform or infra dependencies.
- data/: Repositories/adapters that implement domain interfaces and talk to core SDKs and BFF.
- ui-rn/: React Native components and navigation.
- Core SDKs provide foundational services (e.g., SecurityCore, StorageCore) that feature data layers depend on.
- Apps initialize and compose SDKs; they own configuration and feature toggles.
- Entry points & configuration
- apps/api-bff/src/main.ts: Fastify server + Apollo schema wiring and middleware registration.
- apps/*/App.tsx: SDK initialization sequence (Security → Storage → Sync → Runtime → Trust) and navigation bootstrapping.
- packages/*/src/index.ts: Barrel files re-exporting public API for each package.
- tsconfig.base.json: Strict TypeScript with path aliases for all packages.
## 3. Test Strategy
- Framework: Jest (Nx managed). Use per-package unit tests with co-located *.spec.ts(x) files.
- Suggested organization (based on architecture):
- Domain layer: Unit tests for use cases (pure, no I/O). Mock via interfaces.
- Data layer: Contract tests for GraphQL and network using MSW; integration tests with core SDKs.
- Core SDKs: Unit tests for deterministic logic; integration tests for cross-SDK interactions.
- Apps: E2E tests with Detox for key flows.
- Mocking guidelines:
- Mock via domain interfaces (e.g., IAuthRepository, ITrustRepository) rather than concrete classes.
- For GraphQL, prefer MSW to mock network boundaries rather than stubbing internals.
- Use dependency injection to pass fakes/mocks into use cases.
- Coverage expectations:
- Aim high on domain logic (>90%).
- Maintain pragmatic coverage for data/adapters; prefer integration and contract tests.
- CI:
- Use nx affected:test for efficient runs.
## 4. Code Style
- Languages & typing
- TypeScript with strict mode enabled. Prefer precise types and interfaces over any.
- Public APIs should have explicit return types (ESLint warns on missing types).
- Favor async/await over promise chains; avoid top-level side effects.
- Naming conventions
- Classes: PascalCase (e.g., SecurityCore, LoginUseCase).
- Functions/variables: camelCase.
- Files: index.ts as package barrels; core classes often use PascalCase file names (e.g., SecurityCore.ts). Keep barrels aligned with actual exports.
- Packages follow scopes (@core/*, @feature-*/domain|data|ui-rn, @shared/*).
- Formatting
- Prettier: singleQuote, semi, printWidth 100, arrowParens avoid, LF line endings.
- Enforced via lint-staged on staged files.
- Lint rules & boundaries
- ESLint: no-unused-vars (ignore args prefixed with _), explicit-function-return-type warn.
- Module boundaries via @nx/enforce-module-boundaries with tags:
- type:domain → only depend on [type:domain, type:types, scope:shared].
- type:data → depend on [type:domain, type:types, scope:core, scope:shared].
- type:ui → depend on [type:data, type:domain, type:types, scope:shared].
- scope:feature cannot depend on other scope:feature.
- scope:core only depends on [scope:core, scope:shared, type:types].
- platform:shared cannot depend on platform:rn or platform:node.
- Ensure each Nx library is properly tagged to satisfy these constraints.
- Documentation & comments
- Use concise JSDoc for public APIs and to mark FRD references (e.g., F.SC.004).
- Map errors to user-friendly codes/messages at boundaries (see LoginUseCase.handleLoginError).
- Error handling
- Guard methods with ensureInitialized() where applicable (e.g., SecurityCore, StorageCore).
- On server, do not expose internals in production (see BFF formatError).
## 5. Common Patterns
- Clean Architecture layering (UI → Data → Domain → Shared Types) and dependency inversion via interfaces.
- SDK initialization order in apps: Security → Storage → Sync → Runtime → Trust → Feature SDKs.
- Barrel exports (index.ts) per package for a stable public surface.
- GraphQL BFF:
- Fastify plugins for security (helmet, cors) and custom plugins (security, rateLimit).
- Middleware order: DPoP → Auth → Policy (ABAC) before GraphQL handler.
- Dynamic imports for optional dependencies (e.g., Permit.io client).
- Security & cryptography
- Hardware-backed keys, DPoP proof generation, envelope encryption with organizational DEKs.
- Cryptographic erasure and secure wipe via key management.
- Offline-first storage
- Encrypted local DB, schema registry, selective purge by organization, re-keying (planned).
## 6. Do's and Don'ts
- Do
- Initialize core SDKs in the documented order before feature initialization.
- Keep domain logic pure and free from platform or network code.
- Depend on interfaces in domain; implement in data with adapters to core SDKs/BFF.
- Use path aliases from tsconfig.base.json; export public API via index.ts.
- Respect ESLint module boundaries and Nx tags; add proper library tags when creating new packages.
- Map server errors to safe messages in production; log full details server-side only.
- Use MSW for network contract tests; keep unit tests fast and deterministic.
- Follow Conventional Commits with configured scopes and the additional `security` type.
- Keep barrel files accurate and synchronized with actual implementation files.
- Don't
- Import across features (no feature-to-feature dependencies).
- Make domain depend on data/core/platform code.
- Bypass ensureInitialized guards in core SDKs.
- Expose stack traces or sensitive details to clients in production.
- Hardcode secrets or environment-specific values; use config and env vars.
- Introduce Node-specific APIs into React Native code paths.
## 7. Tools & Dependencies
- Tooling
- PNPM workspaces + Nx orchestration (caching, affected commands).
- ESLint + Prettier + lint-staged; commitlint with conventional commits.
- Changesets for versioning and publishing (SDK packages only).
- Key libraries
- Apps: React Native, React Navigation.
- BFF: Fastify, @apollo/server, @graphql-tools/schema, @fastify/cors, @fastify/helmet, optional Permit.io.
- Core SDKs: Security (DPoP, key management, encryption), Storage (encrypted DB, schema registry), Sync/Runtime/Trust (per architecture).
- Setup
- Install: pnpm install; build: pnpm nx run-many -t build.
- Dev scripts: dev:playground, dev:pro, dev:foundation.
- Tests: pnpm test or pnpm affected:test.
- BFF env vars: NODE_ENV, PORT (default 4000), HOST (default 0.0.0.0), PERMIT_PDP_URL, PERMIT_API_KEY.
+61
View File
@@ -0,0 +1,61 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test',
'security' // Added for security-related changes
]
],
'scope-enum': [
2,
'always',
[
// Core SDKs
'security',
'storage',
'sync',
'policy',
'bff-client',
'runtime',
'trust',
'consent',
'analytics',
// Feature SDKs
'auth',
'tasks',
'messaging',
'memberships',
'media',
'location',
'notes',
// Apps
'pro-app',
'foundation-app',
'playground',
// Infrastructure
'monorepo',
'ci',
'deps',
'release'
]
],
'subject-case': [2, 'never', ['pascal-case', 'upper-case']],
'subject-max-length': [2, 'always', 72]
}
};
+69
View File
@@ -0,0 +1,69 @@
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"extends": "nx/presets/npm.json",
"tasksRunnerOptions": {
"default": {
"runner": "nx-cloud",
"options": {
"cacheableOperations": ["build", "test", "lint", "typecheck"],
"accessToken": "process.env.NX_CLOUD_ACCESS_TOKEN"
}
}
},
"targetDefaults": {
"build": {
"cache": true,
"dependsOn": ["^build"],
"inputs": ["production", "^production"]
},
"test": {
"cache": true,
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"]
},
"lint": {
"cache": true,
"inputs": [
"default",
"{workspaceRoot}/.eslintrc.js",
"{workspaceRoot}/.eslintignore"
]
},
"typecheck": {
"cache": true,
"inputs": ["default", "^production"]
}
},
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/jest.config.[jt]s",
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/test-setup.[jt]s",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.js"
],
"sharedGlobals": []
},
"generators": {
"@nx/react": {
"application": {
"babel": true
}
},
"@nx/react-native": {
"application": {
"unitTestRunner": "jest"
}
}
},
"release": {
"projects": ["packages/**"],
"changelog": {
"workspaceChangelog": false,
"projectChangelogs": true
}
}
}
+52
View File
@@ -0,0 +1,52 @@
{
"name": "lynkedup-monorepo",
"version": "1.0.0",
"private": true,
"description": "LynkedUp Platform - Mobile-first SDK-based application suite",
"scripts": {
"build": "nx run-many -t build",
"test": "nx run-many -t test",
"lint": "nx run-many -t lint",
"typecheck": "nx run-many -t typecheck",
"affected:build": "nx affected -t build",
"affected:test": "nx affected -t test",
"affected:lint": "nx affected -t lint",
"changeset": "changeset",
"changeset:version": "changeset version",
"changeset:publish": "changeset publish",
"dev:playground": "nx serve sdk-playground",
"dev:pro": "nx start lynkedup-pro",
"dev:foundation": "nx start lynkedup-foundation"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"@nx/devkit": "^18.0.0",
"@nx/eslint-plugin": "^18.0.0",
"@nx/js": "^18.0.0",
"@nx/react": "^18.0.0",
"@nx/react-native": "^18.0.0",
"@nx/workspace": "^18.0.0",
"@react-native/eslint-config": "^0.74.0",
"@react-native/metro-config": "^0.74.0",
"@types/jest": "^29.5.0",
"@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"commitlint": "^18.0.0",
"eslint": "^8.57.0",
"husky": "^8.0.3",
"jest": "^29.5.0",
"lint-staged": "^15.0.0",
"nx": "^18.0.0",
"prettier": "^3.0.0",
"typescript": "^5.3.0"
},
"workspaces": [
"apps/*",
"packages/core/*",
"packages/feature-*",
"packages/shared/*",
"tooling/*"
],
"packageManager": "pnpm@10.18.3+sha512.bbd16e6d7286fd7e01f6b3c0b3c932cda2965c06a908328f74663f10a9aea51f1129eea615134bf992831b009eabe167ecb7008b597f40ff9bc75946aadfb08d"
}
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/analytics",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+1
View File
@@ -0,0 +1 @@
export const AnalyticsCore = {};
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/bff-client",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+1
View File
@@ -0,0 +1 @@
export const BFFClient = {};
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/consent",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+1
View File
@@ -0,0 +1 @@
export const ConsentCore = {};
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/policy-client",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+1
View File
@@ -0,0 +1 @@
export const PolicyClient = {};
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/runtime",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+1
View File
@@ -0,0 +1 @@
export const RuntimeCore = {};
+24
View File
@@ -0,0 +1,24 @@
{
"name": "@core/security",
"version": "1.0.0",
"description": "Core security SDK for hardware-backed cryptography, DPoP, and contextual encryption",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"build": "nx build",
"test": "nx test",
"lint": "nx lint",
"typecheck": "nx typecheck"
},
"dependencies": {
"react-native-keychain": "^8.2.0",
"react-native-crypto-js": "^1.0.0",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/uuid": "^9.0.7"
},
"nx": {
"tags": ["scope:core", "type:infra", "platform:rn"]
}
}
+144
View File
@@ -0,0 +1,144 @@
import { v4 as uuidv4 } from 'uuid';
import type { DPoPProof } from './types';
// Note: This requires a custom Native Module (NativeCryptoModule) capable of
// generating ECC keys in the Secure Enclave and signing data with them.
// This is a placeholder implementation that would need native module integration.
const DPOP_KEY_ALIAS = 'lynkedup.dpop.key.v1';
/**
* DPoP (Demonstrating Proof-of-Possession) Service
* Implements RFC 9449 for sender-constrained access tokens
*
* Features:
* - Hardware-backed ECC key generation
* - JWT signing with private key in secure enclave
* - Request binding via HTTP method and URI
*/
export class DPoPService {
private publicKey: string | null = null;
/**
* Initialize DPoP key pair in secure enclave
* Returns the public key JWK
*/
async initializeKeyPair(): Promise<string> {
if (this.publicKey) return this.publicKey;
// Check if key exists natively using the alias, otherwise generate it
// This would call into a native module
let pubKey = await this.getPublicKeyFromNative(DPOP_KEY_ALIAS);
if (!pubKey) {
pubKey = await this.generateHardwareECCKeyPair(DPOP_KEY_ALIAS);
}
this.publicKey = pubKey;
return pubKey;
}
/**
* Sign a DPoP proof for HTTP request
* @param method HTTP method (GET, POST, etc.)
* @param uri Full request URI
* @param accessToken Optional access token to bind to request
*/
async signProof(method: string, uri: string, accessToken?: string): Promise<string> {
if (!this.publicKey) {
await this.initializeKeyPair();
}
// Construct the DPoP JWT payload (htu, htm, jti, ath)
const payload = {
htm: method, // HTTP Method
htu: uri, // HTTP URI
jti: uuidv4(), // Unique identifier for this proof
iat: Math.floor(Date.now() / 1000), // Issued at time
// Include hash of access token (ath) if present
ath: accessToken ? this.base64url(this.sha256(accessToken)) : undefined,
};
// Sign the JWT using the hardware-backed private key via the native module
const signedJwt = await this.signJWTWithNative(payload, DPOP_KEY_ALIAS);
return signedJwt;
}
/**
* Sign arbitrary data with DPoP key
*/
async signData(data: string): Promise<string> {
if (!this.publicKey) {
await this.initializeKeyPair();
}
const signaturePayload = {
data,
timestamp: Date.now(),
nonce: uuidv4()
};
return this.signJWTWithNative(signaturePayload, DPOP_KEY_ALIAS);
}
/**
* Get the current public key
*/
getPublicKey(): string | null {
return this.publicKey;
}
// Native module integration methods (would be implemented via bridge)
private async getPublicKeyFromNative(keyAlias: string): Promise<string | null> {
// This would call into a native module
// Example: return NativeCryptoModule.getPublicKey(keyAlias);
console.warn('Native module integration required for getPublicKeyFromNative');
return null;
}
private async generateHardwareECCKeyPair(keyAlias: string): Promise<string> {
// This would call into a native module to generate ECC key in secure enclave
// Example: return NativeCryptoModule.generateHardwareECCKeyPair(keyAlias);
console.warn('Native module integration required for generateHardwareECCKeyPair');
// Mock implementation for development
return JSON.stringify({
kty: 'EC',
crv: 'P-256',
x: 'mock-x-coordinate',
y: 'mock-y-coordinate',
use: 'sig',
kid: keyAlias
});
}
private async signJWTWithNative(payload: any, keyAlias: string): Promise<string> {
// This would call into a native module to sign JWT with hardware key
// Example: return NativeCryptoModule.signJWT(payload, keyAlias);
console.warn('Native module integration required for signJWTWithNative');
// Mock implementation for development
const header = { alg: 'ES256', typ: 'dpop+jwt', jwk: JSON.parse(this.publicKey!) };
const encodedHeader = this.base64url(JSON.stringify(header));
const encodedPayload = this.base64url(JSON.stringify(payload));
const signature = 'mock-signature'; // Would be actual signature from secure enclave
return `${encodedHeader}.${encodedPayload}.${signature}`;
}
// Utility methods
private base64url(str: string): string {
return Buffer.from(str)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
private sha256(str: string): string {
// This would use a proper crypto library
console.warn('Proper SHA256 implementation required');
return 'mock-hash';
}
}
+165
View File
@@ -0,0 +1,165 @@
import { DPoPService } from './DPoPService';
import { CryptoService } from './CryptoService';
import { KeyManagementService } from './KeyManagementService';
import type { SecurityConfig, EncryptionResult, KeyReference } from './types';
/**
* Core Security SDK
* Provides hardware-backed cryptography, DPoP implementation, and contextual encryption
*
* Key Features (per FRD):
* - F.SC.001: Cryptographic utilities (AES-GCM envelope encryption)
* - F.SC.002: Hardware-backed key storage (Keychain/StrongBox)
* - F.SC.003: Certificate Pinning logic
* - F.SC.004: DPoP proof generation
* - F.SC.005: Organizational Data Encryption Keys (DEKs) management
* - F.SC.006: Secure wipe/cryptographic erasure
* - F.SC.007: Device attestation integration
*/
export class SecurityCore {
private config: SecurityConfig;
private dpopService: DPoPService;
private cryptoService: CryptoService;
private keyManagement: KeyManagementService;
private initialized = false;
constructor(config: SecurityConfig) {
this.config = config;
this.dpopService = new DPoPService();
this.cryptoService = new CryptoService();
this.keyManagement = new KeyManagementService(config);
}
/**
* Initialize the Security Core
* Must be called before any other operations
*/
async initialize(): Promise<void> {
if (this.initialized) return;
await this.keyManagement.initialize();
await this.dpopService.initializeKeyPair();
this.initialized = true;
}
/**
* F.SC.004: Generate DPoP proof for request authentication
*/
async signDPoPProof(method: string, uri: string, accessToken?: string): Promise<string> {
this.ensureInitialized();
return this.dpopService.signProof(method, uri, accessToken);
}
/**
* F.SC.001: Encrypt data using organizational DEK (envelope encryption)
*/
async encryptForOrganization(data: string, orgId: string): Promise<EncryptionResult> {
this.ensureInitialized();
// Get or create organizational DEK
const orgKeyRef = await this.keyManagement.getOrganizationalKey(orgId);
// Generate random file encryption key
const fileKey = await this.cryptoService.generateKey();
// Encrypt data with file key
const encryptedData = await this.cryptoService.encrypt(data, fileKey);
// Wrap file key with organizational DEK
const wrappedKey = await this.cryptoService.wrapKey(fileKey, orgKeyRef.keyId);
return {
encryptedData: encryptedData.ciphertext,
keyReference: {
keyId: wrappedKey,
orgId,
keyType: 'dek',
createdAt: new Date().toISOString()
},
iv: encryptedData.iv,
authTag: encryptedData.authTag
};
}
/**
* Decrypt data using organizational DEK
*/
async decryptForOrganization(encryptedData: string, keyReference: KeyReference): Promise<string> {
this.ensureInitialized();
if (!keyReference.orgId) {
throw new Error('Organization ID required for decryption');
}
// Get organizational DEK
const orgKeyRef = await this.keyManagement.getOrganizationalKey(keyReference.orgId);
// Unwrap file key
const fileKey = await this.cryptoService.unwrapKey(keyReference.keyId, orgKeyRef.keyId);
// Decrypt data
return this.cryptoService.decrypt(encryptedData, fileKey);
}
/**
* F.SC.002: Get database master key from secure storage
*/
async getDatabaseMasterKey(): Promise<string> {
this.ensureInitialized();
return this.keyManagement.getDatabaseMasterKey();
}
/**
* F.SC.005: Store authentication tokens securely
*/
async storeAuthTokens(accessToken: string, refreshToken: string): Promise<void> {
this.ensureInitialized();
await this.keyManagement.storeSecureValue('auth.access_token', accessToken);
await this.keyManagement.storeSecureValue('auth.refresh_token', refreshToken);
}
/**
* Get stored authentication tokens
*/
async getAuthTokens(): Promise<{ accessToken?: string; refreshToken?: string }> {
this.ensureInitialized();
const [accessToken, refreshToken] = await Promise.all([
this.keyManagement.getSecureValue('auth.access_token'),
this.keyManagement.getSecureValue('auth.refresh_token')
]);
return { accessToken, refreshToken };
}
/**
* F.SC.006: Cryptographic erasure - delete organizational keys
*/
async performCryptographicErasure(orgId: string): Promise<void> {
this.ensureInitialized();
await this.keyManagement.deleteOrganizationalKeys(orgId);
}
/**
* F.SC.006: Complete secure wipe - delete all keys
*/
async performSecureWipe(): Promise<void> {
this.ensureInitialized();
await this.keyManagement.secureWipe();
}
/**
* Sign arbitrary data with identity key
*/
async signData(data: string): Promise<string> {
this.ensureInitialized();
return this.dpopService.signData(data);
}
private ensureInitialized(): void {
if (!this.initialized) {
throw new Error('SecurityCore must be initialized before use');
}
}
}
+11
View File
@@ -0,0 +1,11 @@
export { SecurityCore } from './SecurityCore';
export { DPoPService } from './DPoPService';
export { CryptoService } from './CryptoService';
export { KeyManagementService } from './KeyManagementService';
export type {
SecurityConfig,
DPoPProof,
EncryptionResult,
KeyReference,
SecurityLevel
} from './types';
+39
View File
@@ -0,0 +1,39 @@
export interface SecurityConfig {
enableHardwareBackedStorage: boolean;
requireSecureEnclave: boolean;
enableCertificatePinning: boolean;
allowDebugging: boolean;
}
export interface DPoPProof {
jwt: string;
publicKey: string;
algorithm: string;
}
export interface EncryptionResult {
encryptedData: string;
keyReference: KeyReference;
iv: string;
authTag: string;
}
export interface KeyReference {
keyId: string;
orgId?: string;
keyType: 'master' | 'dek' | 'dpop' | 'identity';
createdAt: string;
}
export enum SecurityLevel {
SOFTWARE = 'software',
SECURE_HARDWARE = 'secure_hardware',
SECURE_ENCLAVE = 'secure_enclave'
}
export interface AttestationResult {
status: 'VALID' | 'INVALID' | 'UNKNOWN';
deviceCheck?: any;
playIntegrity?: any;
timestamp: string;
}
+26
View File
@@ -0,0 +1,26 @@
{
"name": "@core/storage",
"version": "1.0.0",
"description": "Core storage SDK for encrypted RxDB/SQLCipher database management",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"build": "nx build",
"test": "nx test",
"lint": "nx lint",
"typecheck": "nx typecheck"
},
"dependencies": {
"rxdb": "^15.0.0",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@types/node": "^20.0.0"
},
"peerDependencies": {
"@core/security": "workspace:*"
},
"nx": {
"tags": ["scope:core", "type:infra", "platform:rn"]
}
}
+220
View File
@@ -0,0 +1,220 @@
import type { SecurityCore } from '@core/security';
import { DatabaseProvider } from './DatabaseProvider';
import { SchemaRegistry } from './SchemaRegistry';
import type { StorageConfig, CollectionSchema, DatabaseInstance } from './types';
/**
* Core Storage SDK
* Provides encrypted local database management with RxDB/SQLCipher
*
* Key Features (per FRD):
* - F.STC.001: Abstraction layer over RxDB/SQLite with SQLCipher encryption
* - F.STC.002: Schema registration for feature SDKs
* - F.STC.003: Conflict resolution strategies (CRDT configuration, LWW handling)
* - F.STC.004: Encrypted file vault for local media storage
* - F.STC.005: Automated database schema migration
* - F.STC.006: Incremental encryption re-keying
* - F.STC.007: Selective purge mechanisms
*/
export class StorageCore {
private config: StorageConfig;
private securityCore: SecurityCore;
private databaseProvider: DatabaseProvider;
private schemaRegistry: SchemaRegistry;
private initialized = false;
constructor(config: StorageConfig, securityCore: SecurityCore) {
this.config = config;
this.securityCore = securityCore;
this.databaseProvider = new DatabaseProvider(config, securityCore);
this.schemaRegistry = new SchemaRegistry();
}
/**
* F.STC.001: Initialize the storage layer with encryption
*/
async initialize(): Promise<void> {
if (this.initialized) return;
await this.databaseProvider.initialize();
this.initialized = true;
}
/**
* F.STC.002: Register schema for feature SDKs
*/
registerSchema(collectionName: string, schema: CollectionSchema): void {
this.schemaRegistry.register(collectionName, schema);
}
/**
* Get the database instance
*/
getDatabase(): DatabaseInstance {
this.ensureInitialized();
return this.databaseProvider.getInstance();
}
/**
* F.STC.002: Create collection with registered schema
*/
async createCollection(name: string): Promise<void> {
this.ensureInitialized();
const schema = this.schemaRegistry.getSchema(name);
if (!schema) {
throw new Error(`Schema not registered for collection: ${name}`);
}
await this.databaseProvider.createCollection(name, schema);
}
/**
* F.STC.004: Store encrypted file
*/
async storeEncryptedFile(
filename: string,
data: Buffer,
mimeType: string,
orgId?: string
): Promise<string> {
this.ensureInitialized();
// Encrypt file content
const encryptResult = orgId
? await this.securityCore.encryptForOrganization(data.toString('base64'), orgId)
: await this.encryptFileLocally(data);
// Store encrypted file to filesystem
const encryptedPath = await this.writeEncryptedFile(filename, encryptResult.encryptedData);
// Store metadata in database
const fileId = this.generateFileId();
const metadata = {
id: fileId,
filename,
mimeType,
size: data.length,
encryptedPath,
keyReference: JSON.stringify(encryptResult.keyReference),
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
const db = this.getDatabase();
await db.collections.fileVault.insert(metadata);
return fileId;
}
/**
* F.STC.004: Retrieve encrypted file
*/
async retrieveEncryptedFile(fileId: string, orgId?: string): Promise<Buffer> {
this.ensureInitialized();
const db = this.getDatabase();
const metadata = await db.collections.fileVault.findOne(fileId).exec();
if (!metadata) {
throw new Error(`File not found: ${fileId}`);
}
// Read encrypted file
const encryptedData = await this.readEncryptedFile(metadata.encryptedPath);
const keyReference = JSON.parse(metadata.keyReference);
// Decrypt file content
const decryptedData = orgId
? await this.securityCore.decryptForOrganization(encryptedData, keyReference)
: await this.decryptFileLocally(encryptedData, keyReference);
return Buffer.from(decryptedData, 'base64');
}
/**
* F.STC.007: Selective purge by organization
*/
async purgeOrganizationData(orgId: string): Promise<void> {
this.ensureInitialized();
const db = this.getDatabase();
// Find all collections and purge org-specific data
for (const [collectionName, collection] of Object.entries(db.collections)) {
// Remove documents with matching orgId
await collection.find({ orgId }).remove();
}
// Purge encrypted files belonging to organization
const orgFiles = await db.collections.fileVault
.find()
.where('keyReference')
.regex(new RegExp(orgId))
.exec();
for (const file of orgFiles) {
await this.deleteEncryptedFile(file.encryptedPath);
await file.remove();
}
}
/**
* F.STC.006: Re-encrypt data with new keys
*/
async reEncryptData(orgId: string, newKeyReference: any): Promise<void> {
this.ensureInitialized();
// This would implement re-encryption of existing data
// when organizational keys are rotated
console.warn('Re-encryption implementation needed');
}
/**
* Get sync status for collections
*/
getSyncStatus(collectionName: string): any {
this.ensureInitialized();
const db = this.getDatabase();
return db.collections[collectionName]?.find({ syncStatus: 'PENDING' });
}
private async encryptFileLocally(data: Buffer): Promise<any> {
// Implementation would use local encryption for non-org files
throw new Error('Local file encryption not implemented');
}
private async decryptFileLocally(encryptedData: string, keyReference: any): Promise<string> {
// Implementation would use local decryption for non-org files
throw new Error('Local file decryption not implemented');
}
private async writeEncryptedFile(filename: string, encryptedData: string): Promise<string> {
// Implementation would write to secure app documents directory
const path = `/secure/${this.generateFileId()}_${filename}`;
console.warn('File system integration needed');
return path;
}
private async readEncryptedFile(path: string): Promise<string> {
// Implementation would read from secure app documents directory
console.warn('File system integration needed');
return 'mock-encrypted-data';
}
private async deleteEncryptedFile(path: string): Promise<void> {
// Implementation would securely delete file
console.warn('Secure file deletion needed');
}
private generateFileId(): string {
return `file_${Date.now()}_${Math.random().toString(36).substring(2)}`;
}
private ensureInitialized(): void {
if (!this.initialized) {
throw new Error('StorageCore must be initialized before use');
}
}
}
+9
View File
@@ -0,0 +1,9 @@
export { StorageCore } from './StorageCore';
export { DatabaseProvider } from './DatabaseProvider';
export { SchemaRegistry } from './SchemaRegistry';
export type {
StorageConfig,
CollectionSchema,
MigrationStrategy,
ConflictResolutionStrategy
} from './types';
+42
View File
@@ -0,0 +1,42 @@
import type { RxDatabase, RxCollection } from 'rxdb';
export interface StorageConfig {
databaseName: string;
enableEncryption: boolean;
enableCRDT: boolean;
migrationStrategy: 'drop' | 'migrate';
}
export interface CollectionSchema {
version: number;
title: string;
type: 'object';
properties: Record<string, any>;
required?: string[];
indexes?: string[];
migrationStrategies?: Record<number, MigrationStrategy>;
conflictResolution?: ConflictResolutionStrategy;
}
export type MigrationStrategy = (oldDoc: any) => any;
export interface ConflictResolutionStrategy {
type: 'crdt' | 'lww' | 'custom';
resolver?: (conflicts: any[]) => any;
}
export interface DatabaseInstance {
database: RxDatabase;
collections: Record<string, RxCollection>;
}
export interface EncryptedFileMetadata {
id: string;
filename: string;
mimeType: string;
size: number;
encryptedPath: string;
keyReference: string;
createdAt: string;
updatedAt: string;
}
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/sync",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+3
View File
@@ -0,0 +1,3 @@
export const SyncCore = {
// placeholder sync core
};
+7
View File
@@ -0,0 +1,7 @@
{
"name": "@core/trust",
"version": "1.0.0",
"private": true,
"main": "src/index.ts",
"nx": { "tags": ["scope:core","type:infra"] }
}
+1
View File
@@ -0,0 +1 @@
export const TrustCore = {};
+279
View File
@@ -0,0 +1,279 @@
# @feature/auth Playbook
## 1. Overview
Handles Authentication (OTP, Magic Link, Federated), Session Management, and Biometrics with risk-adaptive security.
**Key Features (per FRD):**
- F.ID.001: Login, Registration, and Forgot Password flows
- F.ID.002: Configurable verification (OTP, Email, Magic Links)
- F.ID.003: Secure session token storage and rotation
- F.ID.004: Device biometrics integration (FaceID/TouchID/Android Biometrics)
- F.ID.005: Configurable "Remember Me" duration
- F.ID.006: Enhanced Magic Link security with nonce and expiry
- F.ID.007: Federated Login connectors (Google, Apple)
## 2. Setup & Dependencies
**Required Core SDKs:**
- `@core/security` - DPoP key generation and signing
- `@core/trust` - Runtime Risk Score; triggers Step-Up MFA if score is high
- `@core/policy` - Risk-adaptive policy checks
- `@core/storage` - Encrypted session storage
**Installation:**
```bash
# Install auth feature layers
pnpm add @feature/auth/domain @feature/auth/data @feature/auth/ui-rn
# Peer dependencies (automatically resolved in monorepo)
# @core/security @core/trust @core/policy @core/storage
```
## 3. Core Workflow: DPoP Login and Risk Assessment
```mermaid
sequenceDiagram
participant App
participant Auth as @feature/auth
participant Trust as @core/trust
participant Security as @core/security
participant Policy as @core/policy
participant BFF
App->>Auth: login(credentials)
Auth->>Trust: calculateRiskScore()
Trust-->>Auth: { score: 45, signals: {...} }
Auth->>Security: initializeDPoP()
Security-->>Auth: publicKey
Auth->>BFF: exchangeCredentials(creds, pubKey)
BFF-->>Auth: session + tokens
alt Risk Score > Threshold
Auth->>Policy: check('step-up-mfa', context)
Policy-->>Auth: requires_verification: true
Auth-->>App: { success: true, requiresStepUp: true }
else Low Risk
Auth-->>App: { success: true, session }
end
```
## 4. Integration Points
### @core/security Integration
```typescript
// DPoP key generation and signing
const publicKey = await this.authRepository.initializeDPoP();
const signedProof = await this.securityCore.signDPoPProof('POST', '/auth/login', accessToken);
```
### @core/trust Integration
```typescript
// Risk assessment for adaptive authentication
const { score, signals } = await this.trustRepository.calculateRiskScore();
const requiresStepUp = this.shouldRequireStepUp(score, signals);
```
### @core/policy Integration
```typescript
// Risk-adaptive policy checks
const allowed = await this.policyClient.check('login', 'User', {
riskScore: 60,
deviceSignals: signals
});
```
## 5. Policy Enforcement Examples
**Risk-Adaptive Login:**
```typescript
// Low risk (score < 50): Standard login
await policyClient.check('login', 'User', { riskScore: 35 }); // → true
// Medium risk (50-75): Email verification
await policyClient.check('login', 'User', { riskScore: 65 }); // → requires email MFA
// High risk (75+): OTP + Device attestation
await policyClient.check('login', 'User', { riskScore: 85 }); // → requires OTP + attestation
```
**Organization Access:**
```typescript
// Check organization membership with role-based permissions
await policyClient.check('access-org', 'Organization', {
orgId: 'org-123',
userRole: 'member',
riskScore: 40
});
```
## 6. API Usage Examples
### Basic Login Flow
```typescript
import { LoginUseCase } from '@feature/auth/domain';
import { AuthRepository } from '@feature/auth/data';
const authRepo = new AuthRepository(securityCore, bffClient);
const trustRepo = new TrustRepository(trustCore);
const loginUseCase = new LoginUseCase(authRepo, trustRepo, config);
const result = await loginUseCase.execute({
identifier: 'user@example.com',
password: 'secure_password',
deviceId: 'device-uuid'
});
if (result.success) {
if (result.requiresStepUp) {
// Handle step-up MFA flow
console.log('Additional verification required:', result.verificationMethod);
} else {
// Login successful
console.log('User session:', result.session);
}
}
```
### Biometric Authentication
```typescript
import { BiometricUseCase } from '@feature/auth/domain';
const biometricUseCase = new BiometricUseCase(authRepo, biometricConfig);
const result = await biometricUseCase.authenticate({
promptMessage: 'Authenticate to access LynkedUp',
fallbackToPassword: true
});
```
### Magic Link Flow
```typescript
// Generate magic link
const magicLink = await authRepo.generateMagicLink('user@example.com');
// Verify magic link (typically called from deep link handler)
const result = await loginUseCase.executeWithMagicLink(token, nonce);
```
## 7. Configuration
```typescript
const authConfig: AuthConfig = {
requireEmailVerification: true,
requirePhoneVerification: false,
biometrics: {
enabled: true,
fallbackToPassword: true,
promptMessage: 'Authenticate with LynkedUp'
},
rememberMeDays: 30,
maxLoginAttempts: 5,
lockoutDurationMinutes: 15
};
```
## 8. Error Handling
```typescript
// Standard error codes returned by AuthResult
switch (result.errorCode) {
case 'INVALID_CREDENTIALS':
// Handle invalid login
break;
case 'ACCOUNT_LOCKED':
// Handle account lockout
break;
case 'VERIFICATION_REQUIRED':
// Handle unverified account
break;
case 'DEVICE_NOT_TRUSTED':
// Handle untrusted device
break;
case 'POLICY_VIOLATION':
// Handle policy-based denial
break;
}
```
## 9. Testing Strategy
### Unit Tests
```typescript
// Domain layer testing (LoginUseCase)
describe('LoginUseCase', () => {
it('should require step-up for high risk score', async () => {
mockTrustRepo.calculateRiskScore.mockResolvedValue({ score: 85, signals: {} });
const result = await loginUseCase.execute(validCredentials);
expect(result.requiresStepUp).toBe(true);
});
});
```
### Contract Tests
```typescript
// Data layer testing against mocked BFF
import { setupServer } from 'msw/node';
import { graphql } from 'msw';
const server = setupServer(
graphql.mutation('Login', (req, res, ctx) => {
return res(ctx.data({
login: {
accessToken: 'mock-token',
user: mockUser
}
}));
})
);
```
## 10. Security Notes
**Critical Security Requirements:**
- Private keys MUST remain in the Secure Enclave/TEE
- Magic links MUST enforce nonce and expiry (see F.ID.006)
- DPoP proofs MUST be bound to specific HTTP requests
- Session tokens MUST be stored in hardware-backed keychain
- Step-up MFA triggers MUST be policy-driven, not hardcoded
**Risk Signals Handling:**
- Root/Jailbreak detection → Immediate step-up required
- Device attestation failure → Block access + notify admin
- Geolocation deviation → Email verification required
- New device → SMS OTP required
## 11. Troubleshooting
**Common Issues:**
1. **"SecurityCore must be initialized"**
- Ensure `securityCore.initialize()` is called before auth operations
2. **"DPoP key generation failed"**
- Verify hardware-backed storage is available
- Check device security settings (passcode/biometrics enabled)
3. **"Policy evaluation failed"**
- Verify policy bundles are cached locally
- Check network connectivity for policy updates
4. **Biometric authentication unavailable**
- Verify device biometric enrollment
- Check app permissions for biometric access
## 12. Performance Considerations
- **Key Operations**: DPoP key generation (one-time, ~100ms)
- **Risk Assessment**: Device evaluation (~50-200ms depending on signals)
- **Policy Evaluation**: Local cache lookup (~1-5ms)
- **Session Storage**: Keychain operations (~10-50ms)
**Optimization Tips:**
- Cache risk assessment results for 5-10 minutes
- Pre-warm DPoP keys during app initialization
- Batch policy evaluations when possible
+6
View File
@@ -0,0 +1,6 @@
{
"name": "@feature/auth/data",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
+1
View File
@@ -0,0 +1 @@
export const AuthData = {};
+22
View File
@@ -0,0 +1,22 @@
{
"name": "@feature/auth/domain",
"version": "1.0.0",
"description": "Authentication domain logic - pure business rules and use cases",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"build": "nx build",
"test": "nx test",
"lint": "nx lint",
"typecheck": "nx typecheck"
},
"dependencies": {
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/uuid": "^9.0.7"
},
"nx": {
"tags": ["scope:feature", "type:domain", "platform:shared"]
}
}
@@ -0,0 +1,53 @@
export interface User {
id: string;
email: string;
phoneNumber?: string;
firstName: string;
lastName: string;
isEmailVerified: boolean;
isPhoneVerified: boolean;
createdAt: string;
lastLoginAt?: string;
profilePictureUrl?: string;
organizations: UserOrganization[];
preferences: UserPreferences;
}
export interface UserOrganization {
orgId: string;
orgName: string;
role: string;
permissions: string[];
joinedAt: string;
status: 'active' | 'suspended' | 'pending';
}
export interface UserPreferences {
language: string;
timezone: string;
theme: 'light' | 'dark' | 'system';
notifications: NotificationPreferences;
}
export interface NotificationPreferences {
email: boolean;
push: boolean;
sms: boolean;
marketing: boolean;
}
export interface AuthResult {
success: boolean;
session?: any;
requiresVerification?: boolean;
verificationMethod?: VerificationMethod;
errorCode?: string;
errorMessage?: string;
nextSteps?: string[];
}
export type VerificationMethod =
| { type: 'otp'; target: string }
| { type: 'email'; target: string }
| { type: 'biometric' }
| { type: 'magic_link'; target: string };
+20
View File
@@ -0,0 +1,20 @@
export const AuthDomain = {};
import { LoginUseCase } from './usecases/LoginUseCase';
import { RegistrationUseCase } from './usecases/RegistrationUseCase';
import { SessionUseCase } from './usecases/SessionUseCase';
import { BiometricUseCase } from './usecases/BiometricUseCase';
export { LoginUseCase, RegistrationUseCase, SessionUseCase, BiometricUseCase };
export type {
IAuthRepository,
ITrustRepository,
Credentials,
UserSession,
BiometricConfig,
AuthConfig
} from './interfaces';
export type {
User,
AuthResult,
VerificationMethod
} from './entities';
@@ -0,0 +1,76 @@
import type { User, AuthResult } from './entities';
/**
* Repository interface that the data layer must implement
* Following clean architecture principles - domain defines the contract
*/
export interface IAuthRepository {
// F.ID.004: DPoP initialization
initializeDPoP(): Promise<string>;
// F.ID.001: Login flows
exchangeCredentialsForToken(creds: Credentials, pubKey: string): Promise<UserSession>;
// F.ID.002: Verification flows
sendOTPVerification(phoneNumber: string): Promise<void>;
verifyOTP(phoneNumber: string, code: string): Promise<boolean>;
sendEmailVerification(email: string): Promise<void>;
verifyEmail(email: string, token: string): Promise<boolean>;
// Magic Links (F.ID.006 - Enhanced security)
generateMagicLink(email: string): Promise<string>;
verifyMagicLink(token: string, nonce: string): Promise<UserSession>;
// F.ID.007: Federated login
authenticateWithProvider(provider: 'google' | 'apple', token: string): Promise<UserSession>;
// Session management
storeSession(session: UserSession): Promise<void>;
getSession(): Promise<UserSession | null>;
refreshSession(refreshToken: string): Promise<UserSession>;
revokeSession(): Promise<void>;
// F.ID.005: Remember me functionality
enableRememberMe(duration: number): Promise<void>;
disableRememberMe(): Promise<void>;
}
/**
* Trust/Risk assessment interface
*/
export interface ITrustRepository {
calculateRiskScore(): Promise<{ score: number; signals: Record<string, any> }>;
performDeviceAttestation(): Promise<boolean>;
}
export interface Credentials {
identifier: string; // email or phone
password?: string;
biometricSignature?: string;
deviceId: string;
}
export interface UserSession {
userId: string;
accessToken: string;
refreshToken: string;
expiresAt: string;
user: User;
riskScore?: number;
requiresStepUp?: boolean;
}
export interface BiometricConfig {
enabled: boolean;
fallbackToPassword: boolean;
promptMessage: string;
}
export interface AuthConfig {
requireEmailVerification: boolean;
requirePhoneVerification: boolean;
biometrics: BiometricConfig;
rememberMeDays: number;
maxLoginAttempts: number;
lockoutDurationMinutes: number;
}
@@ -0,0 +1,5 @@
export class BiometricUseCase {
async verify(signature: string) {
return false;
}
}
@@ -0,0 +1,177 @@
import type { IAuthRepository, ITrustRepository, Credentials, UserSession, AuthConfig } from '../interfaces';
import type { AuthResult } from '../entities';
/**
* Login Use Case - Pure business logic
* Orchestrates the login flow including risk assessment and DPoP initialization
*
* Features implemented (per FRD):
* - F.ID.001: Login flows
* - F.ID.004: DPoP integration
* - Risk-adaptive authentication
* - Step-up MFA based on risk score
*/
export class LoginUseCase {
constructor(
private authRepository: IAuthRepository,
private trustRepository: ITrustRepository,
private config: AuthConfig
) {}
/**
* Execute login flow with risk assessment
*/
async execute(credentials: Credentials): Promise<AuthResult> {
try {
// 1. Risk Assessment (F.TR.004 from Trust SDK)
const { score: riskScore, signals } = await this.trustRepository.calculateRiskScore();
// 2. Initialize DPoP (F.ID.004 / F.SC.004)
const publicKey = await this.authRepository.initializeDPoP();
// 3. Attempt authentication
const session = await this.authRepository.exchangeCredentialsForToken(credentials, publicKey);
// 4. Enhance session with risk information
const enhancedSession: UserSession = {
...session,
riskScore,
requiresStepUp: this.shouldRequireStepUp(riskScore, signals)
};
// 5. Store session
await this.authRepository.storeSession(enhancedSession);
// 6. Check if step-up authentication is required
if (enhancedSession.requiresStepUp) {
return {
success: true,
session: enhancedSession,
requiresVerification: true,
verificationMethod: this.determineStepUpMethod(signals),
nextSteps: ['Complete additional verification to proceed']
};
}
// 7. Enable Remember Me if configured
if (this.config.rememberMeDays > 0) {
await this.authRepository.enableRememberMe(this.config.rememberMeDays);
}
return {
success: true,
session: enhancedSession
};
} catch (error) {
return this.handleLoginError(error);
}
}
/**
* Biometric login flow
*/
async executeWithBiometrics(biometricSignature: string, deviceId: string): Promise<AuthResult> {
const credentials: Credentials = {
identifier: 'biometric',
biometricSignature,
deviceId
};
return this.execute(credentials);
}
/**
* Magic link login flow (F.ID.006)
*/
async executeWithMagicLink(token: string, nonce: string): Promise<AuthResult> {
try {
const session = await this.authRepository.verifyMagicLink(token, nonce);
await this.authRepository.storeSession(session);
return {
success: true,
session
};
} catch (error) {
return this.handleLoginError(error);
}
}
/**
* Federated login flow (F.ID.007)
*/
async executeWithProvider(provider: 'google' | 'apple', token: string): Promise<AuthResult> {
try {
const session = await this.authRepository.authenticateWithProvider(provider, token);
await this.authRepository.storeSession(session);
return {
success: true,
session
};
} catch (error) {
return this.handleLoginError(error);
}
}
private shouldRequireStepUp(riskScore: number, signals: Record<string, any>): boolean {
// Risk-based step-up logic
if (riskScore > 75) return true;
if (signals.isRooted || signals.isEmulator) return true;
if (signals.attestationFailed) return true;
if (signals.geoDeviation && riskScore > 50) return true;
return false;
}
private determineStepUpMethod(signals: Record<string, any>) {
// Determine the most appropriate step-up method based on risk signals
if (signals.suspiciousLocation) {
return { type: 'otp' as const, target: 'phone' };
}
if (signals.newDevice) {
return { type: 'email' as const, target: 'email' };
}
// Default to biometric if available
return { type: 'biometric' as const };
}
private handleLoginError(error: any): AuthResult {
console.error('Login failed:', error);
// Map specific errors to user-friendly messages
if (error.code === 'INVALID_CREDENTIALS') {
return {
success: false,
errorCode: 'INVALID_CREDENTIALS',
errorMessage: 'Invalid email or password'
};
}
if (error.code === 'ACCOUNT_LOCKED') {
return {
success: false,
errorCode: 'ACCOUNT_LOCKED',
errorMessage: 'Account is temporarily locked due to multiple failed attempts'
};
}
if (error.code === 'VERIFICATION_REQUIRED') {
return {
success: false,
requiresVerification: true,
verificationMethod: error.verificationMethod,
errorMessage: 'Account verification required'
};
}
return {
success: false,
errorCode: 'UNKNOWN_ERROR',
errorMessage: 'An unexpected error occurred'
};
}
}
@@ -0,0 +1,5 @@
export class RegistrationUseCase {
async execute(payload: any) {
return { success: true };
}
}
@@ -0,0 +1,5 @@
export class SessionUseCase {
async getCurrent(sessionId: string) {
return null;
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"name": "@feature/auth/ui-rn",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
+1
View File
@@ -0,0 +1 @@
export const AuthUI = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/location/domain",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const LocationDomain = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/location/ui-rn",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const LocationUI = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/media/domain",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const MediaDomain = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/media/ui-rn",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const MediaUI = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/memberships/domain",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const MembershipsDomain = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/memberships/ui-rn",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const MembershipsUI = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/messaging/data",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}
@@ -0,0 +1 @@
export const MessagingData = {};
@@ -0,0 +1,6 @@
{
"name": "@feature/messaging/domain",
"version": "1.0.0",
"private": true,
"main": "src/index.ts"
}

Some files were not shown because too many files have changed in this diff Show More