Skip to content

Latest#9771

Open
edgardoparaiso790-byte wants to merge 672 commits into
npm:feat/registry-clientfrom
edgardoparaiso790-byte:latest
Open

Latest#9771
edgardoparaiso790-byte wants to merge 672 commits into
npm:feat/registry-clientfrom
edgardoparaiso790-byte:latest

Conversation

@edgardoparaiso790-byte

Copy link
Copy Markdown

// SIDV Edge Function: revoke-str
// Revokes an active STR (Security Transaction Reference) code.
// Deploy via Supabase Dashboard (Edge Functions > Deploy a new function > Via Editor)
// or CLI: supabase functions deploy revoke-str
//
// Auth: Admin-only. Expects a valid admin/service Bearer token (sk_live_ / sk_test_).
// Mirrors the CORS/error helper conventions used in verify-str and str-webhook.

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

// ---- Shared CORS headers (same pattern as verify-str / str-webhook) ----
const corsHeaders = {
'Access-Control-Allow-Origin': '*', // tighten to your production domain(s) if needed
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
}

// ---- Shared error response helper ----
function errorResponse(code: string, message: string, status = 400) {
return new Response(
JSON.stringify({
error: {
code,
message,
},
}),
{
status,
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
}
)
}

function successResponse(data: Record<string, unknown>, status = 200) {
return new Response(JSON.stringify({ data }), {
status,
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
})
}

Deno.serve(async (req: Request) => {
// Handle CORS preflight
if (req.method === 'OPTIONS') {
return new Response('ok', { headers: corsHeaders })
}

if (req.method !== 'POST') {
return errorResponse('METHOD_NOT_ALLOWED', 'Only POST is supported', 405)
}

try {
// ---- Auth check: admin-only ----
const authHeader = req.headers.get('Authorization')
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return errorResponse('UNAUTHORIZED', 'Missing or invalid Authorization header', 401)
}

const token = authHeader.replace('Bearer ', '').trim()

// Only admin/service-level keys may revoke. Adjust prefix check to match
// your actual admin key issuance scheme.
if (!token.startsWith('sk_live_') && !token.startsWith('sk_test_')) {
  return errorResponse('FORBIDDEN', 'Revocation requires an admin API key', 403)
}

// ---- Parse request body ----
let body: { str_code?: string; reason?: string }
try {
  body = await req.json()
} catch {
  return errorResponse('INVALID_REQUEST', 'Request body must be valid JSON', 400)
}

const { str_code, reason } = body

if (!str_code || typeof str_code !== 'string') {
  return errorResponse('INVALID_REQUEST', 'str_code is required', 400)
}

// Basic format check for SIDV-XXXX-XXXX-XXXX
const strFormat = /^SIDV-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/
if (!strFormat.test(str_code)) {
  return errorResponse('INVALID_STR_FORMAT', 'str_code does not match expected format', 400)
}

// ---- Connect to Supabase with service role (bypasses RLS) ----
const supabase = createClient(
  Deno.env.get('SUPABASE_URL') ?? '',
  Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)

// ---- Look up the STR record ----
const { data: strRecord, error: fetchError } = await supabase
  .from('sidv_transactions')
  .select('id, status, str_code')
  .eq('str_code', str_code)
  .single()

if (fetchError || !strRecord) {
  return errorResponse('STR_NOT_FOUND', 'No matching STR code found', 404)
}

if (strRecord.status === 'revoked') {
  return errorResponse('STR_REVOKED', 'This STR code has already been revoked', 409)
}

if (strRecord.status === 'expired') {
  return errorResponse('STR_EXPIRED', 'This STR code has expired', 409)
}

if (strRecord.status === 'used') {
  return errorResponse('STR_USED', 'This STR code has already been used', 409)
}

// ---- Perform revocation ----
const { error: updateError } = await supabase
  .from('sidv_transactions')
  .update({
    status: 'revoked',
    revoked_at: new Date().toISOString(),
    revoked_reason: reason ?? null,
  })
  .eq('id', strRecord.id)

if (updateError) {
  return errorResponse('REVOCATION_FAILED', 'Failed to revoke STR code', 500)
}

// ---- Audit log entry ----
await supabase.from('sidv_audit_log').insert({
  event_type: 'str_revoked',
  str_code,
  metadata: { reason: reason ?? null },
  created_at: new Date().toISOString(),
})

return successResponse({
  str_code,
  status: 'revoked',
  revoked_at: new Date().toISOString(),
})

} catch (err) {
console.error('revoke-str error:', err)
return errorResponse('INTERNAL_ERROR', 'An unexpected error occurred', 500)
}
})

