Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #10396 from EtherealEngine/project-orgnames
Browse files Browse the repository at this point in the history
Project Orgname Support
  • Loading branch information
HexaField authored Aug 18, 2024
2 parents 76cda41 + 57ddebb commit fe208a9
Show file tree
Hide file tree
Showing 73 changed files with 619 additions and 353 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/branch-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
key: dir-${{github.sha}}
- run: npm run dev-docker
- run: npm run dev-reinit
- run: npm run check-errors
- run: npx lerna run --scope '@etherealengine/*' check-errors
timeout-minutes: 20

build-client:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/projects-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
uses: actions/checkout@v3
with:
repository: etherealengine/ee-development-test-suite
path: './packages/projects/projects/ee-development-test-suite'
path: './packages/projects/projects/etherealengine/ee-development-test-suite'
- name: Use Node.js
uses: actions/setup-node@v3
with:
Expand All @@ -43,7 +43,7 @@ jobs:
- run: cp .env.local.default .env.local
- run: npm install --production=false --loglevel notice --legacy-peer-deps
- run: npm run lint
- run: npm run check-errors
- run: npx lerna run --scope '@etherealengine/*' check-errors
- run: npm run check-eslint
- run: npm run dev-docker
- run: npm run dev-reinit
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"packages": [
"packages/*",
"packages/projects/projects/*"
"packages/projects/projects/**"
],
"version": "1.6.0",
"npmClient": "npm",
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"workspaces": [
"packages/*",
"packages/projects/projects/*"
"packages/projects/projects/**"
],
"keywords": [
"three",
Expand Down Expand Up @@ -41,10 +41,11 @@
"scripts": {
"build-client": "cd packages/client && npm run build",
"check": "npm run lint && npm run check-errors && npm run check-eslint && npm run test && npm run build-client",
"check-errors": "tsc --noemit && lerna run --scope '@etherealengine/*' check-errors && lerna run --ignore '@etherealengine/*' check-errors",
"check-errors": "lerna run --scope '@etherealengine/*' check-errors && lerna run --ignore '@etherealengine/*' check-errors",
"check-eslint": "eslint --quiet .",
"checkout-dev": "lerna exec 'git checkout dev' --parallel --no-bail",
"clean-node-modules": "npx rimraf node_modules && npx rimraf package-lock.json && npx lerna exec npx rimraf node_modules && npx lerna exec npx rimraf package-lock.json",
"clone-project": "cross-env ts-node --swc scripts/clone-project.ts",
"create-root-package-json": "cross-env ts-node --swc scripts/create-root-package-json",
"create-project": "cross-env ts-node --swc scripts/create-project",
"depcheck": "lerna exec --no-bail --stream -- depcheck",
Expand All @@ -57,7 +58,7 @@
"dev-docker": "cd scripts && ./start-containers.sh",
"dev-docker-windows": "cd scripts && docker-compose up -d && docker-compose up -d -f docker-compose-minio.yml",
"dev-tabs": "npm run dev-docker && cd scripts && ./dev-tabs.sh",
"fetch-projects": "lerna exec 'git fetch -p && git rebase' --parallel --ignore @etherealengine/* --no-bail",
"fetch-projects": "lerna exec 'git fetch -p && git rebase' --parallel --no-bail",
"dev-reinit": "./scripts/checkenv.sh && npm run dev-docker && cd packages/server && npm run dev-reinit-db",
"dev-server": "cd packages/server && npm run dev",
"dev-windows": "npm run dev-docker-windows && concurrently -n agones,server,client npm:dev-agones-silent npm:dev-server npm:dev-client",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default function ProjectTable(props: { search: string }) {
startIcon={<HiOutlineArrowPath />}
size="small"
className="mr-2 h-min whitespace-pre bg-theme-blue-secondary text-[#214AA6] disabled:opacity-50 dark:text-white"
disabled={project.name === 'default-project'}
disabled={project.name === 'etherealengine/default-project'}
onClick={() =>
PopoverState.showPopupover(
<AddEditProjectModal update={true} inputProject={project} onSubmit={handleProjectUpdate} />
Expand All @@ -135,7 +135,7 @@ export default function ProjectTable(props: { search: string }) {
startIcon={<GrGithub />}
size="small"
className="mr-2 h-min whitespace-pre bg-theme-blue-secondary text-[#214AA6] disabled:opacity-50 dark:text-white"
disabled={!project || !project.repositoryPath || project.name === 'default-project'}
disabled={!project || !project.repositoryPath || project.name === 'etherealengine/default-project'}
onClick={() => {
PopoverState.showPopupover(
<ConfirmDialog
Expand Down Expand Up @@ -202,7 +202,7 @@ export default function ProjectTable(props: { search: string }) {
startIcon={<HiOutlineTrash />}
size="small"
className="h-min whitespace-pre bg-theme-blue-secondary text-[#214AA6] disabled:opacity-50 dark:text-white"
disabled={project.name === 'default-project'}
disabled={project.name === 'etherealengine/default-project'}
onClick={() => {
PopoverState.showPopupover(
<ConfirmDialog
Expand Down Expand Up @@ -247,7 +247,7 @@ export default function ProjectTable(props: { search: string }) {
projectVersion: row.version,
enabled: (
<Toggle
disabled={row.name === 'default-project'}
disabled={row.name === 'etherealengine/default-project'}
value={row.enabled}
onChange={() => handleEnabledChange(row)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export default function UpdateEngineModal() {
</div>
<div className="grid gap-2">
{projectState.projects.value
.filter((project) => project.name !== 'default-project' && project.repositoryPath)
.filter((project) => project.name !== 'etherealengine/default-project' && project.repositoryPath)
.map((project) => (
<div key={project.id} className="border border-theme-primary bg-theme-surfaceInput px-3.5 py-5">
<Checkbox
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { config } from '@etherealengine/common/src/config'
import { avatarPath, userAvatarPath, UserID } from '@etherealengine/common/src/schema.type.module'
import { useFind, useGet } from '@etherealengine/spatial/src/common/functions/FeathersHooks'

export const DEFAULT_PROFILE_IMG_PLACEHOLDER = `${config.client.fileServer}/projects/default-project/assets/default-silhouette.svg`
export const DEFAULT_PROFILE_IMG_PLACEHOLDER = `${config.client.fileServer}/projects/etherealengine/default-project/assets/default-silhouette.svg`

export const useUserAvatarThumbnail = (userId?: UserID) => {
const userAvatar = useFind(userAvatarPath, {
Expand Down
17 changes: 9 additions & 8 deletions packages/common/src/regex/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ export const CSS_URL_REGEX = /(@import\s+["']([^"']+)["']|url\((?!['"]?(?:data):
export const ABSOLUTE_URL_PROTOCOL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/

/**
* Captures project name and asset path from a URL.
* Captures org name, project name and asset path from a URL.
* For eg: `/path/to/projects/project123/assets/images/logo.png` will capture following groups
* - `project123` => Group 1
* - `assets/images/logo.png` => Group 2
* - `@org123` => Group 1
* - `project123` => Group 2
* - `assets/images/logo.png` => Group 3
*/
export const STATIC_ASSET_REGEX = /^(?:.*\/(?:projects|static-resources)\/([^\/]*)\/((?:assets\/|).*)$)/
export const STATIC_ASSET_REGEX = /^(?:.*\/(?:projects|static-resources)\/([^\/]*)\/([^\/]*)\/((?:assets\/|).*)$)/

// =====================================================================
// ========================= ID Regex Patterns =========================
Expand Down Expand Up @@ -111,22 +112,22 @@ export const INSTALLATION_SIGNED_REGEX = /https:\/\/oauth2:[\w\d\s\-_][email protected]
/**
* This regex is used to match specific file paths or directory structures that start with `projects/`, followed by one or more valid characters (letters, digits, hyphens, underscores, or forward slashes), and end with `/assets/`
*/
export const ASSETS_REGEX = /projects\/[a-zA-Z0-9-_\/]+\/assets\//
export const ASSETS_REGEX = /projects\/+[a-zA-Z0-9-_@]+\/[a-zA-Z0-9-_]+\/assets\//

/**
* This regex matches strings that start with `projects/`, followed by one or more characters that can be letters, digits, hyphens, underscores, or forward slashes.
*/
export const PROJECT_REGEX = /projects\/[a-zA-Z0-9-_\/]+/
export const PROJECT_REGEX = /projects\/+[a-zA-Z0-9-_@]+\/[a-zA-Z0-9-_]/

/**
* This regex matches strings that start with `projects/`, followed by one or more characters that can be letters, digits, hyphens, underscores, or forward slashes, and then `/public/`.
*/
export const PROJECT_PUBLIC_REGEX = /projects\/[a-zA-Z0-9-_\/]+\/public\//
export const PROJECT_PUBLIC_REGEX = /projects\/+[a-zA-Z0-9-_@]+\/[a-zA-Z0-9-_]+\/public\//

/**
* This regex matches strings that start with `projects/`, followed by one or more characters that can be letters, digits, hyphens, underscores, or forward slashes, and then `/thumbnails/`.
*/
export const PROJECT_THUMBNAIL_REGEX = /projects\/[a-zA-Z0-9-_\/]+\/thumbnails\//
export const PROJECT_THUMBNAIL_REGEX = /projects\/+[a-zA-Z0-9-_@]+\/[a-zA-Z0-9-_]+\/thumbnails\//

export const VALID_PROJECT_NAME = /^(?!\s)[\w\-\s]+$/

Expand Down
67 changes: 36 additions & 31 deletions packages/common/tests/regex.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,39 +252,44 @@ describe('regex.test', () => {
it('should match static asset URLs', () => {
const positiveCases = [
{
url: 'https://example.com/projects/default-project/assets/images/logo.png',
url: 'https://example.com/projects/etherealengine/default-project/assets/images/logo.png',
orgName: 'etherealengine',
projectName: 'default-project',
assetPath: 'assets/images/logo.png'
},
{
url: 'https://example.com/static-resources/default-project/assets/images/logo.png',
url: 'https://example.com/static-resources/etherealengine/default-project/assets/images/logo.png',
orgName: 'etherealengine',
projectName: 'default-project',
assetPath: 'assets/images/logo.png'
},
{
url: 'https://example.com/projects/default-project/assets/animations/emotes.glb',
url: 'https://example.com/projects/etherealengine/default-project/assets/animations/emotes.glb',
orgName: 'etherealengine',
projectName: 'default-project',
assetPath: 'assets/animations/emotes.glb'
},
{
url: 'https://example.com/projects/default-project/assets/animations/locomotion.glb',
url: 'https://example.com/projects/etherealengine/default-project/assets/animations/locomotion.glb',
orgName: 'etherealengine',
projectName: 'default-project',
assetPath: 'assets/animations/locomotion.glb'
}
]
positiveCases.forEach(({ url, projectName, assetPath }) => {
positiveCases.forEach(({ url, orgName, projectName, assetPath }) => {
const match = STATIC_ASSET_REGEX.exec(url)
assert.ok(match, `Expected '${url}' to match STATIC_ASSET_REGEX`)
assert.equal(match?.[1], projectName, `Expected project name '${projectName}' in '${url}'. Found ${match?.[1]}`)
assert.equal(match?.[2], assetPath, `Expected asset path '${assetPath}' in '${url}'. Found ${match?.[2]}`)
assert.equal(match?.[1], orgName, `Expected org name name '${orgName}' in '${url}'. Found ${match?.[1]}`)
assert.equal(match?.[2], projectName, `Expected project name '${projectName}' in '${url}'. Found ${match?.[2]}`)
assert.equal(match?.[3], assetPath, `Expected asset path '${assetPath}' in '${url}'. Found ${match?.[3]}`)
})
})

it('should not match non-static asset URLs', () => {
const negativeCases = [
'https://example.com/static-resources/',
'https://example.com/project/subdir/assets',
'https://example.com/default-project/assets/animations/emotes.glb'
'https://example.com/etherealengine/default-project/assets/animations/emotes.glb'
]
negativeCases.forEach((url) => {
assert.doesNotMatch(url, STATIC_ASSET_REGEX, `Expected '${url}' to not match STATIC_ASSET_REGEX`)
Expand Down Expand Up @@ -581,9 +586,9 @@ describe('regex.test', () => {
describe('ASSETS_REGEX', () => {
it('should match assets URLs', () => {
const positiveCases = [
'https://example.com/projects/default-project/assets/images/logo.png',
'https://example.com/projects/default-project/assets/animations/emotes.glb',
'https://example.com/projects/default-project/assets/animations/locomotion.glb'
'https://example.com/projects/etherealengine/default-project/assets/images/logo.png',
'https://example.com/projects/etherealengine/default-project/assets/animations/emotes.glb',
'https://example.com/projects/etherealengine/default-project/assets/animations/locomotion.glb'
]
positiveCases.forEach((url) => {
assert.match(url, ASSETS_REGEX, `Expected '${url}' to match ASSETS_REGEX`)
Expand All @@ -592,9 +597,9 @@ describe('regex.test', () => {

it('should not match non-assets URLs', () => {
const negativeCases = [
'https://example.com/projects/default-project/scene.json',
'https://example.com/projects/default-project/assets',
'https://example.com/default-project/assets/animations/emotes.glb'
'https://example.com/projects/etherealengine/default-project/scene.json',
'https://example.com/projects/etherealengine/default-project/assets',
'https://example.com/etherealengine/default-project/assets/animations/emotes.glb'
]
negativeCases.forEach((url) => {
assert.doesNotMatch(url, ASSETS_REGEX, `Expected '${url}' to not match ASSETS_REGEX`)
Expand All @@ -605,9 +610,9 @@ describe('regex.test', () => {
describe('PROJECT_REGEX', () => {
it('should match valid project paths', () => {
const positiveCases = [
'projects/project123',
'projects/project-name',
'projects/project_name',
'projects/etherealengine/project123',
'projects/etherealengine/project-name',
'projects/etherealengine/project_name',
'projects/project/123',
'projects/project/abc_def'
]
Expand All @@ -630,9 +635,9 @@ describe('regex.test', () => {
describe('PROJECT_PUBLIC_REGEX', () => {
it('should match valid project paths', () => {
const positiveCases = [
'projects/project123/public/',
'projects/project-name/public/',
'projects/project_name/public/',
'projects/etherealengine/project123/public/',
'projects/etherealengine/project-name/public/',
'projects/etherealengine/project_name/public/',
'projects/project/123/public/',
'projects/project/abc_def/public/'
]
Expand All @@ -643,10 +648,10 @@ describe('regex.test', () => {

it('should not match invalid project paths', () => {
const negativeCases = [
'projects/project123/public', // (missing trailing slash)
'projects/project-name/private/', // (incorrect folder private instead of public)
'projects/project$name/public/', // (contains invalid character $)
'projects/project-@name/public/', // (contains invalid character @)
'projects/etherealengine/project123/public', // (missing trailing slash)
'projects/etherealengine/project-name/private/', // (incorrect folder private instead of public)
'projects/etherealengine/project$name/public/', // (contains invalid character $)
'projects/etherealengine/project-@name/public/', // (contains invalid character @)
'projects/' // (missing project name and /public/)
]
negativeCases.forEach((value) => {
Expand All @@ -658,9 +663,9 @@ describe('regex.test', () => {
describe('PROJECT_THUMBNAIL_REGEX', () => {
it('should match valid project thumbnail paths', () => {
const positiveCases = [
'projects/project123/thumbnails/',
'projects/project-name/thumbnails/',
'projects/project_name/thumbnails/',
'projects/etherealengine/project123/thumbnails/',
'projects/etherealengine/project-name/thumbnails/',
'projects/etherealengine/project_name/thumbnails/',
'projects/project/123/thumbnails/',
'projects/project/abc_def/thumbnails/'
]
Expand All @@ -671,10 +676,10 @@ describe('regex.test', () => {

it('should not match invalid project thumbnail paths', () => {
const negativeCases = [
'projects/project123/thumbnails', // (missing trailing slash)
'projects/project-name/private/', // (incorrect folder private instead of public)
'projects/project$name/thumbnails/', // (contains invalid character $)
'projects/project-@name/thumbnails/', // (contains invalid character @)
'projects/etherealengine/project123/thumbnails', // (missing trailing slash)
'projects/etherealengine/project-name/private/', // (incorrect folder private instead of public)
'projects/etherealengine/project$name/thumbnails/', // (contains invalid character $)
'projects/etherealengine/project-@name/thumbnails/', // (contains invalid character @)
'projects/' // (missing project name and /thumbnail/)
]
negativeCases.forEach((value) => {
Expand Down
Loading

0 comments on commit fe208a9

Please sign in to comment.