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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### 1.47.0 - 2026-02-24
- Always use container relative URLs
- Remove ExperimentalFeatures.containerRelativeURL
- Update tests to assume container relative URLs
- Add justfile

### 1.46.1 - 2026-02-17
- Update Array filter multi-value delimiter to ';' to match IN/NOT IN filter types to allow filter type conversion

Expand Down
102 changes: 102 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Note: this justfile should work for anyone using MacOS, however with some work we can probably get it to also work on
# Windows if we use the [unix] and [windows] attributes on the commands that execute shell scripts:
# https://just.systems/man/en/attributes.html#enabling-and-disabling-recipes180

[private]
default:
just --list

currentBranch := `git branch --show-current`
branchAsTag := replace(currentBranch, '_', '-')
packageName := '@labkey/api'
pwd := `pwd`

# We quote the paths from our environment variables so these variables will work even if the paths contains spaces
# We trim the trailing / from our environment variables so we can treat them consistently with our other paths
components := quote(trim_end_match(env('LABKEY_UI_COMPONENTS_HOME'), '/') / 'packages/components')
premium := quote(trim_end_match(env('LABKEY_UI_PREMIUM_HOME'), '/'))
distPath := 'node_modules' / packageName / 'dist'
sourceDist := pwd / 'dist/'
modulesToBump := components + ' ' + premium
copyLocations := append('/' + distPath, modulesToBump)

# Builds the package
build:
npm run build

# Copies built package to NODE_MODULES directory for every module listed in copyLocations
copy:
#!/usr/bin/env zsh
set -euo pipefail
for module in {{ copyLocations }}; do
echo '{{ GREEN }}'Copying built package to '{{CYAN}}'$module'{{ NORMAL }}'
rsync -ra {{ sourceDist }} $module
done

# Builds the package and copies it to NODE_MODULES for every module listed in copyLocations
bc: build copy

# Bumps version to a prerelease version based on the current branch name
preVersion:
@echo {{ GREEN }}Bumping prerelease version with preid='{{CYAN}}'{{ branchAsTag }}{{ NORMAL }}
@npm version prerelease --preid {{ branchAsTag }} --no-git-tag-version

# Publishes the current version with the current branch name as a tag
publishPreVersion:
@echo {{ GREEN }}Publishing prerelease package{{ NORMAL }}
@npm publish --tag {{ branchAsTag }}

[private]
sleep:
@echo {{ GREEN }}"Sleeping so artifactory doesn't return 404"{{ NORMAL }}
@sleep 6

# Lists the modules in the 'modulesToBump' variable
listModules:
#!/usr/bin/env zsh
set -euo pipefail
for module in {{ modulesToBump }}; do
echo $module
done

# Stored as a string because we want to execute this when scripts are run, not when the justfile is evaluated, so we
# always have the most up to date version.
currentVersionImport := quote("require('./package.json').version")

# lists the current package version
version:
@echo $(node -p -e {{ currentVersionImport }})

# Bumps the @labkey/premium package to the current version in every module listed in the modulesToBump variable
bump:
#!/usr/bin/env zsh
set -euo pipefail
v=$(node -p -e {{ currentVersionImport }})
echo '{{ GREEN }}'Bumping {{ packageName }} to '{{CYAN}}'$v'{{ NORMAL }}'
for module in {{ modulesToBump }}; do
pushd $module
echo '{{ GREEN }}'Bumping {{ packageName }} in '{{CYAN}}'$(pwd)'{{ NORMAL }}'
npm install --legacy-peer-deps --save-exact {{ packageName }}@$v
popd
done

# Bumps the version to a prerelease version based on the current branch name, publishes the version, and bumps it in every module listed in modulesToBump
release: preVersion publishPreVersion sleep bump

# Bumps the major version
major:
npm version major --no-git-tag-version

# Bumps the minor version
minor:
npm version minor --no-git-tag-version

# Bumps the patch version
patch:
npm version patch --no-git-tag-version

# Publishes the current version, must be a production version
publish:
npm publish