wraithgar and others added 30 commits April 15, 2026 11:26
## Summary

Adds `u` as a short alias for the `update` command, making it consistent
with `i` for `install`.

## Motivation

`npm i` is the canonical short form for `npm install` — the most
commonly used npm command. However, `npm update` lacks an equivalent
single-character alias. The existing `npm up` alias works, but feels
inconsistent compared to `i`.

Adding `u` makes the CLI more ergonomic and intuitive:

```sh
npm i    # install   ✅ already exists
npm u    # update    ✅ this PR
```

## Changes

- Added `u: 'update'` alias in `lib/utils/cmd-list.js`, grouped
alongside the existing `up: 'update'` alias

## Notes

- `u` is not currently used by any other alias or command, so there is
no conflict
- Follows the same pattern as other single-character aliases (`i`, `r`,
`t`, `c`, `s`, `v`, `x`)
BREAKING CHANGE: the `star`, `stars` and `unstar` commands have been
removed

fixes npm/statusboard#1087
BREAKING CHANGE: the --json output of `npm pack` and `npm publish` have
changed. They are now always consistent, and in the same format.

Previously, `npm pack` would output an array of entries and `npm
publish` an object. The `npm publish` object also changed forms
depending on if workspaces were being published.

Now, the output is always an object with the package name as the top
level index.

