Skip to content

Commit cabd046

Browse files
authored
feat: coar notify US4, announce ingest (#1429)
* feat: coar notify US4, announce ingest * feat: split seed into per user story communities * proper syntax for seeding action configs w/ jsonata * wip * cleanup * implement $.pub.in * use css file for styles * add site.base * remove css field * remove default index generation * cleanup * lint * fix coar tests * formatting * fix types * unify in/out loading * collect pubs and iterate * cleaner types * lint fix * revert to site-builder fetch pattern * lint * remove site-builder/buildJournalSite * fix migration * drop table if exists * now this * lint
1 parent 7d07aff commit cabd046

86 files changed

Lines changed: 2927 additions & 3166 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/awsdeploy.yml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,3 @@ jobs:
6767
secrets:
6868
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
6969
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
70-
71-
deploy-site-builder:
72-
uses: ./.github/workflows/deploy-template.yml
73-
with:
74-
service: site-builder
75-
environment: ${{ inputs.environment }}
76-
proper-name: ${{ inputs.proper-name }}
77-
image-tag-override: ${{ inputs.image-tag-override }}
78-
secrets:
79-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
80-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

.github/workflows/ci.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,5 @@ jobs:
7373
if: matrix.task == 'test-run'
7474
run: pnpm test:setup
7575

76-
- name: Run migrations
77-
if: matrix.task == 'test-run'
78-
run: pnpm --filter core migrate-test
79-
8076
- name: Run task
8177
run: NODE_ENV=test pnpm ${{ matrix.task }}

.github/workflows/e2e.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ jobs:
101101
echo "core_label=$ECR_REGISTRY/${ECR_REPOSITORY_NAME_OVERRIDE:-$ECR_REPOSITORY_PREFIX-core}:$IMAGE_TAG" >> $GITHUB_OUTPUT
102102
echo "jobs_label=$ECR_REGISTRY/${ECR_REPOSITORY_NAME_OVERRIDE:-$ECR_REPOSITORY_PREFIX-jobs}:$IMAGE_TAG" >> $GITHUB_OUTPUT
103103
echo "base_label=$ECR_REGISTRY/$ECR_REPOSITORY_PREFIX:$IMAGE_TAG" >> $GITHUB_OUTPUT
104-
echo "site_builder_label=$ECR_REGISTRY/${ECR_REPOSITORY_NAME_OVERRIDE:-$ECR_REPOSITORY_PREFIX-site-builder}:$IMAGE_TAG" >> $GITHUB_OUTPUT
105104
106105
- name: Install dependencies
107106
run: pnpm install --frozen-lockfile --prefer-offline
@@ -125,7 +124,6 @@ jobs:
125124
run: pnpm integration:setup
126125
env:
127126
INTEGRATION_TESTS_IMAGE: ${{steps.label.outputs.core_label}}
128-
SITE_BUILDER_IMAGE: ${{steps.label.outputs.site_builder_label}}
129127
JOBS_IMAGE: ${{steps.label.outputs.jobs_label}}
130128

131129
- name: Log out Container ID for health check
@@ -147,7 +145,6 @@ jobs:
147145
run: docker compose -f docker-compose.test.yml --profile integration logs -t
148146
env:
149147
INTEGRATION_TESTS_IMAGE: ${{steps.label.outputs.core_label}}
150-
SITE_BUILDER_IMAGE: ${{steps.label.outputs.site_builder_label}}
151148
JOBS_IMAGE: ${{steps.label.outputs.jobs_label}}
152149

153150
- name: Upload core playwright snapshots artifact

.github/workflows/ecrbuild-all.yml

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ on:
2323
jobs-image:
2424
description: "Jobs image SHA"
2525
value: ${{ jobs.build-jobs.outputs.image-sha }}
26-
site-builder-image:
27-
description: "Site builder image SHA"
28-
value: ${{ jobs.build-site-builder.outputs.image-sha }}
2926

3027
jobs:
3128
emit-sha-tag:
@@ -77,13 +74,3 @@ jobs:
7774
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
7875
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
7976

80-
build-site-builder:
81-
uses: ./.github/workflows/ecrbuild-template.yml
82-
with:
83-
package: site-builder
84-
target: jobs
85-
publish_to_ghcr: ${{ inputs.publish_to_ghcr }}
86-
ghcr_image_name: platform-site-builder
87-
secrets:
88-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
89-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

.github/workflows/on_main.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ jobs:
6363
PLATFORM_IMAGE: ${{ needs.build-all.outputs.core-image }}
6464
JOBS_IMAGE: ${{ needs.build-all.outputs.jobs-image }}
6565
MIGRATIONS_IMAGE: ${{ needs.build-all.outputs.base-image }}
66-
SITE_BUILDER_IMAGE: ${{ needs.build-all.outputs.site-builder-image }}
6766
AWS_REGION: "us-east-1"
6867
ALWAYS_ON: "main"
6968
COMPOSE_FILES: docker-compose.preview.sandbox.yml

.github/workflows/on_pr.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,9 @@ jobs:
129129
# PLATFORM_IMAGE: 246372085946.dkr.ecr.us-east-1.amazonaws.com/pubpub-v7-core:2b9a81a279c4e405bbedcdbb697c897ded52fbc0
130130
# JOBS_IMAGE: 246372085946.dkr.ecr.us-east-1.amazonaws.com/pubpub-v7-jobs:c786662f4899de16a621e366a485eca5adda4d6a
131131
# MIGRATIONS_IMAGE: 246372085946.dkr.ecr.us-east-1.amazonaws.com/pubpub-v7:c786662f4899de16a621e366a485eca5adda4d6a
132-
# SITE_BUILDER_IMAGE: 246372085946.dkr.ecr.us-east-1.amazonaws.com/pubpub-v7-site-builder:c786662f4899de16a621e366a485eca5adda4d6a
133132
PLATFORM_IMAGE: ${{ needs.build-all.outputs.core-image }}
134133
JOBS_IMAGE: ${{ needs.build-all.outputs.jobs-image }}
135134
MIGRATIONS_IMAGE: ${{ needs.build-all.outputs.base-image }}
136-
SITE_BUILDER_IMAGE: ${{ needs.build-all.outputs.site-builder-image }}
137135
AWS_REGION: "us-east-1"
138136
COMPOSE_FILES: docker-compose.preview.pr.yml
139137
secrets:
@@ -155,7 +153,6 @@ jobs:
155153
PLATFORM_IMAGE: "x" # not used
156154
JOBS_IMAGE: "x" # not used
157155
MIGRATIONS_IMAGE: "x" # not used
158-
SITE_BUILDER_IMAGE: "x" # not used
159156
AWS_REGION: "us-east-1"
160157
secrets:
161158
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

.github/workflows/pull-preview.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ on:
1010
MIGRATIONS_IMAGE:
1111
required: true
1212
type: string
13-
SITE_BUILDER_IMAGE:
14-
required: true
15-
type: string
1613
AWS_REGION:
1714
required: true
1815
type: string
@@ -55,12 +52,10 @@ jobs:
5552
PLATFORM_IMAGE: ${{ inputs.PLATFORM_IMAGE }}
5653
JOBS_IMAGE: ${{ inputs.JOBS_IMAGE }}
5754
MIGRATIONS_IMAGE: ${{ inputs.MIGRATIONS_IMAGE }}
58-
SITE_BUILDER_IMAGE: ${{ inputs.SITE_BUILDER_IMAGE }}
5955
run: |
6056
sed -i "s|image: PLATFORM_IMAGE|image: $PLATFORM_IMAGE|" docker-compose.preview.yml
6157
sed -i "s|image: JOBS_IMAGE|image: $JOBS_IMAGE|" docker-compose.preview.yml
6258
sed -i "s|image: MIGRATIONS_IMAGE|image: $MIGRATIONS_IMAGE|" docker-compose.preview.yml
63-
sed -i "s|image: SITE_BUILDER_IMAGE|image: $SITE_BUILDER_IMAGE|" docker-compose.preview.yml
6459
sed -i "s|DATACITE_REPOSITORY_ID: DATACITE_REPOSITORY_ID|DATACITE_REPOSITORY_ID: ${{ secrets.PREVIEW_DATACITE_REPOSITORY_ID }}|" docker-compose.preview.yml
6560
sed -i "s|DATACITE_PASSWORD: DATACITE_PASSWORD|DATACITE_PASSWORD: ${{ secrets.PREVIEW_DATACITE_PASSWORD }}|" docker-compose.preview.yml
6661
sed -i "s|email someone@example.com|email dev@pubpub.org|" self-host/caddy/Caddyfile

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,6 @@ storybook-static
7272
./playwright
7373

7474
.local_data
75+
76+
# mock-notify store
77+
.notifications.json

core/actions/_lib/interpolationContext.ts

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,12 @@ export type InterpolationContextBase = {
2323
env: InterpolationEnv
2424
}
2525

26-
export type InterpolationContextWithPub = InterpolationContextBase & {
27-
pub: ReturnType<typeof createPubProxy>
28-
json?: Json
29-
}
30-
31-
export type InterpolationContextWithJson = InterpolationContextBase & {
32-
json: Json
26+
export type InterpolationContext = InterpolationContextBase & {
3327
pub?: ReturnType<typeof createPubProxy>
28+
json?: Json
29+
site?: { base: string }
3430
}
3531

36-
export type InterpolationContextWithBoth = InterpolationContextBase & {
37-
pub: ReturnType<typeof createPubProxy>
38-
json: Json
39-
}
40-
41-
export type InterpolationContext =
42-
| InterpolationContextWithPub
43-
| InterpolationContextWithJson
44-
| InterpolationContextWithBoth
45-
4632
type InterpolationCommunity = Pick<Communities, "id" | "name" | "slug" | "avatar">
4733

4834
type InterpolationStage = Pick<CommunityStage, "id" | "name">
@@ -107,7 +93,7 @@ type BuildInterpolationContextArgs =
10793
export function buildInterpolationContext(
10894
args: BuildInterpolationContextArgs
10995
): InterpolationContext {
110-
const baseContext: Omit<InterpolationContext, "json" | "pub"> = {
96+
const baseContext: Omit<InterpolationContext, "json" | "pub" | "site"> = {
11197
env: {
11298
PUBPUB_URL: args.env.PUBPUB_URL,
11399
},

core/actions/_lib/pubProxy.ts

Lines changed: 1 addition & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -1,201 +1 @@
1-
// import type { ProcessedPub } from "contracts"
2-
3-
// export const createPubProxy = (pub: ProcessedPub, communitySlug: string): any => {
4-
// const valuesMap = new Map<string, ProcessedPub["values"][number]>()
5-
6-
// // these are just so that if you do `$.values`/`$.out`/`$.fields` you can see what fields are available
7-
// const fields: Record<string, undefined> = {}
8-
// const relations: Record<string, undefined> = {}
9-
10-
// for (const value of pub.values) {
11-
// fields[value.fieldSlug] = undefined
12-
// fields[value.fieldSlug.replace(`${communitySlug}:`, "")] = undefined
13-
// if (value.relatedPub) {
14-
// relations[value.fieldSlug] = undefined
15-
// relations[value.fieldSlug.replace(`${communitySlug}:`, "")] = undefined
16-
// }
17-
// valuesMap.set(value.fieldSlug, value)
18-
// }
19-
20-
// const pubWithAdditionalFields = { ...pub, fields: undefined, out: relations }
21-
22-
// return new Proxy(pubWithAdditionalFields, {
23-
// get(target, prop) {
24-
// const propStr = String(prop)
25-
// const _lowerProp = propStr.toLowerCase()
26-
27-
// if (prop === "fields") {
28-
// return new Proxy(fields, {
29-
// get(_, fieldSlug: string) {
30-
// return fields[fieldSlug] || fields[fieldSlug.toLowerCase()]
31-
// },
32-
// })
33-
// }
34-
// if (prop === "values") {
35-
// return new Proxy(fields, {
36-
// get(_, fieldSlug: string) {
37-
// const lowerFieldSlug = fieldSlug.toLowerCase()
38-
// const val =
39-
// valuesMap.get(`${communitySlug}:${fieldSlug}`) ??
40-
// valuesMap.get(fieldSlug) ??
41-
// valuesMap.get(`${communitySlug}:${lowerFieldSlug}`) ??
42-
// valuesMap.get(lowerFieldSlug)
43-
// return val?.value
44-
// },
45-
// })
46-
// }
47-
48-
// if (prop === "out") {
49-
// return new Proxy(relations, {
50-
// get(_, fieldSlug: string) {
51-
// if (typeof fieldSlug !== "string") {
52-
// return undefined
53-
// }
54-
55-
// if (fieldSlug === "out") {
56-
// return relations
57-
// }
58-
59-
// const lowerFieldSlug = fieldSlug.toLowerCase()
60-
61-
// const val =
62-
// valuesMap.get(`${communitySlug}:${fieldSlug}`) ??
63-
// valuesMap.get(fieldSlug) ??
64-
// valuesMap.get(`${communitySlug}:${lowerFieldSlug}`) ??
65-
// valuesMap.get(lowerFieldSlug)
66-
// if (val && "relatedPub" in val && val.relatedPub) {
67-
// return createPubProxy(val.relatedPub, communitySlug)
68-
// }
69-
// return undefined
70-
// },
71-
// })
72-
// }
73-
74-
// if (prop === "in") {
75-
// return new Proxy(relations, {
76-
// get(_, fieldSlug: string) {
77-
// const _lowerFieldSlug = fieldSlug.toLowerCase()
78-
// // For "in", we look for pubs that point to this one via fieldSlug
79-
// // This proxy doesn't currently support "in" metadata easily as it's not pre-loaded in valuesMap in the same way.
80-
// // However, if we had it, we'd look it up here.
81-
// return undefined
82-
// },
83-
// })
84-
// }
85-
86-
// return target[prop as keyof typeof target]
87-
// },
88-
// })
89-
// }
90-
91-
import type { ProcessedPub } from "contracts"
92-
93-
// properties that should never be forwarded through the proxy
94-
const BLOCKED_PROPS = new Set([
95-
"then",
96-
"catch",
97-
"finally",
98-
"constructor",
99-
"__proto__",
100-
"prototype",
101-
"$$typeof",
102-
"toJSON",
103-
"valueOf",
104-
"toString",
105-
"hasOwnProperty",
106-
"isPrototypeOf",
107-
"propertyIsEnumerable",
108-
])
109-
110-
const isBlockedProp = (prop: string | symbol): boolean => {
111-
if (typeof prop === "symbol") return true
112-
return BLOCKED_PROPS.has(prop)
113-
}
114-
115-
// creates a proxy that allows case-insensitive lookup but also returns the full object when iterated
116-
const createLookupProxy = <T>(
117-
data: Record<string, T>,
118-
communitySlug: string
119-
): Record<string, T> => {
120-
return new Proxy(data, {
121-
get(target, prop) {
122-
if (isBlockedProp(prop)) return undefined
123-
const propStr = String(prop)
124-
// direct match
125-
if (propStr in target) return target[propStr]
126-
// try with community prefix
127-
const prefixed = `${communitySlug}:${propStr}`
128-
if (prefixed in target) return target[prefixed]
129-
// try lowercase
130-
const lower = propStr.toLowerCase()
131-
if (lower in target) return target[lower]
132-
const prefixedLower = `${communitySlug}:${lower}`
133-
if (prefixedLower in target) return target[prefixedLower]
134-
return undefined
135-
},
136-
has(target, prop) {
137-
if (isBlockedProp(prop)) return false
138-
return prop in target
139-
},
140-
ownKeys(target) {
141-
return Reflect.ownKeys(target)
142-
},
143-
getOwnPropertyDescriptor(target, prop) {
144-
return Object.getOwnPropertyDescriptor(target, prop)
145-
},
146-
})
147-
}
148-
149-
export const createPubProxy = (
150-
pub: ProcessedPub,
151-
communitySlug: string
152-
): Record<string, unknown> => {
153-
// build plain objects for all lookups
154-
const fields: Record<string, true> = {}
155-
const values: Record<string, unknown> = {}
156-
const out: Record<string, Record<string, unknown>> = {}
157-
158-
for (const v of pub.values) {
159-
const shortSlug = v.fieldSlug.replace(`${communitySlug}:`, "")
160-
// use short slug as primary key to avoid duplicates
161-
fields[shortSlug] = true
162-
values[shortSlug] = v.value
163-
164-
if (v.relatedPub) {
165-
out[shortSlug] = createPubProxy(v.relatedPub, communitySlug)
166-
}
167-
}
168-
169-
const fieldsProxy = createLookupProxy(fields, communitySlug)
170-
const valuesProxy = createLookupProxy(values, communitySlug)
171-
const outProxy = createLookupProxy(out, communitySlug)
172-
173-
// build the base object with all pub properties except values (which we override)
174-
const base: Record<string, unknown> = {}
175-
for (const key of Object.keys(pub)) {
176-
if (key === "values") continue
177-
base[key] = pub[key as keyof ProcessedPub]
178-
}
179-
180-
base.fields = fieldsProxy
181-
base.values = valuesProxy
182-
base.out = outProxy
183-
base.in = {} // not implemented yet
184-
185-
return new Proxy(base, {
186-
get(target, prop) {
187-
if (isBlockedProp(prop)) return undefined
188-
return target[prop as string]
189-
},
190-
has(target, prop) {
191-
if (isBlockedProp(prop)) return false
192-
return prop in target
193-
},
194-
ownKeys(target) {
195-
return Reflect.ownKeys(target)
196-
},
197-
getOwnPropertyDescriptor(target, prop) {
198-
return Object.getOwnPropertyDescriptor(target, prop)
199-
},
200-
})
201-
}
1+
export { createPubProxy, type IncomingRelations } from "contracts"

0 commit comments

Comments
 (0)