Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/publish-npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Publish Package

on:
push:
tags:
- 'v*'

permissions:
id-token: write # Required for OIDC
contents: read

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'

# Ensure npm 11.5.1 or later is installed
- name: Update npm
run: npm install -g npm@latest
- run: npm ci
- run: npm run build --if-present
- run: npm test
- run: npm publish
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ COPY package*.json ./
RUN npm ci
COPY src ./src
COPY tsconfig.json ./
COPY schema.graphql ./
RUN npm run build

# Stage 2: Copy the built code and the node modules
Expand All @@ -13,7 +14,6 @@ WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/build ./build
COPY package*.json ./
COPY schema.graphql ./

# Don't run as root
RUN addgroup -g 1001 -S nodejs
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,15 @@ This section aims to describe all the environment variables exposed to configure

To see an example of sensible defaults, see the [env.example](./.env.example) configuration file.

## Installing from npm Registry
## Installing from npm

This package is published to npm and is available for public access

```sh
npm install mina-archive-node-graphql
```

## Installing from artifact registry

This package is published to a Google Cloud Artifact Registry and is available for public access.

Expand Down Expand Up @@ -157,11 +165,13 @@ To create a new release, follow these steps:
3. **Create and push a tag**: `git tag v1.2.3 && git push origin v1.2.3`

The CI/CD workflow will automatically:

- Build and publish npm package to GCP registry with version from package.json
- Build and push Docker image to both GCP Artifact Registry and GitHub Container Registry
- Create semantic version tags (e.g., `1.2.3`, `1.2`, `1`, `latest`)

**Published artifacts:**

- npm: `https://europe-southwest1-npm.pkg.dev/o1labs-192920/euro-npm/`
- Docker (GCP): `europe-west3-docker.pkg.dev/o1labs-192920/euro-docker-repo/archive-node-api`
- Docker (GitHub): `ghcr.io/o1-labs/archive-node-api`
Expand Down
30 changes: 4 additions & 26 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
{
"name": "archive-node-graphql",
"version": "1.0.0",
"name": "mina-archive-node-graphql",
"version": "0.0.8",
"description": "A NodeJS GraphQL server for exposing data for o1js/zkApps",
"repository": {
"type": "git",
"url": "https://github.com/o1-labs/Archive-Node-API"
},
"main": "build/src/index.js",
"start": "build/src/index.js",
"files": [
"build/"
],
"type": "module",
"scripts": {
"build": "npm run clean && npx tsc",
"build": "npm run clean && npx tsc && cp schema.graphql build/",
"start": "node build/src/index.js",
"dev": "cross-env NODE_NO_WARNINGS=1 npx nodemon --exec 'node -r dotenv/config --loader ts-node/esm' src/index.ts",
"test": "./run-tests.sh",
Expand Down
38 changes: 29 additions & 9 deletions src/resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
import { makeExecutableSchema } from '@graphql-tools/schema';
import { Resolvers } from './resolvers-types.js';
import { visit, print, parse } from 'graphql';
import fs from 'fs';
import { parse, print, visit } from 'graphql';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import { Resolvers } from './resolvers-types.js';
import {
TracingState,
setSpanNameFromGraphQLContext,
} from './tracing/tracer.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const graphqlSchemaPath = join(__dirname, '..', 'schema.graphql');

const fullResolvers: Resolvers = {
Query: {
events: async (_, { input }, context) => {
const graphQLSpan = setSpanNameFromGraphQLContext(context, 'events.graphql');
const graphQLSpan = setSpanNameFromGraphQLContext(
context,
'events.graphql'
);
return context.db_client.getEvents(input, {
tracingState: new TracingState(graphQLSpan),
});
},
actions: async (_, { input }, context) => {
const graphQLSpan = setSpanNameFromGraphQLContext(context, 'actions.graphql');
const graphQLSpan = setSpanNameFromGraphQLContext(
context,
'actions.graphql'
);
return context.db_client.getActions(input, {
tracingState: new TracingState(graphQLSpan),
});
},
networkState: async (_, __, context) => {
const graphQLSpan = setSpanNameFromGraphQLContext(context, 'networkState.graphql');
const graphQLSpan = setSpanNameFromGraphQLContext(
context,
'networkState.graphql'
);
return context.db_client.getNetworkState({
tracingState: new TracingState(graphQLSpan),
});
},
blocks: async (_, { query, limit, sortBy }, context) => {
const graphQLSpan = setSpanNameFromGraphQLContext(context, 'blocks.graphql');
const graphQLSpan = setSpanNameFromGraphQLContext(
context,
'blocks.graphql'
);
return context.db_client.getBlocks(query, limit, sortBy, {
tracingState: new TracingState(graphQLSpan),
});
Expand All @@ -41,7 +59,9 @@ let typeDefs: string | undefined = undefined;

// If the ENABLED_QUERIES environment variable is set, filter the schema and resolvers.
if (process.env.ENABLED_QUERIES !== undefined) {
const enabledQueries = process.env.ENABLED_QUERIES.split(',').map((q) => q.trim());
const enabledQueries = process.env.ENABLED_QUERIES.split(',').map((q) =>
q.trim()
);

// If the list is not empty, filter the resolvers.
if (enabledQueries.length > 0) {
Expand All @@ -54,7 +74,7 @@ if (process.env.ENABLED_QUERIES !== undefined) {
};

// Filter the schema AST.
const typeDefsString = fs.readFileSync('./schema.graphql', 'utf-8');
const typeDefsString = fs.readFileSync(graphqlSchemaPath, 'utf-8');
const typeDefsAst = parse(typeDefsString);
const modifiedAst = visit(typeDefsAst, {
ObjectTypeDefinition(node) {
Expand All @@ -76,7 +96,7 @@ if (process.env.ENABLED_QUERIES !== undefined) {
// Create the executable schema.
const schema = makeExecutableSchema({
resolvers: [resolvers],
typeDefs: typeDefs || fs.readFileSync('./schema.graphql', 'utf-8'),
typeDefs: typeDefs || fs.readFileSync(graphqlSchemaPath, 'utf-8'),
});

export { resolvers, schema };