fixes npm/statusboard#1073
BREAKING CHANGE: npm will no longer attempt to resolve the path to node via whichnode. process.execPath is already set by Node to the resolved real path of the node binary, so the lookup was redundant. Scripts that expected npm to override process.execPath with a PATH-resolved (potentially symlinked) node path may be affected.
…es (npm#9235)

Fixes npm#9227

`npm install` hangs when a project uses `bundledDependencies` and
`overrides` targeting a transitive dep shared by multiple bundled deps.

In `edge.js` `satisfiedBy()`, the `inBundle` check (added in npm#4963) uses
`rawSpec` for bundled nodes to prevent overrides from applying to
pre-resolved deps inside a dependency's tarball. However, `inBundle` is
also true for deps the root itself will bundle - these are freshly
resolved from the registry and overrides should apply.

The override was always applied at placement time (correct version
installed), but the edge stayed invalid because `satisfiedBy` checked
`rawSpec`. Two bundled deps sharing the overridden transitive dep would
endlessly re-queue each other via REPLACE.

The fix changes `inBundle` to `inDepBundle`, which is only true when the
bundler is a non-root package. This preserves the npm#4963 behavior for
deps pre-resolved inside a dependency's bundle/shrinkwrap while allowing
the root's overrides to work.

Note: it is unclear whether overrides _should_ be applied to deps that
will be bundled or shrinkwrapped. The comment says that we explicitly
don't, but I can't find supporting docs, and the existing behavior is
that overrides are applied to dependencies that will be
bundled/shrinkwrapped. I added tests asserting that behavior.

These new tests passed without the change:
 - overrides do not apply inside a dependency that bundles
 - node bundled inside a dependency uses rawSpec
 - node inside a shrinkwrap uses rawSpec

These new tests failed, they produced the same tree, but the edges were
marked invalid:
 - node bundled by root uses overridden spec
 - overrides apply to deps the root will bundle and edges are valid

This test hung forever:
 - does not infinite loop

In both cases overrides that are 'baked into' dependnecies appear as
'invalid'. This happens because the root package doesn't read the
bundler's overrides, and doesn't know why the shrinkwrap/bundle included
the out-of-spec version. This commit doesn't affect that behavior.
…#9198)

In continuation of our exploration of using `install-strategy=linked` in
the [Gutenberg
monorepo](WordPress/gutenberg#75814), which
powers the WordPress Block Editor.

When using `install-strategy=linked`, npm overrides for transitive
dependencies were ignored.
The overridden version was installed but reported as `invalid` instead
of `overridden`, and with `strict-peer-deps` the install failed entirely
with `ERESOLVE`.

The root cause is that override propagation stops at Link nodes and
never reaches their targets.
Overrides propagate through the tree via `addEdgeIn` ->
`updateOverridesEdgeInAdded` -> `recalculateOutEdgesOverrides`.
When a Link node receives overrides, `recalculateOutEdgesOverrides`
iterates over `this.edgesOut` — but Links have no `edgesOut` (their
targets do).
So overrides never reach the target node's dependency edges, and those
edges use `rawSpec` instead of the overridden spec.

In the linked strategy, all packages in `node_modules/` are Links
pointing to targets in `.store/`.
This meant no overrides propagated past the first level of the
dependency tree.

The fix overrides `recalculateOutEdgesOverrides` in the `Link` class to
forward overrides to the target node.
When `buildIdealTree` creates a root Link (e.g. on macOS where `/tmp` ->
`/private/tmp`), the target Node is now created with `loadOverrides:
true` so it loads override rules from `package.json`.

The `#applyRootOverridesToWorkspaces` workaround method is removed — it
was compensating for this exact bug by detaching workspace edges whose
specs didn't match. With proper propagation, workspace edges already
have the correct overridden spec, making the workaround dead code.


## References

Fixes npm#9197
…#9255)

`npx` unconditionally re-reifies `file:`/directory specs on every
invocation, even when the package is already installed in the npx cache.
This happens because `missingFromTree()` has an early return for
directory specs that bypasses the cache lookup entirely.
Registry packages correctly skip reify on cache hit by checking
`node.package.resolved === manifest._resolved`, but directory specs
never reach that check.

The fix makes two changes to `missingFromTree()` in
`libnpmexec/lib/index.js`:

1. The early return for directory specs is now scoped to non-npx trees
(`!isNpxTree`), so the npx cache tree is actually consulted on
subsequent runs.
2. Added `node.realpath === manifest._resolved` as an alternative match
condition, since `file:` spec nodes in the npx cache have `undefined`
for `package.resolved` but their `realpath` contains the matching
absolute path.

A regression test verifies that running `exec` twice with the same
`file:` spec only triggers `reify` once (on the cold cache run).

## References

Fixes npm#9251
BREAKING CHANGE: The Twitter and Freenode profile fields have been removed from the npm registry. This means that users will no longer be able to set or view these fields in their npm profiles.
BREAKING CHANGE: `npm shrinkwrap` is removed, the `shrinkwrap` config alias is removed, and `npm-shrinkwrap.json` is no longer loaded or honored at the project root or from inside dependency tarballs. Rename project-root `npm-shrinkwrap.json` to `package-lock.json`; use `bundleDependencies` if you need to ship a locked dependency tree.
BREAKING CHANGE: The `npm pkg` output is no longer forced to json.  This means you can get single values without having to worry about wrapping of the values.  It also outputs non-json content more similarly to `npm view`.

Fixes npm/statusboard#1080
BREAKING CHANGE: npm no longer registers man pages with the system when installed globally. `man npm-install` will no longer work, but `npm help install` is unaffected.
BREAKING CHANGE: `npm sbom --sbom-format=cyclonedx` now reports the
`name` field from each package's `package.json` instead of the on-disk
directory name. The `name`, `bom-ref`, and `purl` of the root component
and of aliased dependencies may change.

fixes: npm#9178

---------

Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
BREAKING CHANGE: npm pack and npm publish now error when a package's overrides apply to one or more of its bundled packages (bundledDependencies / bundleDependencies). Defining both fields is still allowed as long as no override actually targets a bundled package. To resolve the error, remove the affected entries from either overrides or the bundle.
BREAKING CHANGE: npm view --json now always returns an array.
…#9283)

When a peerOptional edge conflicts, search descendants for a satisfying
node before fetching from the registry. This prevents extraneous
packages from blocking hoisting of required deps.

This fixes 1/2 or 1/3 of npm#9249. Before this change a clean install would
resolve `nm/jest-util@30` when resolving the conflict at nm/jest-util
between ts-jest's jest-util@^29||^30, and expect's ^28, which had been
placed at root. `#nodeFromEdge` would create a brand new node, matching
greatest ^30. A subequent install would mark nm/jest-util@30 as
extraneous and prune it.
This tree is valid, but ts-jest's peerOptional jest-util is unsatisfied,
while compatible jest-util are installed and duplicated.

This change reduces duplication and can prevent peerOptionals from
actively installing.

1. Now during initial installs npm will prefer hoisting a dependency to
de-dupe a peerOptional conflict over creating a new extraneous edge.
2. It doesn't solve the problem if there's no compatible version in the
sub-tree. npm will still use `#nodeFromEdge` and install an extraneous
edge.
3. It doesn't fix installs from lockfiles generated before this fix. I
think this is okay, because the trees are techincally valid, just not
optimal.

 I think a better solution to all three issues would be:
* During problemEdge conflict resolution, npm would hoist
nm/jest-util@28 under expect, without replacing it with anything.
ts-jest's peerOptional jest-util would be unsatisfied. This creates the
same tree as npm's second installs that prune extraneous.
* Check for any dependencies that can be hosited. This can run during
the initial install on problemEdge conflict resoultion, and in
pruneIdealTree on any nodes that are removed.
 
I think this solves all three issues. I didn't implement it because I
couldn't find a way to resolve the conflict by leaving a hole in the
tree..
Michael Smith and others added 19 commits June 29, 2026 08:59
Unknown configuration keys in .npmrc files now emit a warning by
default, restoring pre-npm-12 behavior, instead of throwing. This
reverts the breaking change from 979518d (npm#9276) for file-based
configs. The new `strict-npmrc` config (default false) opts back into
treating them as a hard error. Unknown CLI flags and abbreviations
continue to error regardless of this setting.
…9733)

## What / Why

npm#9729 reverts the `.npmrc` file-config half of the breaking change from
`979518d` (npm#9276): unknown `.npmrc` configs warn by default again, and
the new `strict-npmrc` config opts back into erroring. Unknown CLI flags
and abbreviations still throw.

The `12.0.0-pre.1` changelog entry still carried the original wording,
which claimed unknown `.npmrc` configs now throw. Since release-please
aggregates every prerelease `BREAKING CHANGE` note into the eventual
stable `v12.0.0` release notes, that stale line would surface
(inaccurately) in the 12.0.0 notes. This corrects the wording in place.

## Change

Edits the single breaking-changes bullet in the `## [12.0.0-pre.1]`
section:

> unknown CLI flags, abbreviated flags, and single-hyphen multi-char
shorthands now throw instead of warning. (Unknown `.npmrc` configs still
warn by default; opt into erroring with the new `strict-npmrc` config.)

## Notes

- Manual, targeted edit to an already-released, release-please-generated
section — this does not disturb release-please, which derives versions
from git tags + commit history and only prepends new sections.
Precedent: npm#8298 (`chore: add contributor to changelog entry`).
- Best merged alongside / after npm#9729 so the corrected note reflects
shipped behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This PR fixes npm#9722.

`mock-registry` pinned `@npmcli/arborist@^9.1.2`, which meant the local
workspace version wasn't linked and the dependency was pulled from the
registry instead. `sigstore@^4` got installed at the root node_modules
and `^5` was put into `workspaces/libnpmpublish/node_modules`. The
dev-only `^4` was then excluded when npm was packed.

Fix:
- `mock-registry`: arborist `^9.1.2` ->  `^10.0.0`
- `workspaces/arborist`: validate-npm-package-name `^7.0.2` -> `^8.0.0`
(need to release a patch for arborist)
- Lockfile regenerated via install + dedupe; `node . run dependencies`


The packed tarball now contains `package/node_modules/sigstore` and
`publish --dry-run` from the extracted tarball succeeds.
npm 12.0.0 breaks downstream updaters by returning nested arrays for
`npm view <pkg> versions --json`.

## The bug

On npm 12.0.0, a single array-valued field is wrapped in the outer
results array:

```
$ npm view abbrev versions --json
[["1.0.3","1.0.4", ...]]   # should be ["1.0.3","1.0.4", ...]
```

This happens in `lib/commands/view.js` `#packageOutput`: for a
single-field query it maps to `res.map(m => m[first[0]])`, and when that
field's value is itself an array (e.g. `versions`), it gets
double-wrapped.

## The fix

Return a sole array-valued JSON result directly instead of adding a
second result wrapper. Existing output shapes are preserved:

- scalar and object results still return in an array (`["1.0.0"]`,
`[{...}]`)
- multiple matching versions keep the result boundary (`[[...],[...]]`)
- a single array-valued result is returned directly
(`["1.0.0","1.0.1"]`)

Docs and tests updated to cover flat array, nested array,
object-wrapper, workspace, and multi-match cases.

Co-authored-by: Martin Ruiz <martin.ruiz.mares@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pm#9746)

The `bin links adding and removing` test in
`workspaces/arborist/test/arborist/reify.js` reifies `rimraf@2.7.1`
without setting up a mock registry.

This adds `createRegistry(t, true)` so the test uses the mock registry
instead of depending on the real one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Problem

The `build nodejs` jobs in `Release Integration / publish` fail at
`.github/workflows/node-integration.yml`:

```
node . pack --loglevel=silent --json | jq -r .[0].filename
→ jq: error (at <stdin>:9859): Cannot index object with number
→ Process completed with exit code 5
```

As of npm#9247 (sync json output of pack and publish), `npm pack --json` no
longer outputs an array. `logTar` now buffers `{ [tar.name]: tarball }`,
so the output is an object keyed by package name:

```json
{ "npm": { "filename": "npm-12.0.1.tgz", ... } }
```

The workflow still parsed it with `.[0].filename`, which errors on an
object. npm 12.0.x is the first release carrying this change, so the
release integration only started breaking now.

## Fix

Parse the filename from the object instead of an array index:

```diff
-npmtarball="$(node . pack --loglevel=silent --json | jq -r .[0].filename)"
+npmtarball="$(node . pack --loglevel=silent --json | jq -r 'to_entries[0].value.filename')"
```

Verified locally: returns `npm-12.0.1.tgz`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@edgardoparaiso790-byte
edgardoparaiso790-byte requested a review from a team as a code owner July 16, 2026 07:01
@edgardoparaiso790-byte
edgardoparaiso790-byte changed the base branch from feat/audit-cooldown-check to regi/cmd-config2 July 16, 2026 07:17
@edgardoparaiso790-byte
edgardoparaiso790-byte changed the base branch from regi/cmd-config2 to feat/audit-cooldown-check July 16, 2026 07:17

@edgardoparaiso790-byte edgardoparaiso790-byte left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-383+;;*+#(#!$!

Updated workflow name format and added link to build job.
@edgardoparaiso790-byte
edgardoparaiso790-byte changed the base branch from feat/audit-cooldown-check to latest July 16, 2026 17:24
@edgardoparaiso790-byte
edgardoparaiso790-byte requested a review from a team as a code owner July 16, 2026 17:24

@edgardoparaiso790-byte edgardoparaiso790-byte left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This a worker custom

@edgardoparaiso790-byte
edgardoparaiso790-byte changed the base branch from latest to owlstronaut/circle-ci-trust-backup July 18, 2026 06:41
@edgardoparaiso790-byte
edgardoparaiso790-byte changed the base branch from owlstronaut/circle-ci-trust-backup to ci-no-npm-update-v11 July 18, 2026 06:41
@edgardoparaiso790-byte
edgardoparaiso790-byte changed the base branch from ci-no-npm-update-v11 to feat/registry-client July 18, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.