Add Camino datatypes package export
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
dist/
|
||||
node_modules/
|
||||
.yarn/install-state.gz
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
+15
@@ -0,0 +1,15 @@
|
||||
approvedGitRepositories:
|
||||
- https://gitea-external.egads.tutti.syntaxblitz.net/quixos/*
|
||||
|
||||
enableScripts: true
|
||||
|
||||
generateDefaultNix: false
|
||||
|
||||
individualNixPackaging: true
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- checksum: 271de9a785321a37c564b8e2a6b5cd689850b20572d5fee8ec0a6b8e7a5d4cfb59e533524af2b4a537e00da12828abd062eaec6978556e3dd9149a020db2591b
|
||||
path: .yarn/plugins/yarn-plugin-nixify.cjs
|
||||
spec: "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/yarn-plugin-nixify-patched/raw/commit/4528fdd20b30d869262443b3f044549810e75fb8/dist/yarn-plugin-nixify.js"
|
||||
Generated
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1783776592,
|
||||
"narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e7a3ca8092b61ff85b6a45bf863ea2b2d6a661b3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"quixosNixHelpers": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1783886666,
|
||||
"narHash": "sha256-y52TlYwH9RBzzyhpkY/eB21t85BE84idpsg8618MIHg=",
|
||||
"ref": "refs/heads/exported",
|
||||
"rev": "81e55657d9ce0ba092cffd69ee15179ea02aa598",
|
||||
"revCount": 2,
|
||||
"type": "git",
|
||||
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
|
||||
},
|
||||
"original": {
|
||||
"ref": "refs/heads/exported",
|
||||
"rev": "81e55657d9ce0ba092cffd69ee15179ea02aa598",
|
||||
"type": "git",
|
||||
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"quixosNixHelpers": "quixosNixHelpers"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
description = "Shared Camino datatype semantics";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
quixosNixHelpers = {
|
||||
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/heads/exported&rev=81e55657d9ce0ba092cffd69ee15179ea02aa598";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
|
||||
outputs = inputs@{ nixpkgs, flake-utils, quixosNixHelpers, ... }:
|
||||
let
|
||||
quixosHelpers = import "${quixosNixHelpers}/quixos-package-helpers.nix";
|
||||
in
|
||||
quixosHelpers.mkCaminoTsYarnNixifyFlake {
|
||||
inherit inputs nixpkgs flake-utils;
|
||||
packageRoot = ./.;
|
||||
sourceName = "quixos-camino-datatypes-source";
|
||||
promptName = "camino-datatypes";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@quixos/camino-datatypes",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"packageManager": "yarn@4.14.1",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./src/index.ts"
|
||||
},
|
||||
"./field-semantics": {
|
||||
"types": "./src/field-semantics.ts",
|
||||
"default": "./src/field-semantics.ts"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.build.json",
|
||||
"test": "yarn build && node --test dist/test/*.test.js",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
export type UnknownFieldClock = {
|
||||
kind: "unknown";
|
||||
};
|
||||
|
||||
export type RevisionFieldClock = {
|
||||
kind: "revision";
|
||||
revision: bigint;
|
||||
};
|
||||
|
||||
export type FieldClock = UnknownFieldClock | RevisionFieldClock;
|
||||
|
||||
export type CanonicalFieldValue<T> = {
|
||||
value: T;
|
||||
clock: FieldClock;
|
||||
};
|
||||
|
||||
export type PendingFieldWrite<T> = {
|
||||
clientMutationId: string;
|
||||
sequence: number;
|
||||
value: T;
|
||||
};
|
||||
|
||||
export type RegisterFieldState<T> = {
|
||||
canonical: CanonicalFieldValue<T>;
|
||||
visible: T;
|
||||
pending: PendingFieldWrite<T>[];
|
||||
nextPendingSequence: number;
|
||||
};
|
||||
|
||||
export type FieldApplyResult = {
|
||||
accepted: boolean;
|
||||
canonicalChanged: boolean;
|
||||
pendingChanged: boolean;
|
||||
visibleChanged: boolean;
|
||||
};
|
||||
|
||||
export const unknownFieldClock = (): FieldClock => ({ kind: "unknown" });
|
||||
|
||||
export const revisionFieldClock = (
|
||||
revision: string | number | bigint | undefined | null,
|
||||
): FieldClock => {
|
||||
if (typeof revision === "bigint") {
|
||||
return { kind: "revision", revision };
|
||||
}
|
||||
if (typeof revision === "number" && Number.isInteger(revision) && revision >= 0) {
|
||||
return { kind: "revision", revision: BigInt(revision) };
|
||||
}
|
||||
if (typeof revision === "string" && /^\d+$/.test(revision)) {
|
||||
return { kind: "revision", revision: BigInt(revision) };
|
||||
}
|
||||
return unknownFieldClock();
|
||||
};
|
||||
|
||||
export const fieldClockToRevisionString = (clock: FieldClock) =>
|
||||
clock.kind === "revision" ? clock.revision.toString() : "";
|
||||
|
||||
export const compareFieldClocks = (
|
||||
left: FieldClock,
|
||||
right: FieldClock,
|
||||
): "older" | "same" | "newer" | "unknown" => {
|
||||
if (left.kind === "revision" && right.kind === "revision") {
|
||||
if (left.revision < right.revision) {
|
||||
return "older";
|
||||
}
|
||||
if (left.revision > right.revision) {
|
||||
return "newer";
|
||||
}
|
||||
return "same";
|
||||
}
|
||||
if (left.kind === "unknown" && right.kind === "unknown") {
|
||||
return "same";
|
||||
}
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
export const sameFieldClock = (left: FieldClock, right: FieldClock) =>
|
||||
compareFieldClocks(left, right) === "same";
|
||||
|
||||
const shouldAcceptCanonical = (incoming: FieldClock, current: FieldClock) => {
|
||||
const order = compareFieldClocks(incoming, current);
|
||||
if (order === "older") {
|
||||
return false;
|
||||
}
|
||||
if (order === "unknown" && current.kind !== "unknown") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const latestPendingValue = <T>(state: RegisterFieldState<T>) =>
|
||||
state.pending.at(-1)?.value;
|
||||
|
||||
const recomputeVisible = <T>(state: RegisterFieldState<T>) => {
|
||||
const pendingValue = latestPendingValue(state);
|
||||
return pendingValue === undefined ? state.canonical.value : pendingValue;
|
||||
};
|
||||
|
||||
export const createRegisterFieldState = <T>(
|
||||
initial: CanonicalFieldValue<T>,
|
||||
): RegisterFieldState<T> => ({
|
||||
canonical: initial,
|
||||
visible: initial.value,
|
||||
pending: [],
|
||||
nextPendingSequence: 1,
|
||||
});
|
||||
|
||||
export const applyCanonicalFieldValue = <T>(
|
||||
state: RegisterFieldState<T>,
|
||||
incoming: CanonicalFieldValue<T>,
|
||||
clientMutationId?: string,
|
||||
): FieldApplyResult => {
|
||||
const visibleBefore = state.visible;
|
||||
const pendingBefore = state.pending.length;
|
||||
if (!shouldAcceptCanonical(incoming.clock, state.canonical.clock)) {
|
||||
return {
|
||||
accepted: false,
|
||||
canonicalChanged: false,
|
||||
pendingChanged: false,
|
||||
visibleChanged: false,
|
||||
};
|
||||
}
|
||||
|
||||
const canonicalChanged =
|
||||
!Object.is(state.canonical.value, incoming.value) ||
|
||||
!sameFieldClock(state.canonical.clock, incoming.clock);
|
||||
|
||||
state.canonical = incoming;
|
||||
if (clientMutationId) {
|
||||
state.pending = state.pending.filter(
|
||||
(entry) => entry.clientMutationId !== clientMutationId,
|
||||
);
|
||||
}
|
||||
state.visible = recomputeVisible(state);
|
||||
|
||||
return {
|
||||
accepted: true,
|
||||
canonicalChanged,
|
||||
pendingChanged: state.pending.length !== pendingBefore,
|
||||
visibleChanged: !Object.is(state.visible, visibleBefore),
|
||||
};
|
||||
};
|
||||
|
||||
export const beginLocalFieldWrite = <T>(
|
||||
state: RegisterFieldState<T>,
|
||||
clientMutationId: string,
|
||||
value: T,
|
||||
): FieldApplyResult => {
|
||||
const visibleBefore = state.visible;
|
||||
state.pending.push({
|
||||
clientMutationId,
|
||||
sequence: state.nextPendingSequence++,
|
||||
value,
|
||||
});
|
||||
state.visible = value;
|
||||
return {
|
||||
accepted: true,
|
||||
canonicalChanged: false,
|
||||
pendingChanged: true,
|
||||
visibleChanged: !Object.is(state.visible, visibleBefore),
|
||||
};
|
||||
};
|
||||
|
||||
export const failLocalFieldWrite = <T>(
|
||||
state: RegisterFieldState<T>,
|
||||
clientMutationId: string,
|
||||
): FieldApplyResult => {
|
||||
const visibleBefore = state.visible;
|
||||
const pendingBefore = state.pending.length;
|
||||
state.pending = state.pending.filter(
|
||||
(entry) => entry.clientMutationId !== clientMutationId,
|
||||
);
|
||||
state.visible = recomputeVisible(state);
|
||||
return {
|
||||
accepted: true,
|
||||
canonicalChanged: false,
|
||||
pendingChanged: state.pending.length !== pendingBefore,
|
||||
visibleChanged: !Object.is(state.visible, visibleBefore),
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./field-semantics.js";
|
||||
@@ -0,0 +1,107 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import {
|
||||
applyCanonicalFieldValue,
|
||||
beginLocalFieldWrite,
|
||||
createRegisterFieldState,
|
||||
failLocalFieldWrite,
|
||||
revisionFieldClock,
|
||||
} from "../src/field-semantics.js";
|
||||
|
||||
test("register fields reject stale canonical values", () => {
|
||||
const state = createRegisterFieldState({
|
||||
value: "current",
|
||||
clock: revisionFieldClock(5n),
|
||||
});
|
||||
|
||||
beginLocalFieldWrite(state, "local:1", "current!");
|
||||
|
||||
const stale = applyCanonicalFieldValue(state, {
|
||||
value: "old",
|
||||
clock: revisionFieldClock(4n),
|
||||
});
|
||||
|
||||
assert.equal(stale.accepted, false);
|
||||
assert.equal(state.canonical.value, "current");
|
||||
assert.equal(state.visible, "current!");
|
||||
assert.equal(state.pending.length, 1);
|
||||
});
|
||||
|
||||
test("register fields reconcile optimistic writes by mutation id", () => {
|
||||
const state = createRegisterFieldState({
|
||||
value: "a",
|
||||
clock: revisionFieldClock(1n),
|
||||
});
|
||||
|
||||
beginLocalFieldWrite(state, "local:1", "ab");
|
||||
beginLocalFieldWrite(state, "local:2", "abc");
|
||||
|
||||
const otherWriter = applyCanonicalFieldValue(state, {
|
||||
value: "z",
|
||||
clock: revisionFieldClock(2n),
|
||||
});
|
||||
assert.equal(otherWriter.accepted, true);
|
||||
assert.equal(state.canonical.value, "z");
|
||||
assert.equal(state.visible, "abc");
|
||||
assert.equal(state.pending.length, 2);
|
||||
|
||||
const firstAck = applyCanonicalFieldValue(
|
||||
state,
|
||||
{
|
||||
value: "ab",
|
||||
clock: revisionFieldClock(3n),
|
||||
},
|
||||
"local:1",
|
||||
);
|
||||
assert.equal(firstAck.accepted, true);
|
||||
assert.equal(state.canonical.value, "ab");
|
||||
assert.equal(state.visible, "abc");
|
||||
assert.equal(state.pending.length, 1);
|
||||
|
||||
const secondAck = applyCanonicalFieldValue(
|
||||
state,
|
||||
{
|
||||
value: "abc",
|
||||
clock: revisionFieldClock(4n),
|
||||
},
|
||||
"local:2",
|
||||
);
|
||||
assert.equal(secondAck.accepted, true);
|
||||
assert.equal(state.canonical.value, "abc");
|
||||
assert.equal(state.visible, "abc");
|
||||
assert.equal(state.pending.length, 0);
|
||||
});
|
||||
|
||||
test("register fields reject unclocked values after a revision is known", () => {
|
||||
const state = createRegisterFieldState({
|
||||
value: "known",
|
||||
clock: revisionFieldClock(9n),
|
||||
});
|
||||
|
||||
const result = applyCanonicalFieldValue(state, {
|
||||
value: "unclocked",
|
||||
clock: revisionFieldClock(undefined),
|
||||
});
|
||||
|
||||
assert.equal(result.accepted, false);
|
||||
assert.equal(state.canonical.value, "known");
|
||||
assert.equal(state.visible, "known");
|
||||
});
|
||||
|
||||
test("failed optimistic writes reveal the newest accepted canonical value", () => {
|
||||
const state = createRegisterFieldState({
|
||||
value: "base",
|
||||
clock: revisionFieldClock(1n),
|
||||
});
|
||||
|
||||
beginLocalFieldWrite(state, "local:1", "local");
|
||||
applyCanonicalFieldValue(state, {
|
||||
value: "remote",
|
||||
clock: revisionFieldClock(2n),
|
||||
});
|
||||
failLocalFieldWrite(state, "local:1");
|
||||
|
||||
assert.equal(state.canonical.value, "remote");
|
||||
assert.equal(state.visible, "remote");
|
||||
assert.equal(state.pending.length, 0);
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"noEmit": false,
|
||||
"outDir": "dist",
|
||||
"rootDir": ".",
|
||||
"sourceMap": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "test/**/*.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
# This file is generated by running "yarn install" inside your project.
|
||||
# Manual changes might be lost - proceed with caution!
|
||||
|
||||
{ lib, stdenv, nodejs, git, cacert, fetchurl, writeShellScript, writeShellScriptBin }:
|
||||
{ src, overrideAttrs ? null, ... } @ args:
|
||||
|
||||
let
|
||||
|
||||
yarnBin = fetchurl {
|
||||
url = "https://repo.yarnpkg.com/4.14.1/packages/yarnpkg-cli/bin/yarn.js";
|
||||
hash = "sha512-ZN9EgFWy03uiadfbU1pGm42pP47xFAwl/XqDwAqPuqyyFMoOAlU7kqLFTO94u2fQtIF/qwIAHfDiT6wPrMw7Qg==";
|
||||
};
|
||||
|
||||
cacheFolder = ".yarn/cache";
|
||||
lockfile = ./yarn.lock;
|
||||
|
||||
# Call overrideAttrs on a derivation if a function is provided.
|
||||
optionalOverride = fn: drv:
|
||||
if fn == null then drv else drv.overrideAttrs fn;
|
||||
|
||||
# Simple stub that provides the global yarn command.
|
||||
yarn = writeShellScriptBin "yarn" ''
|
||||
exec '${nodejs}/bin/node' '${yarnBin}' "$@"
|
||||
'';
|
||||
|
||||
# Common attributes between Yarn derivations.
|
||||
drvCommon = {
|
||||
# Make sure the build uses the right Node.js version everywhere.
|
||||
buildInputs = [ nodejs yarn ];
|
||||
# All dependencies should already be cached.
|
||||
yarn_enable_network = "0";
|
||||
# Tell node-gyp to use the provided Node.js headers for native code builds.
|
||||
npm_config_nodedir = nodejs;
|
||||
};
|
||||
|
||||
# Comman variables that we set in a Nix build, but not in a Nix shell.
|
||||
buildVars = ''
|
||||
# Make Yarn produce friendlier logging for automated builds.
|
||||
export CI=1
|
||||
# Tell node-pre-gyp to never fetch binaries / always build from source.
|
||||
export npm_config_build_from_source=true
|
||||
'';
|
||||
|
||||
# Create derivations for fetching dependencies.
|
||||
cacheDrvs = let
|
||||
in lib.mapAttrs (locator: { filename, hash }: stdenv.mkDerivation {
|
||||
name = lib.strings.sanitizeDerivationName locator;
|
||||
buildInputs = [ yarn git cacert ];
|
||||
buildCommand = ''
|
||||
cd '${src}'
|
||||
${buildVars}
|
||||
HOME="$TMP" yarn_enable_global_cache=false yarn_cache_folder="$TMP" \
|
||||
yarn nixify fetch ${lib.escapeShellArg locator}
|
||||
# Because we change the cache dir, Yarn may generate a different name.
|
||||
mv "$TMP/$(sed 's/-[^-]*\.[^-]*$//' <<< "$outputFilename")"-* $out
|
||||
'';
|
||||
outputFilename = filename;
|
||||
outputHash = hash;
|
||||
}) cacheEntries;
|
||||
|
||||
# Create a shell snippet to copy dependencies from a list of derivations.
|
||||
mkCacheBuilderForDrvs = drvs:
|
||||
writeShellScript "collect-yarn-cache" (lib.concatMapStrings (drv: ''
|
||||
cp --reflink=auto ${drv} '${drv.outputFilename}'
|
||||
'') drvs);
|
||||
|
||||
# Main project derivation.
|
||||
project = stdenv.mkDerivation (drvCommon // {
|
||||
inherit src;
|
||||
name = "@quixos/camino-datatypes";
|
||||
|
||||
configurePhase = ''
|
||||
${buildVars}
|
||||
|
||||
# Copy over the Yarn cache.
|
||||
rm -fr '${cacheFolder}'
|
||||
mkdir -p '${cacheFolder}'
|
||||
pushd '${cacheFolder}' > /dev/null
|
||||
source ${mkCacheBuilderForDrvs (lib.attrValues cacheDrvs)}
|
||||
popd > /dev/null
|
||||
|
||||
# Yarn may need a writable home directory.
|
||||
export yarn_global_folder="$TMP"
|
||||
|
||||
# Ensure global cache is disabled. Cache must be part of our output.
|
||||
touch .yarnrc.yml
|
||||
sed -i -e '/^enableGlobalCache/d' .yarnrc.yml
|
||||
echo 'enableGlobalCache: false' >> .yarnrc.yml
|
||||
|
||||
# Some node-gyp calls may call out to npm, which could fail due to an
|
||||
# read-only home dir.
|
||||
export HOME="$TMP"
|
||||
|
||||
# running preConfigure after the cache is populated allows for
|
||||
# preConfigure to contain substituteInPlace for dependencies as well as the
|
||||
# main project. This is necessary for native bindings that maybe have
|
||||
# hardcoded values.
|
||||
runHook preConfigure
|
||||
|
||||
# Run normal Yarn install to complete dependency installation.
|
||||
yarn install --immutable --immutable-cache
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
# Move the package contents to the output directory.
|
||||
if grep -q '"workspaces"' package.json; then
|
||||
# We can't use `yarn pack` in a workspace setup, because it only
|
||||
# packages the outer workspace.
|
||||
mkdir -p "$out/libexec"
|
||||
mv $PWD "$out/libexec/$name"
|
||||
else
|
||||
# - If the package.json has a `files` field, only files matching those patterns are copied
|
||||
# - Otherwise all files are copied.
|
||||
yarn pack --out package.tgz
|
||||
mkdir -p "$out/libexec/$name"
|
||||
tar xzf package.tgz --directory "$out/libexec/$name" --strip-components=1
|
||||
|
||||
cp --reflink=auto .yarnrc* "$out/libexec/$name"
|
||||
cp --reflink=auto ${lockfile} "$out/libexec/$name/yarn.lock"
|
||||
cp --reflink=auto --recursive .yarn "$out/libexec/$name"
|
||||
|
||||
# Copy the Yarn linker output into the package.
|
||||
cp --reflink=auto --recursive node_modules "$out/libexec/$name"
|
||||
fi
|
||||
|
||||
cd "$out/libexec/$name"
|
||||
|
||||
# Invoke a plugin internal command to setup binaries.
|
||||
mkdir -p "$out/bin"
|
||||
yarn nixify install-bin $out/bin
|
||||
|
||||
# A package with node_modules doesn't need the cache
|
||||
yarn cache clean
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit nodejs;
|
||||
yarn-freestanding = yarn;
|
||||
yarn = writeShellScriptBin "yarn" ''
|
||||
exec '${yarn}/bin/yarn' --cwd '${overriddenProject}/libexec/${overriddenProject.name}' "$@"
|
||||
'';
|
||||
};
|
||||
});
|
||||
|
||||
overriddenProject = optionalOverride overrideAttrs project;
|
||||
|
||||
cacheEntries = {
|
||||
"@types/node@npm:24.13.3" = { filename = "@types-node-npm-24.13.3-b512a0bbeb-a5bc08f49b.zip"; hash = "sha512-pbwI9JuVgdzcqQ4CzXcZejx5mECAdmSULlzVFhpVPU0q6AZPfjKUQQ10jX0Ji1wYSL5/pQwG8pxBk6sWvk5Z6w=="; };
|
||||
"typescript@npm:5.9.3" = { filename = "typescript-npm-5.9.3-48715be868-6bd7552ce3.zip"; hash = "sha512-a9dVLOOfl+cR21qgSPb5mVtT8cUvfYZnwavcFwDGinajCPV5zTCc5rU2Rt606aG+fIE6k7qvCijM1TajAnDhxQ=="; };
|
||||
"typescript@patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5" = { filename = "typescript-patch-6fda4d02cf-ad09fdf7a7.zip"; hash = "sha512-rQn996dWgU3OZbxgwWV7QNREUTRoWO6iMOEPLpWiidkYO24y5cEelazAzMIUtPNiidytS/GIawrbhNcR0zakMA=="; };
|
||||
"undici-types@npm:7.18.2" = { filename = "undici-types-npm-7.18.2-3e6d69d829-85a7918911.zip"; hash = "sha512-haeRiRE6I4lZ16ZHNo5PfFVZw6QE69uPxEiBRc6UJvzYIlKoRKMCeY38Djfm+xeP9IHtA7xMr2NMV1fZ70NSHQ=="; };
|
||||
};
|
||||
|
||||
in overriddenProject
|
||||
@@ -0,0 +1,51 @@
|
||||
# This file is generated by running "yarn install" inside your project.
|
||||
# Manual changes might be lost - proceed with caution!
|
||||
|
||||
__metadata:
|
||||
version: 9
|
||||
cacheKey: 10c0
|
||||
|
||||
"@quixos/camino-datatypes@workspace:.":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@quixos/camino-datatypes@workspace:."
|
||||
dependencies:
|
||||
"@types/node": "npm:^24"
|
||||
typescript: "npm:^5.9.3"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@types/node@npm:^24":
|
||||
version: 24.13.3
|
||||
resolution: "@types/node@npm:24.13.3"
|
||||
dependencies:
|
||||
undici-types: "npm:~7.18.0"
|
||||
checksum: 10c0/a5bc08f49b9581dcdca90e02cd77197a3c799840807664942e5cd5161a553d4d2ae8064f7e3294410d748d7d098b5c1848be7fa50c06f29c4193ab16be4e59eb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5.9.3":
|
||||
version: 5.9.3
|
||||
resolution: "typescript@npm:5.9.3"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
|
||||
version: 5.9.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~7.18.0":
|
||||
version: 7.18.2
|
||||
resolution: "undici-types@npm:7.18.2"
|
||||
checksum: 10c0/85a79189113a238959d7a647368e4f7c5559c3a404ebdb8fc4488145ce9426fcd82252a844a302798dfc0e37e6fb178ff481ed03bc4caf634c5757d9ef43521d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
Reference in New Issue
Block a user