pb: publish sleep bump
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/api",
"version": "1.46.1",
"version": "1.47.0",
"description": "JavaScript client API for LabKey Server",
"scripts": {
"build": "npm run build:dist && npm run build:docs",
Expand Down
4 changes: 2 additions & 2 deletions src/labkey/ActionURL.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ describe('ActionURL', () => {

it('should build the correct URL', () => {
const url = ActionURL.buildURL('project', 'getWebPart', 'MyContainer');
expect(url).toEqual('/project/MyContainer/getWebPart.view');
expect(url).toEqual('/MyContainer/project-getWebPart.view');
});

it('should build the correct URL with optional parameters', () => {
const params = { listId: 50, returnUrl: 'home', array: [10, 'li'] };
const url = ActionURL.buildURL('project', 'getWebPart', 'MyContainer', params);
expect(url).toEqual('/project/MyContainer/getWebPart.view?listId=50&returnUrl=home&array=10&array=li');
expect(url).toEqual('/MyContainer/project-getWebPart.view?listId=50&returnUrl=home&array=10&array=li');
});
});

Expand Down
11 changes: 3 additions & 8 deletions src/labkey/ActionURL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,10 @@ export function buildURL(
if (action.indexOf('.') == -1) {
action += '.view';
}
const query = queryString(parameters);

let newURL: string;
const { contextPath, experimental } = getServerContext();
if (experimental && experimental.containerRelativeURL) {
newURL = contextPath + containerPath + controller + '-' + action;
} else {
newURL = contextPath + '/' + controller + containerPath + action;
}
const query = queryString(parameters);
const { contextPath } = getServerContext();
let newURL = contextPath + containerPath + controller + '-' + action;

if (query) {
newURL += '?' + query;
Expand Down
10 changes: 5 additions & 5 deletions src/labkey/Assay.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('assayList.api requests', () => {
// Assert
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
url: '/assay/my/special/folder/assayList.api',
url: '/my/special/folder/assay-assayList.api',
})
);
});
Expand All @@ -59,7 +59,7 @@ describe('assayList.api requests', () => {
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
jsonData: { id: assayId },
url: '/assay/my/special/folder/assayList.api',
url: '/my/special/folder/assay-assayList.api',
})
);
});
Expand All @@ -78,7 +78,7 @@ describe('assayList.api requests', () => {
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
jsonData: { name: assayName },
url: '/assay/my/special/folder/assayList.api',
url: '/my/special/folder/assay-assayList.api',
})
);
});
Expand All @@ -97,7 +97,7 @@ describe('assayList.api requests', () => {
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
jsonData: { type: assayType },
url: '/assay/my/special/folder/assayList.api',
url: '/my/special/folder/assay-assayList.api',
})
);
});
Expand All @@ -117,7 +117,7 @@ describe('assayList.api requests', () => {
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
jsonData: { id, name, plateEnabled, status, type },
url: '/assay/assayList.api',
url: '/assay-assayList.api',
})
);
});
Expand Down
2 changes: 1 addition & 1 deletion src/labkey/Report.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('execute', () => {
// Assert
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
url: '/reports/execute.api',
url: '/reports-execute.api',
method: 'POST',
jsonData: {
reportId: 'db:123',
Expand Down
1 change: 0 additions & 1 deletion src/labkey/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export interface Project {
}

export enum ExperimentalFeatures {
containerRelativeURL = 'containerRelativeURL',
disableGuestAccount = 'disableGuestAccount',
}

Expand Down
16 changes: 8 additions & 8 deletions src/labkey/query/Rows.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('deleteRows', () => {
rows,
schemaName,
}),
url: '/query/deleteRows.api',
url: '/query-deleteRows.api',
})
);
});
Expand Down Expand Up @@ -69,7 +69,7 @@ describe('insertRows', () => {
rows,
schemaName,
}),
url: '/query/insertRows.api',
url: '/query-insertRows.api',
})
);
});
Expand All @@ -92,7 +92,7 @@ describe('insertRows', () => {
expect.objectContaining({
method: 'POST',
form: expect.anything(),
url: '/query/insertRows.api',
url: '/query-insertRows.api',
})
);
expect(requestSpy).toHaveBeenCalledWith(
Expand All @@ -117,7 +117,7 @@ describe('insertRows', () => {
expect.objectContaining({
method: 'POST',
form: expect.anything(),
url: '/query/insertRows.api',
url: '/query-insertRows.api',
})
);
});
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('updateRows', () => {
rows,
schemaName,
}),
url: '/query/updateRows.api',
url: '/query-updateRows.api',
})
);
});
Expand All @@ -169,7 +169,7 @@ describe('updateRows', () => {
expect.objectContaining({
method: 'POST',
form: expect.anything(),
url: '/query/updateRows.api',
url: '/query-updateRows.api',
})
);
expect(requestSpy).toHaveBeenCalledWith(
Expand Down Expand Up @@ -224,7 +224,7 @@ describe('saveRows', () => {
jsonData: expect.objectContaining({
commands,
}),
url: '/query/saveRows.api',
url: '/query-saveRows.api',
})
);
});
Expand Down Expand Up @@ -267,7 +267,7 @@ describe('saveRows', () => {
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
method: 'POST',
url: '/query/saveRows.api',
url: '/query-saveRows.api',
})
);
const form = requestSpy.mock.lastCall[0].form;
Expand Down
4 changes: 2 additions & 2 deletions src/labkey/query/SelectRows.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe('selectRows', () => {
expect(requestSpy).toHaveBeenCalledWith(
expect.objectContaining({
// default to container-free URL
url: '/query/getQuery.api',
url: '/query-getQuery.api',

// default to 'GET' request
method: 'GET',
Expand Down Expand Up @@ -138,7 +138,7 @@ describe('selectRows -- optional parameters', () => {

test('containerPath', () => {
const containerPath = '/container';
expect(selectRowsRequest({ containerPath })).toHaveProperty('url', '/query/container/getQuery.api');
expect(selectRowsRequest({ containerPath })).toHaveProperty('url', '/container/query-getQuery.api');
});

test('dataRegionName', () => {
Expand Down