mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-13 11:20:40 -07:00
Compare commits
106
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
292a93b738 | ||
|
|
5b1658c823 | ||
|
|
b1f0260dcb | ||
|
|
4fdbce2459 | ||
|
|
e941378535 | ||
|
|
4548c11406 | ||
|
|
22ba21d63f | ||
|
|
85bd0d35a6 | ||
|
|
f8bb63a1bb | ||
|
|
c6a6ef1a1f | ||
|
|
6fb707f9c4 | ||
|
|
f03247d420 | ||
|
|
ebc8daeec9 | ||
|
|
21a822348f | ||
|
|
fce2899e88 | ||
|
|
e4aeb023fd | ||
|
|
542a75fd44 | ||
|
|
e443068cb9 | ||
|
|
fad00aa14e | ||
|
|
df27ac6947 | ||
|
|
834328b9cb | ||
|
|
22b5a12333 | ||
|
|
d141c4bdd2 | ||
|
|
53489641ac | ||
|
|
3b5627b040 | ||
|
|
612da52275 | ||
|
|
a0ea372764 | ||
|
|
a7da93ff0f | ||
|
|
513940dfa7 | ||
|
|
8f700ae10a | ||
|
|
55e144a029 | ||
|
|
6ca5376362 | ||
|
|
0983f2c420 | ||
|
|
12001b6161 | ||
|
|
7591ddc161 | ||
|
|
3b24f079ea | ||
|
|
bd571d19d1 | ||
|
|
47ddc1193b | ||
|
|
50253a98ca | ||
|
|
b12eb8ab4b | ||
|
|
4955e75be7 | ||
|
|
842b45c96a | ||
|
|
ea0eab93d1 | ||
|
|
76a7fb738e | ||
|
|
2b630353c4 | ||
|
|
8c7cef9f95 | ||
|
|
303a0d44b5 | ||
|
|
28ebe11d26 | ||
|
|
fdec831e5c | ||
|
|
490ff4309c | ||
|
|
e09657c52b | ||
|
|
d48ac56824 | ||
|
|
2b713b721d | ||
|
|
258780e9a8 | ||
|
|
18d55929e5 | ||
|
|
ccd83bc6bd | ||
|
|
306b070507 | ||
|
|
05223c4378 | ||
|
|
01029aba87 | ||
|
|
902a8e4c22 | ||
|
|
08421ea70c | ||
|
|
f816955704 | ||
|
|
1937aa1f1d | ||
|
|
4518a19588 | ||
|
|
dafdfbc849 | ||
|
|
3632623456 | ||
|
|
85f5b327fa | ||
|
|
9347586cb5 | ||
|
|
629d958b86 | ||
|
|
fe978c8cd9 | ||
|
|
8ff9aea8ce | ||
|
|
dd7616acb9 | ||
|
|
d75ac93390 | ||
|
|
2caeeda1c1 | ||
|
|
6ebf2ee427 | ||
|
|
3bd825afb0 | ||
|
|
67a5b229ca | ||
|
|
c1c72b53d5 | ||
|
|
30e364c7d0 | ||
|
|
8af682d2ca | ||
|
|
88aa63fd58 | ||
|
|
fce9fcfa68 | ||
|
|
45adbd7008 | ||
|
|
942944eae0 | ||
|
|
660d9be55f | ||
|
|
dc6a301387 | ||
|
|
803a0907fc | ||
|
|
4427ae1fb9 | ||
|
|
7009a054f3 | ||
|
|
b8e7e2d946 | ||
|
|
4c30c660ae | ||
|
|
d916981dad | ||
|
|
fc2731376f | ||
|
|
3bd8d2e557 | ||
|
|
5d91e3d2ef | ||
|
|
5facd99a27 | ||
|
|
3f4f328572 | ||
|
|
a7c94eeeb5 | ||
|
|
2222a1be87 | ||
|
|
bf425c3adb | ||
|
|
c0bc2de76e | ||
|
|
4759371102 | ||
|
|
e03e053362 | ||
|
|
d8691421b4 | ||
|
|
0b4e2a9979 | ||
|
|
e401a30972 |
+129
-3
@@ -321,8 +321,7 @@
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/2703309?v=4",
|
||||
"profile": "https://github.com/amit777",
|
||||
"contributions": [
|
||||
"code",
|
||||
"financial"
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -577,8 +576,135 @@
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jgarber623",
|
||||
"name": "Jason Garber",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/73866?v=4",
|
||||
"profile": "https://sixtwothree.org",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "NReilingh",
|
||||
"name": "Nick Reilingh",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2458645?v=4",
|
||||
"profile": "http://nickreilingh.com/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ebobby",
|
||||
"name": "Francisco Soto",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/170356?v=4",
|
||||
"profile": "http://ebobby.org",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "davidlj95",
|
||||
"name": "David LJ",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8050648?v=4",
|
||||
"profile": "https://www.davidlj95.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "RasmusWL",
|
||||
"name": "Rasmus Wriedt Larsen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1054041?v=4",
|
||||
"profile": "https://github.com/RasmusWL",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "brunodccarvalho",
|
||||
"name": "Bruno Carvalho",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/24962950?v=4",
|
||||
"profile": "https://github.com/brunodccarvalho",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "fupengl",
|
||||
"name": "傅鹏",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/20211964?v=4",
|
||||
"profile": "https://github.com/fupengl",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "joel-hamilton",
|
||||
"name": "Joel Hamilton",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12899024?v=4",
|
||||
"profile": "https://github.com/joel-hamilton",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "amedve",
|
||||
"name": "Max Medve",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/23156422?v=4",
|
||||
"profile": "https://github.com/amedve",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cossssmin",
|
||||
"name": "Cosmin Popovici",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1656595?v=4",
|
||||
"profile": "https://maizzle.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "admtnnr",
|
||||
"name": "Adam Tanner",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/27502?v=4",
|
||||
"profile": "https://github.com/admtnnr",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "GuillermoCasalCaro",
|
||||
"name": "Guillermo Casal Caro",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/18685581?v=4",
|
||||
"profile": "https://github.com/GuillermoCasalCaro",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jsoref",
|
||||
"name": "Josh Soref",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2119212?v=4",
|
||||
"profile": "https://github.com/jsoref",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "vrugtehagel",
|
||||
"name": "Koen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/41021050?v=4",
|
||||
"profile": "https://vrugtehagel.nl",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"skipCi": true
|
||||
"skipCi": true,
|
||||
"commitType": "docs"
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"prefer-const": 2,
|
||||
"no-unused-vars": "off",
|
||||
"indent": "off",
|
||||
"no-mixed-operators": "off",
|
||||
"no-dupe-class-members": "off",
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/indent": ["error", 2],
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Build
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
bundles:
|
||||
required: false
|
||||
type: string
|
||||
env:
|
||||
BUNDLES: ${{ inputs.bundles }}
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ inputs.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dist-${{ inputs.os }}
|
||||
path: dist
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -1,41 +0,0 @@
|
||||
name: Check
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
- name: Test
|
||||
run: |
|
||||
npm run lint
|
||||
TZ=Etc/GMT npm run test
|
||||
TZ=Asia/Shanghai npm run test
|
||||
TZ=America/New_York npm run test
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Performance
|
||||
run: |
|
||||
npm run perf:diff
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,28 @@
|
||||
name: CI Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'test'
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
lint:
|
||||
uses: ./.github/workflows/lint.yml
|
||||
test:
|
||||
needs: build
|
||||
uses: ./.github/workflows/test.yml
|
||||
coverage:
|
||||
uses: ./.github/workflows/coverage.yml
|
||||
performance:
|
||||
needs: build
|
||||
uses: ./.github/workflows/performance.yml
|
||||
with:
|
||||
os: ubuntu-latest
|
||||
docs:
|
||||
uses: ./.github/workflows/docs.yml
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Test Coverage
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
coverage:
|
||||
name: Test Coverage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Test
|
||||
run: npm run test:coverage
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -1,32 +1,30 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
docs:
|
||||
name: Docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '20'
|
||||
- name: Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
npm run build:docs
|
||||
- name: Publish
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: JamesIves/[email protected]
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: docs/public
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Lint
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Performance Check
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
type: string
|
||||
jobs:
|
||||
performance:
|
||||
name: Performance
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: dist-${{ inputs.os }}
|
||||
path: dist
|
||||
- name: Check Performance
|
||||
run: npm run perf:diff
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
@@ -0,0 +1,22 @@
|
||||
name: PR Build
|
||||
on: pull_request
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
lint:
|
||||
uses: ./.github/workflows/lint.yml
|
||||
test:
|
||||
needs: build
|
||||
uses: ./.github/workflows/test.yml
|
||||
coverage:
|
||||
uses: ./.github/workflows/coverage.yml
|
||||
performance:
|
||||
needs: build
|
||||
uses: ./.github/workflows/performance.yml
|
||||
with:
|
||||
os: ubuntu-latest
|
||||
@@ -1,15 +1,12 @@
|
||||
name: "PR Title Checker"
|
||||
|
||||
name: PR Check
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR title
|
||||
title:
|
||||
name: Check PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
@@ -6,32 +6,27 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build:dist
|
||||
- name: Test
|
||||
run: |
|
||||
npm run lint
|
||||
npm run test
|
||||
- name: Coverage
|
||||
uses: coverallsapp/[email protected]
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npx semantic-release
|
||||
run: |
|
||||
if [ ${{ github.ref == 'refs/heads/master' }} ]; then
|
||||
npx semantic-release
|
||||
else
|
||||
npx semantic-release --dry-run
|
||||
fi
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Test
|
||||
on: [workflow_dispatch, workflow_call]
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
timezone: [Etc/GMT, Asia/Shanghai, America/New_York]
|
||||
node-version: [22]
|
||||
include:
|
||||
- os: macos-latest
|
||||
timezone: America/New_York
|
||||
node-versoin: 22
|
||||
- os: ubuntu-latest
|
||||
timezone: Etc/GMT
|
||||
node-version: 16
|
||||
- os: ubuntu-latest
|
||||
timezone: Asia/Shanghai
|
||||
node-version: 15
|
||||
- os: ubuntu-latest
|
||||
timezone: Asia/Shanghai
|
||||
node-version: 14
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: dist-${{ matrix.os }}
|
||||
path: dist
|
||||
- name: Run Test
|
||||
run: TZ=${{ matrix.timezone }} npm test
|
||||
- name: Archive npm failure logs
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: npm-logs
|
||||
path: ~/.npm/_logs
|
||||
+5
-1
@@ -9,8 +9,12 @@ coverage/
|
||||
|
||||
# modules
|
||||
node_modules/
|
||||
|
||||
# tmp
|
||||
docs/public/js/liquid.browser.min.js
|
||||
docs/themes/navy/layout/partial/all-contributors.swig
|
||||
docs/themes/navy/layout/partial/financial-contributors.swig
|
||||
dist/
|
||||
demo/*/package-lock.json
|
||||
demo/*/yarn.json
|
||||
|
||||
# editors
|
||||
|
||||
+183
-4
@@ -1,3 +1,182 @@
|
||||
## [10.16.3](https://github.com/harttle/liquidjs/compare/v10.16.2...v10.16.3) (2024-08-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* support for NodeJS 15, fixes [#732](https://github.com/harttle/liquidjs/issues/732) ([4548c11](https://github.com/harttle/liquidjs/commit/4548c1140629bf270d163a403c2994d785c7f710))
|
||||
|
||||
## [10.16.2](https://github.com/harttle/liquidjs/compare/v10.16.1...v10.16.2) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* support for NodeJS 14 ([85bd0d3](https://github.com/harttle/liquidjs/commit/85bd0d35a6d949a02db49ba546407fe5be17db5e))
|
||||
|
||||
## [10.16.1](https://github.com/harttle/liquidjs/compare/v10.16.0...v10.16.1) (2024-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* parser throws on non-string input, [#726](https://github.com/harttle/liquidjs/issues/726) ([21a8223](https://github.com/harttle/liquidjs/commit/21a822348f3c315dae56fba2674ad3db0cf2f80d))
|
||||
|
||||
# [10.16.0](https://github.com/harttle/liquidjs/compare/v10.15.0...v10.16.0) (2024-07-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* locale support for date filter, [#567](https://github.com/harttle/liquidjs/issues/567) ([#723](https://github.com/harttle/liquidjs/issues/723)) ([e4aeb02](https://github.com/harttle/liquidjs/commit/e4aeb023fddf5ead90db209599cfd99450274658))
|
||||
|
||||
# [10.15.0](https://github.com/harttle/liquidjs/compare/v10.14.0...v10.15.0) (2024-07-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* report error for malformed else/elsif/endif/endfor, [#713](https://github.com/harttle/liquidjs/issues/713) ([22b5a12](https://github.com/harttle/liquidjs/commit/22b5a123333a066aaf7dff580df061e7cd6aa7b2))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* DoS prevention, [#250](https://github.com/harttle/liquidjs/issues/250) ([e443068](https://github.com/harttle/liquidjs/commit/e443068cb9281883ff0fe9f755a15f52ada4e7e2))
|
||||
* support in-memory template mapping, inspired by [@jg-rp](https://github.com/jg-rp) [#714](https://github.com/harttle/liquidjs/issues/714) ([df27ac6](https://github.com/harttle/liquidjs/commit/df27ac694739496982012432077fe28b1476662a))
|
||||
|
||||
# [10.14.0](https://github.com/harttle/liquidjs/compare/v10.13.1...v10.14.0) (2024-06-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* use drop `valueOf` when evaluated as condition ([#705](https://github.com/harttle/liquidjs/issues/705)) ([a7da93f](https://github.com/harttle/liquidjs/commit/a7da93ff0f2c1c66f9c85b45ffcc1326c23254c7))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support catching all errors, [#220](https://github.com/harttle/liquidjs/issues/220) ([#710](https://github.com/harttle/liquidjs/issues/710)) ([3b5627b](https://github.com/harttle/liquidjs/commit/3b5627b04072b1d6703ef5ba782a3a0f26fd2a60))
|
||||
|
||||
## [10.13.1](https://github.com/harttle/liquidjs/compare/v10.13.0...v10.13.1) (2024-05-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow liquidMethodMissing to return any supported value type ([#698](https://github.com/harttle/liquidjs/issues/698)) ([0983f2c](https://github.com/harttle/liquidjs/commit/0983f2c42012b2b97258d0cdcb07b6d43c904814))
|
||||
* isComparable full interface check ([#701](https://github.com/harttle/liquidjs/issues/701)) ([55e144a](https://github.com/harttle/liquidjs/commit/55e144a0298047349d55d8483a46b2513303d940))
|
||||
|
||||
# [10.13.0](https://github.com/harttle/liquidjs/compare/v10.12.0...v10.13.0) (2024-05-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* array_to_sentence_string and number_of_words filters from Jekyll, [#443](https://github.com/harttle/liquidjs/issues/443) ([50253a9](https://github.com/harttle/liquidjs/commit/50253a98caf5356d3c33e148be66f34fbe75a204))
|
||||
* date filters from Jekyll ([4955e75](https://github.com/harttle/liquidjs/commit/4955e75be7f38a3fd15e71f2c192cff6f0d6e2d5))
|
||||
* escape filters from Jekyll, [#443](https://github.com/harttle/liquidjs/issues/443) ([b12eb8a](https://github.com/harttle/liquidjs/commit/b12eb8ab4b58b002459725b6c0ed00159cdc15e6))
|
||||
* jsonify, inspect, to_integer, normalize_whitespace filters ([842b45c](https://github.com/harttle/liquidjs/commit/842b45c96a46290a1e1ba43fc5cc7a465f4ba9de))
|
||||
* slugify filter from Jekyll, [#443](https://github.com/harttle/liquidjs/issues/443) ([47ddc11](https://github.com/harttle/liquidjs/commit/47ddc1193b84bbdeb8d48457bb5aead24d5aff77))
|
||||
|
||||
# [10.12.0](https://github.com/harttle/liquidjs/compare/v10.11.1...v10.12.0) (2024-04-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* case/when array equality, [#673](https://github.com/harttle/liquidjs/issues/673) ([2b63035](https://github.com/harttle/liquidjs/commit/2b630353c478368cb36dbfcb38961b25bf48249e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* introduce where_exp filter from Jekyll ([8c7cef9](https://github.com/harttle/liquidjs/commit/8c7cef9f95cda765164ada8d58af7d402b3d3143))
|
||||
|
||||
## [10.11.1](https://github.com/harttle/liquidjs/compare/v10.11.0...v10.11.1) (2024-04-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow %Z for TimezoneDate, update docs accordingly [#684](https://github.com/harttle/liquidjs/issues/684) ([e09657c](https://github.com/harttle/liquidjs/commit/e09657c52b5e9920256d73f99455e2e81cadf065))
|
||||
* Allow `lenientIf` for multiple operands (issue [#682](https://github.com/harttle/liquidjs/issues/682)) ([#683](https://github.com/harttle/liquidjs/issues/683)) ([490ff43](https://github.com/harttle/liquidjs/commit/490ff4309cc231a25be23df5374a5d032aac144e))
|
||||
|
||||
# [10.11.0](https://github.com/harttle/liquidjs/compare/v10.10.2...v10.11.0) (2024-04-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* group_by/group_by_exp/find/find_exp from Jekyll, [#443](https://github.com/harttle/liquidjs/issues/443) ([2b713b7](https://github.com/harttle/liquidjs/commit/2b713b721d1f355309a70ebb5846169c6c03c523))
|
||||
* pop/shift/unshift filters from Jekyll ([258780e](https://github.com/harttle/liquidjs/commit/258780e9a87ce87534a6bb4336725cb1d38a2998))
|
||||
|
||||
## [10.10.2](https://github.com/harttle/liquidjs/compare/v10.10.1...v10.10.2) (2024-03-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* contains regression ([#677](https://github.com/harttle/liquidjs/issues/677)) ([05223c4](https://github.com/harttle/liquidjs/commit/05223c4378f9474f4e658af36cb8272e161d681f)), closes [#675](https://github.com/harttle/liquidjs/issues/675)
|
||||
|
||||
## [10.10.1](https://github.com/harttle/liquidjs/compare/v10.10.0...v10.10.1) (2024-02-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* in conditionals, don't render anything after an else branch ([#671](https://github.com/harttle/liquidjs/issues/671)) ([f816955](https://github.com/harttle/liquidjs/commit/f81695570491ede77975de2c26a07612a2d62c28))
|
||||
* Rely on equal for computing contains ([#668](https://github.com/harttle/liquidjs/issues/668)) ([1937aa1](https://github.com/harttle/liquidjs/commit/1937aa1f1dce01ee6332f39a6e658e85cbe4f30b))
|
||||
|
||||
# [10.10.0](https://github.com/harttle/liquidjs/compare/v10.9.4...v10.10.0) (2023-12-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Array sum filter ([#661](https://github.com/harttle/liquidjs/issues/661)) ([629d958](https://github.com/harttle/liquidjs/commit/629d958b86a97ddf2921d2285b7c9ea83430004e))
|
||||
|
||||
## [10.9.4](https://github.com/harttle/liquidjs/compare/v10.9.3...v10.9.4) (2023-11-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow unicode to be identifiers, fixes [#655](https://github.com/harttle/liquidjs/issues/655) ([dd7616a](https://github.com/harttle/liquidjs/commit/dd7616acb9a71b77f39d2fa24b6f68a7caef87f1))
|
||||
|
||||
## [10.9.3](https://github.com/harttle/liquidjs/compare/v10.9.2...v10.9.3) (2023-10-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* package version in released files ([67a5b22](https://github.com/harttle/liquidjs/commit/67a5b229ca9ccabb4aee42bbb5c9f03d4076786a))
|
||||
|
||||
## [10.9.2](https://github.com/harttle/liquidjs/compare/v10.9.1...v10.9.2) (2023-08-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* handle windows newlines on `newline_to_br` and `strip_newlines` ([88aa63f](https://github.com/harttle/liquidjs/commit/88aa63fd58b5a5824c031acc6f3e4072bedd262f))
|
||||
* sort and where bug when using `strictVariables` ([8af682d](https://github.com/harttle/liquidjs/commit/8af682d2ca68de99bafd4a7055e4912eeb318f57))
|
||||
|
||||
## [10.9.1](https://github.com/harttle/liquidjs/compare/v10.9.0...v10.9.1) (2023-08-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* map filter allow nil results in strict mode, fixes [#647](https://github.com/harttle/liquidjs/issues/647) ([45adbd7](https://github.com/harttle/liquidjs/commit/45adbd7008296a94da04d21a35917f744a0f4109))
|
||||
|
||||
# [10.9.0](https://github.com/harttle/liquidjs/compare/v10.8.4...v10.9.0) (2023-08-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* case should allow multiple values separated by or ([b8e7e2d](https://github.com/harttle/liquidjs/commit/b8e7e2d9467b17ca786e6fb422e9579dd178de76))
|
||||
* for throws undefined var with a null value with strictVariables ([dc6a301](https://github.com/harttle/liquidjs/commit/dc6a3013874872ac85f1fbe5184c74631122d851))
|
||||
* remove_last was eating an extra character ([fc27313](https://github.com/harttle/liquidjs/commit/fc2731376f8ef59ac7160f97cef1fb5d94f053db))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* more flexible squared property read expression, fixes [#643](https://github.com/harttle/liquidjs/issues/643) ([#646](https://github.com/harttle/liquidjs/issues/646)) ([660d9be](https://github.com/harttle/liquidjs/commit/660d9be55f8eac16ca5ac77fd0b38b0d7f94961e))
|
||||
|
||||
## [10.8.4](https://github.com/harttle/liquidjs/compare/v10.8.3...v10.8.4) (2023-07-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow quotes in inline comment tag, fixes [#628](https://github.com/harttle/liquidjs/issues/628) ([bf425c3](https://github.com/harttle/liquidjs/commit/bf425c3adb929e68fa234bee8397560a436595bb))
|
||||
|
||||
## [10.8.3](https://github.com/harttle/liquidjs/compare/v10.8.2...v10.8.3) (2023-06-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* strftime getSuffix works for all dates ([0b4e2a9](https://github.com/harttle/liquidjs/commit/0b4e2a99790347bea0ab5f7d651f2330e3054601))
|
||||
|
||||
## [10.8.2](https://github.com/harttle/liquidjs/compare/v10.8.1...v10.8.2) (2023-06-04)
|
||||
|
||||
|
||||
@@ -942,7 +1121,7 @@
|
||||
|
||||
* Tag#render now returns void, use emitter argument
|
||||
to write rendered html.
|
||||
* ship to Node.js 8, the dist/liquid.cjs.js (main) nolonger
|
||||
* ship to Node.js 8, the dist/liquid.cjs.js (main) no longer
|
||||
supports Node.js 6, other bundles are also provided via dist/liquid.esm.js, dist/liquid.js (ES5 umd) and liquid.min.js (minified ES5 umd)
|
||||
* remove default export, now should be used like import
|
||||
{Liquid} from 'liquidjs'
|
||||
@@ -987,7 +1166,7 @@ supports Node.js 6, other bundles are also provided via dist/liquid.esm.js, dist
|
||||
|
||||
### Features
|
||||
|
||||
* at_least, at_most, sort_naturual for [#132](https://github.com/harttle/liquidjs/issues/132) ([e6f5f1c](https://github.com/harttle/liquidjs/commit/e6f5f1c))
|
||||
* at_least, at_most, sort_natural for [#132](https://github.com/harttle/liquidjs/issues/132) ([e6f5f1c](https://github.com/harttle/liquidjs/commit/e6f5f1c))
|
||||
|
||||
# [8.3.0](https://github.com/harttle/liquidjs/compare/v8.2.4...v8.3.0) (2019-06-27)
|
||||
|
||||
@@ -1051,7 +1230,7 @@ supports Node.js 6, other bundles are also provided via dist/liquid.esm.js, dist
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* use polymophism instead duck test ([82d7673](https://github.com/harttle/liquidjs/commit/82d7673))
|
||||
* use polymorphism instead duck test ([82d7673](https://github.com/harttle/liquidjs/commit/82d7673))
|
||||
|
||||
## [8.0.1](https://github.com/harttle/liquidjs/compare/v8.0.0...v8.0.1) (2019-03-22)
|
||||
|
||||
@@ -1075,7 +1254,7 @@ supports Node.js 6, other bundles are also provided via dist/liquid.esm.js, dist
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Options and method names in JavaScript API are now renamed to cammelCase, for a complete list see #109
|
||||
* Options and method names in JavaScript API are now renamed to camelCase, for a complete list see #109
|
||||
|
||||
## [7.5.1](https://github.com/harttle/liquidjs/compare/v7.5.0...v7.5.1) (2019-03-05)
|
||||
|
||||
|
||||
+17
-25
@@ -16,14 +16,14 @@
|
||||
- Ensure the build runs because the Husky pre-commit hook checks it
|
||||
- `npm run check` checks runs the build, tests, lint and perf tests
|
||||
- `commitlint` checks the commit message format
|
||||
|
||||
|
||||
If there is a problem you will see it in the pre-commit hook output.
|
||||
In VS Code, this output will be shown in a new file in a new tab if the
|
||||
pre-commit hook fails.
|
||||
If you want to check the commit message without using the VS Code Source
|
||||
Control UI, you can run `echo "feat: my commit message" > npx commitlint`
|
||||
directly.
|
||||
|
||||
|
||||
- `git switch -c your_branch_name` (do this in your fork not the main repo)
|
||||
- `git add .`
|
||||
- `git commit -m "feat: Adding my change"`
|
||||
@@ -33,32 +33,24 @@
|
||||
## Playground
|
||||
|
||||
The Playground runs off the `docs` directory.
|
||||
`npm run:docs` is used to build it and that's included in `npm run build`.
|
||||
`npm run build:docs` is used to build it.
|
||||
|
||||
To start the site locally, go to `docs` and run `npm start`, then visit
|
||||
Then, to start the site locally, go to `docs` and run `npm start`, then visit
|
||||
http://localhost:4000/playground.html.
|
||||
|
||||
At the moment, the Playground uses the latest NPM version of the LiquidJS
|
||||
library instead of using the built artifact produced by `npm run build:dist`
|
||||
(also included in `npm run build`).
|
||||
The Playground uses a local built LiquidJS, which is created during `npm run build:docs`.
|
||||
To update that, you'll need to run `./bin/build-docs-liquid.sh` each time after making changes.
|
||||
Then refresh the Playground site for the changes to take effect.
|
||||
|
||||
To use the Playground with the local build of the library, make these changes:
|
||||
## Performance
|
||||
|
||||
- Copy `dist/liquid.browser.min.js` to `docs/public/js/liquid.browser.min.js`
|
||||
- Open `docs/themes/navy/layout/partial/after_footer.swig`
|
||||
- Remove `https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js` line
|
||||
- Add `{{ js('liquid.browser.min.js') }}` line before `{{ js('js/main') }}` line
|
||||
- Refresh the Playground site for the changes to take effect
|
||||
- Replace `liquid.browser.min.js` each time after making changes and building
|
||||
If your change can have a performance impact, you can update and run performance cases under `benchmark/`.
|
||||
|
||||
```diff
|
||||
{% if page.layout === 'playground' %}
|
||||
-<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-min/ace.js"></script>
|
||||
{% endif %}
|
||||
|
||||
+{{ js('js/liquid.browser.min.js') }}
|
||||
{{ js('js/main') }}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
||||
```
|
||||
1. `npm run build:cjs` to build a CommonJS bundle for the perf test.
|
||||
2. `npm run perf:diff` to check whether there's a regression compared against `liquidjs@latest`
|
||||
|
||||
Further more, `benchmark/` contains different cases to check its ops/sec. Useful when debugging perf regressions, to use it:
|
||||
|
||||
- `cd benchmark` go into benchmark project
|
||||
- `npm ci` install dependencies
|
||||
- `npm start` run the cases
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
[](https://www.npmjs.org/package/liquidjs)
|
||||
[](https://www.npmjs.org/package/liquidjs)
|
||||
[](https://coveralls.io/github/harttle/liquidjs?branch=master)
|
||||
[](https://github.com/harttle/liquidjs/actions/workflows/check.yml?query=branch%3Amaster)
|
||||
[](https://github.com/harttle/liquidjs/actions/workflows/ci-build.yml?query=branch%3Amaster)
|
||||
[](https://github.com/harttle/liquidjs/blob/master/LICENSE)
|
||||
[](https://github.com/harttle/liquidjs)
|
||||
|
||||
A simple, expressive and safe [Shopify][shopify/liquid] / Github Pages compatible template engine in pure JavaScript.
|
||||
**The purpose of this repo** is to provide a standard Liquid implementation for the JavaScript community so that [Jekyll sites](https://jekyllrb.com), [Github Pages](https://pages.github.com/) and [Shopify templates](https://themes.shopify.com/) can be ported to Node.js without pain.
|
||||
A simple, expressive and safe [Shopify][shopify/liquid] / GitHub Pages compatible template engine in pure JavaScript.
|
||||
**The purpose of this repo** is to provide a standard Liquid implementation for the JavaScript community so that [Jekyll sites](https://jekyllrb.com), [GitHub Pages](https://pages.github.com/) and [Shopify templates](https://themes.shopify.com/) can be ported to Node.js without pain.
|
||||
|
||||
* [Documentation][doc]
|
||||
* Please star [LiquidJS on GitHub][github]!
|
||||
* Support [LiquidJS on Open Collective][oc] or [Patreon][patreon]
|
||||
* Financial support via [GitHub Sponsors](https://github.com/sponsors/harttle).
|
||||
|
||||
<p align="center"><a href="https://liquidjs.com"><img height="155px" width="155px" src="https://liquidjs.com/icon/mstile-310x310.png" alt="logo"></a></p>
|
||||
|
||||
@@ -50,26 +50,49 @@ npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Snake"}'
|
||||
|
||||
For more details, refer to the [Setup Guide][setup].
|
||||
|
||||
## Related Projects
|
||||
## Who's Using LiquidJS?
|
||||
|
||||
* [@11ty/eleventy](https://www.npmjs.com/package/@11ty/eleventy): A simpler static site generator. An alternative to Jekyll. Written in JavaScript. Transforms a directory of templates (of varying types) into HTML.
|
||||
* [gulp-liquidjs](https://www.npmjs.com/package/@tuanpham-dev/gulp-liquidjs): A shopify compatible Liquid template engine for Gulp using liquidjs.
|
||||
* [grunt-liquify](https://www.npmjs.com/package/grunt-liquify): A Grunt task to process Liquid using liquidjs. Use it to add Liquid magic to your scripts and css assets.
|
||||
* [react-liquid](https://github.com/aquibm/react-liquid#readme): Liquid templating language component for React
|
||||
- [Eleventy](https://www.11ty.dev/): Eleventy, a simpler static site generator.
|
||||
- [Opensense](https://www.opensense.com/): The smarter way to send email.
|
||||
- [Directus](https://docs.directus.io/): an instant REST+GraphQL API and intuitive no-code data collaboration app for any SQL database.
|
||||
- [Semgrep](https://github.com/returntocorp/semgrep): Lightweight static analysis for many languages.
|
||||
- [Rock](https://www.rockrms.com/): An open source CMS, Relationship Management System (RMS) and Church Management System (ChMS) all rolled into one.
|
||||
- [Mitosis](https://github.com/BuilderIO/mitosis): Write components once, run everywhere. Compiles to React, Vue, Qwik, Solid, Angular, Svelte, and more.
|
||||
- [Pattern Lab](https://patternlab.io/): a frontend workshop environment that helps you build, view, test, and showcase your design system's UI components.
|
||||
- [Builder.io](https://www.builder.io/m/developers): the first and only headless CMS with a visual editor that lets you drag and drop with your components, directly within your current site or app. Completely API-driven, for cleaner code and simpler workflows.
|
||||
- [Microsoft Power Pages](https://learn.microsoft.com/en-us/power-pages/introduction): a secure, enterprise-grade, low-code software as a service (SaaS) platform for creating, hosting, and administering modern external-facing business websites.
|
||||
- [Azure API Management developer portal](https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-developer-portal): an automatically generated, fully customizable website with the documentation of your APIs.
|
||||
- [WISMOlabs](https://wismolabs.com/): Post Purchase Experience platform for eCommerce retailers enhancing customer satisfaction by using LiquidJS to provide customizable post-purchase experiences through programmable email, SMS, order tracking pages, and webhooks.
|
||||
|
||||
Feel free to create a PR or contact me to add your use case into this list!
|
||||
|
||||
## Financial Support
|
||||
|
||||
If you love LiquidJS or your company is using LiquidJS? Please consider [support us on Open Collective or Patreon][financial-support].
|
||||
If you personally love LiquidJS or it's benefiting your business, please consider financially support us via [GitHub Sponsors](https://github.com/sponsors/harttle). Special thanks to our sponsors!
|
||||
|
||||
### Backers
|
||||
If you personally like LiquidJS and find it useful to you, you can buy me a coffee!
|
||||
|
||||
<img src="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72">
|
||||
|
||||
### Sponsors
|
||||
If LiquidJS is benefiting your business/company, please sponsor us to contribute to our effort!
|
||||
|
||||
<img src="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72">
|
||||
<!-- FINANCIAL-CONTRIBUTORS-BEGIN -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.opensense.com/"><img src="https://images.opencollective.com/opensense-inc/bf840ae/logo/256.png?height=100" width="100px;" alt="Opensense Inc."/><br /><sub><b>Opensense</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.11ty.dev/"><img src="https://avatars.githubusercontent.com/u/35147177?v=4?s=100" width="100px;" alt="Eleventy"/><br /><sub><b>Eleventy</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt="Peter deHaan"/><br /><sub><b>Peter deHaan</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://opencollective.com/touchless"><img src="https://images.opencollective.com/touchless/273bc74/logo/256.png?height=100" width="100px;" alt="Touchless"/><br /><sub><b>Touchless</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.dropkiq.com/"><img src="https://images.opencollective.com/1bertlol/43a8ea8/logo/256.png?height=100" width="100px;" alt="Adam Darrah"/><br /><sub><b>Dropkiq</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://dailycontributors.com/"><img src="https://images.opencollective.com/dailycontributors/3c2e057/logo/256.png?height=100&width=100" width="100px;" alt="Dailycontributors"/><br /><sub><b>Dailycontributors</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/coni2k"><img src="https://avatars0.githubusercontent.com/u/1284601?v=4?s=100" width="100px;" alt="coni2k"/><br /><sub><b>Serkan Holat</b></sub></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt="amit777"/><br /><sub><b>amit777</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://opencollective.com/khaled-salem"><img src="https://images.opencollective.com/khaled-salem/avatar/256.png?height=256" width="100px;" alt="Khaled Salem"/><br /><sub><b>Khaled Salem</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://sentry.io/"><img src="https://avatars.githubusercontent.com/u/1396951?v=4?s=100" width="100px;" alt="Sentry"/><br /><sub><b>Sentry</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.checkoutblocks.com/"><img src="https://avatars.githubusercontent.com/u/114603307?v=4?s=100" width="100px;" alt="Checkout Blocks"/><br /><sub><b>Checkout Blocks</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://customer.io/"><img src="https://avatars.githubusercontent.com/u/1152079?v=4?s=100" width="100px;" alt="Customer IO"/><br /><sub><b>Customer IO</b></sub></a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/15fathoms"><img src="https://avatars.githubusercontent.com/u/79156039?v=4?s=100" width="100px;" alt="Emmanuel Cartelli"/><br /><sub><b>Emmanuel Cartelli</b></sub></a><br /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- FINANCIAL-CONTRIBUTORS-END -->
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
@@ -122,7 +145,7 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/IAmTrySound"><img src="https://avatars0.githubusercontent.com/u/5635476?v=4?s=100" width="100px;" alt="Bogdan Chadkin"/><br /><sub><b>Bogdan Chadkin</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TrySound" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://hightouch.io"><img src="https://avatars0.githubusercontent.com/u/5959235?v=4?s=100" width="100px;" alt="Tejas Manohar"/><br /><sub><b>Tejas Manohar</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=tejasmanohar" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://about.me/peterdehaan"><img src="https://avatars2.githubusercontent.com/u/557895?v=4?s=100" width="100px;" alt="Peter deHaan"/><br /><sub><b>Peter deHaan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=pdehaan" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt="amit777"/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a> <a href="#financial-amit777" title="Financial">💵</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amit777"><img src="https://avatars0.githubusercontent.com/u/2703309?v=4?s=100" width="100px;" alt="amit777"/><br /><sub><b>amit777</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amit777" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://www.ifi.uzh.ch/en/ce/people/schuldenzucker.html"><img src="https://avatars3.githubusercontent.com/u/1100776?v=4?s=100" width="100px;" alt="Steffen Schuldenzucker"/><br /><sub><b>Steffen Schuldenzucker</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=sschuldenzucker" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -159,6 +182,24 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bangank36"><img src="https://avatars.githubusercontent.com/u/10071857?v=4?s=100" width="100px;" alt="BaNgan"/><br /><sub><b>BaNgan</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=bangank36" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mahyar-pasarzangene"><img src="https://avatars.githubusercontent.com/u/16485039?v=4?s=100" width="100px;" alt="Mahyar Pasarzangene"/><br /><sub><b>Mahyar Pasarzangene</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=mahyar-pasarzangene" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://hubelbauer.net/"><img src="https://avatars.githubusercontent.com/u/6831144?v=4?s=100" width="100px;" alt="Tomáš Hübelbauer"/><br /><sub><b>Tomáš Hübelbauer</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Code">💻</a> <a href="https://github.com/harttle/liquidjs/commits?author=TomasHubelbauer" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://sixtwothree.org"><img src="https://avatars.githubusercontent.com/u/73866?v=4?s=100" width="100px;" alt="Jason Garber"/><br /><sub><b>Jason Garber</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jgarber623" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://nickreilingh.com/"><img src="https://avatars.githubusercontent.com/u/2458645?v=4?s=100" width="100px;" alt="Nick Reilingh"/><br /><sub><b>Nick Reilingh</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=NReilingh" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://ebobby.org"><img src="https://avatars.githubusercontent.com/u/170356?v=4?s=100" width="100px;" alt="Francisco Soto"/><br /><sub><b>Francisco Soto</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=ebobby" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.davidlj95.com"><img src="https://avatars.githubusercontent.com/u/8050648?v=4?s=100" width="100px;" alt="David LJ"/><br /><sub><b>David LJ</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=davidlj95" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RasmusWL"><img src="https://avatars.githubusercontent.com/u/1054041?v=4?s=100" width="100px;" alt="Rasmus Wriedt Larsen"/><br /><sub><b>Rasmus Wriedt Larsen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=RasmusWL" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/brunodccarvalho"><img src="https://avatars.githubusercontent.com/u/24962950?v=4?s=100" width="100px;" alt="Bruno Carvalho"/><br /><sub><b>Bruno Carvalho</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=brunodccarvalho" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fupengl"><img src="https://avatars.githubusercontent.com/u/20211964?v=4?s=100" width="100px;" alt="傅鹏"/><br /><sub><b>傅鹏</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=fupengl" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/joel-hamilton"><img src="https://avatars.githubusercontent.com/u/12899024?v=4?s=100" width="100px;" alt="Joel Hamilton"/><br /><sub><b>Joel Hamilton</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=joel-hamilton" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amedve"><img src="https://avatars.githubusercontent.com/u/23156422?v=4?s=100" width="100px;" alt="Max Medve"/><br /><sub><b>Max Medve</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=amedve" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://maizzle.com"><img src="https://avatars.githubusercontent.com/u/1656595?v=4?s=100" width="100px;" alt="Cosmin Popovici"/><br /><sub><b>Cosmin Popovici</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=cossssmin" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/admtnnr"><img src="https://avatars.githubusercontent.com/u/27502?v=4?s=100" width="100px;" alt="Adam Tanner"/><br /><sub><b>Adam Tanner</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=admtnnr" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GuillermoCasalCaro"><img src="https://avatars.githubusercontent.com/u/18685581?v=4?s=100" width="100px;" alt="Guillermo Casal Caro"/><br /><sub><b>Guillermo Casal Caro</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=GuillermoCasalCaro" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jsoref"><img src="https://avatars.githubusercontent.com/u/2119212?v=4?s=100" width="100px;" alt="Josh Soref"/><br /><sub><b>Josh Soref</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=jsoref" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://vrugtehagel.nl"><img src="https://avatars.githubusercontent.com/u/41021050?v=4?s=100" width="100px;" alt="Koen"/><br /><sub><b>Koen</b></sub></a><br /><a href="https://github.com/harttle/liquidjs/commits?author=vrugtehagel" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -173,7 +214,5 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
|
||||
[setup]: https://liquidjs.com/tutorials/setup.html
|
||||
[doc]: https://liquidjs.com
|
||||
[github]: https://github.com/harttle/liquidjs
|
||||
[patreon]: https://www.patreon.com/harttle
|
||||
[oc]: https://opencollective.com/liquidjs/
|
||||
[contribution]: https://liquidjs.com/tutorials/contribution-guidelines.html
|
||||
[financial-support]: https://liquidjs.com/tutorials/contribution-guidelines.html#Financial-Support
|
||||
|
||||
@@ -7,7 +7,7 @@ function createEngine (pkg) {
|
||||
cache: true,
|
||||
extname: '.liquid'
|
||||
})
|
||||
liquid.registerFilter('url', path => `http://example.com${path}`)
|
||||
liquid.registerFilter('url', path => `https://example.com${path}`)
|
||||
return {
|
||||
load: path => liquid.parse(readFileSync(path + '.liquid', 'utf8')),
|
||||
render: (tpl, data) => liquid.renderSync(tpl, data)
|
||||
|
||||
@@ -12,7 +12,7 @@ handlebars.registerHelper('concat', function (...args) {
|
||||
})
|
||||
|
||||
handlebars.registerHelper('url', function (path) {
|
||||
return `http://example.com${path}`
|
||||
return `https://example.com${path}`
|
||||
})
|
||||
|
||||
handlebars.registerHelper('inc', function (num) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const swig = require('swig')
|
||||
|
||||
swig.setFilter('url', function (path) {
|
||||
return `http://example.com${path}`
|
||||
return `https://example.com${path}`
|
||||
})
|
||||
|
||||
swig.setFilter('prepend', function (input, arg) {
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ function tag () {
|
||||
new Benchmark.Suite('tag')
|
||||
.add('if', test('{% if "foobar" %}foo{% endif %}'))
|
||||
.add('unless', test('{%unless "foo"%}true{%else%}false{%endunless%}'))
|
||||
.add('for', test('{% for i in (1..3) %}{{fooloop.index}}{% endfor %}'))
|
||||
.add('for', test('{% for i in (1..3) %}{{forloop.index}}{% endfor %}'))
|
||||
.add('switch', test('{%case 3%}{% when 1 %}1{% when 2 %}2{% when 3 %}3{%endcase%}'))
|
||||
.add('assign', test('{%assign a="foo bar"%}'))
|
||||
.add('capture', test('{%capture foo%}what is this{%endcapture%}'))
|
||||
|
||||
@@ -5,7 +5,7 @@ function capitalize (str) {
|
||||
return str[0].toUpperCase() + str.slice(1).toLowerCase()
|
||||
}
|
||||
function url (path) {
|
||||
return `http://example.com${path}`
|
||||
return `https://example.com${path}`
|
||||
}
|
||||
function renderTodoIcon (id) {
|
||||
return <img title="risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices" src="http://images.example.com/{id}.png"/>
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
rm -rf docs/source/api
|
||||
typedoc ./src --gitRevision master --out docs/source/api
|
||||
typedoc --plugin typedoc-plugin-missing-exports ./src --gitRevision master --out docs/source/api
|
||||
|
||||
+3
-14
@@ -1,17 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Run `sed` in a way that's compatible with both macOS (BSD) and Linux (GNU)
|
||||
sedi() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' "$@"
|
||||
else
|
||||
sed -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
cd docs
|
||||
cp ../CHANGELOG.md source/tutorials/changelog.md
|
||||
sedi \
|
||||
sed -i \
|
||||
-e 's/{%/{% raw %}{%{% endraw %}/g' \
|
||||
-e 's/{{/{% raw %}{{{% endraw %}/g' \
|
||||
-e '1 s/"/\"/g' \
|
||||
@@ -20,7 +11,5 @@ sedi \
|
||||
source/tutorials/changelog.md
|
||||
cp source/tutorials/changelog.md source/zh-cn/tutorials/changelog.md
|
||||
|
||||
sedi -e '1i\
|
||||
---\ntitle: Changelog\nauto: true\n---\n' source/tutorials/changelog.md
|
||||
sedi -e '1i\
|
||||
---\ntitle: 更新日志\nauto: true\n---\n' source/zh-cn/tutorials/changelog.md
|
||||
sed -i -e '1i\---\ntitle: Changelog\nauto: true\n---\n' source/tutorials/changelog.md
|
||||
sed -i -e '1i\---\ntitle: 更新日志\nauto: true\n---\n' source/zh-cn/tutorials/changelog.md
|
||||
|
||||
@@ -3,17 +3,24 @@
|
||||
# Run `sed` in a way that's compatible with both macOS (BSD) and Linux (GNU)
|
||||
sedi() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' "$@"
|
||||
/usr/bin/sed -i '' "$@"
|
||||
else
|
||||
sed -i "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
cp .all-contributorsrc docs/.all-contributorsrc
|
||||
sedi \
|
||||
-e 's/README.md/docs\/themes\/navy\/layout\/partial\/all-contributors.swig/g' \
|
||||
-e 's/"contributorsPerLine": 7/"contributorsPerLine": 65535/g' \
|
||||
docs/.all-contributorsrc
|
||||
# create docs/themes/navy/layout/partial/all-contributors.swig
|
||||
awk '/ALL-CONTRIBUTORS-LIST:START/{flag=1;next}/ALL-CONTRIBUTORS-LIST:END/{flag=0}flag' README.md | \
|
||||
sed 's/<br \/>.*<\/td>/<\/a><\/td>/g' | \
|
||||
sed 's/width="[^"]*"//g' | \
|
||||
tr -d '\n' | \
|
||||
sed 's/<\/tr>\s*<tr>//g' \
|
||||
> docs/themes/navy/layout/partial/all-contributors.swig
|
||||
|
||||
all-contributors --config docs/.all-contributorsrc generate
|
||||
sedi 's/<br \/>.*<\/td>/<\/a><\/td>/g' docs/themes/navy/layout/partial/all-contributors.swig
|
||||
# create docs/themes/navy/layout/partial/financial-contributors.swig
|
||||
awk '/FINANCIAL-CONTRIBUTORS-BEGIN/{flag=1;next}/FINANCIAL-CONTRIBUTORS-END/{flag=0}flag' README.md | \
|
||||
sed 's/<br \/>.*<\/td>/<\/a><\/td>/g' | \
|
||||
sed 's/width="[^"]*"//g' | \
|
||||
tr -d '\n' | \
|
||||
sed 's/<\/tr>\s*<tr>//g' \
|
||||
> docs/themes/navy/layout/partial/financial-contributors.swig
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUNDLES=min npm run build
|
||||
mkdir -p docs/public/js/
|
||||
cp dist/liquid.browser.min.js docs/public/js/
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
set -ex
|
||||
|
||||
./bin/build-docs-liquid.sh
|
||||
./bin/build-contributors.sh
|
||||
./bin/build-apidoc.sh
|
||||
./bin/build-changelog.sh
|
||||
|
||||
Regular → Executable
+12
-4
@@ -4,18 +4,19 @@ const isQuote = c => c === '"' || c === "'"
|
||||
const isOperator = c => '!=<>'.includes(c)
|
||||
const isNumber = c => c >= '0' && c <= '9'
|
||||
const isCharacter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|
||||
const isIdentifier = c => '_-?'.includes(c) || isCharacter(c) || isNumber(c)
|
||||
const isBlank = c => c === '\n' || c === '\t' || c === ' ' || c === '\r' || c === '\v' || c === '\f'
|
||||
const isWord = c => '_-?'.includes(c) || isCharacter(c) || isNumber(c)
|
||||
const isBlank = c => '\n\t \r\v\f'.includes(c)
|
||||
const isInlineBlank = c => c === '\t' || c === ' ' || c === '\r'
|
||||
const isSign = c => c === '-' || c === '+'
|
||||
// See https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
||||
const unicodeBlanks = '\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000'
|
||||
const unicodePunctuation = '“”'
|
||||
|
||||
const types = []
|
||||
for (let i = 0; i < 128; i++) {
|
||||
const c = String.fromCharCode(i)
|
||||
let n = 0
|
||||
if (isIdentifier(c)) n |= 1
|
||||
if (isWord(c)) n |= 1
|
||||
if (isOperator(c)) n |= 2
|
||||
if (isBlank(c)) n |= 4
|
||||
if (isQuote(c)) n |= 8
|
||||
@@ -31,13 +32,20 @@ console.log(`
|
||||
// This file is generated by bin/character-gen.js
|
||||
// bitmask character types to boost performance
|
||||
export const TYPES = [${types.join(', ')}]
|
||||
export const IDENTIFIER = 1
|
||||
export const WORD = 1
|
||||
export const OPERATOR = 2
|
||||
export const BLANK = 4
|
||||
export const QUOTE = 8
|
||||
export const INLINE_BLANK = 16
|
||||
export const NUMBER = 32
|
||||
export const SIGN = 64
|
||||
export const PUNCTUATION = 128
|
||||
|
||||
export function isWord (char: string): boolean {
|
||||
const code = char.charCodeAt(0)
|
||||
return code >= 128 ? !TYPES[code] : !!(TYPES[code] & WORD)
|
||||
}
|
||||
`.trim())
|
||||
|
||||
console.log([...unicodeBlanks].map(char => `TYPES[${char.charCodeAt(0)}]`).join(' = ') + ' = BLANK')
|
||||
console.log([...unicodePunctuation].map(char => `TYPES[${char.charCodeAt(0)}]`).join(' = ') + ' = PUNCTUATION')
|
||||
|
||||
+2
-6
@@ -1,16 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
VERSION_LATEST=$(cat package.json | grep '"version":' | awk -F'"' '{print $4}')
|
||||
VERSION_LATEST=$(cat package.json | grep '"version":' | head -1 | awk -F'"' '{print $4}')
|
||||
FILE_LOCAL=dist/liquid.node.cjs.js
|
||||
FILE_LATEST=dist/liquid.node.cjs.$VERSION_LATEST.js
|
||||
URL_LATEST=https://unpkg.com/liquidjs@$VERSION_LATEST/dist/liquid.node.cjs.js
|
||||
|
||||
if [ ! -f $FILE_LATEST ]; then
|
||||
if [ ! -f "$FILE_LATEST" ]; then
|
||||
curl $URL_LATEST > $FILE_LATEST
|
||||
fi
|
||||
|
||||
# if [ ! -f $FILE_LOCAL ]; then
|
||||
BUNDLES=cjs npm run build:dist
|
||||
# fi
|
||||
|
||||
exec node benchmark/diff.js $FILE_LOCAL $FILE_LATEST
|
||||
|
||||
Generated
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "liquidjs-demo-nodejs",
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"hello-liquid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hello-liquid/-/hello-liquid-1.0.0.tgz",
|
||||
"integrity": "sha512-WNmZp5s647BN2WHPq4FHVH85CcqNVet5DXIVw1UtVMaV+MJHFA+ylge0hqHSw0iOI/Ojrx8KEKZurYZix5PekQ=="
|
||||
},
|
||||
"liquidjs": {
|
||||
"version": "9.42.0",
|
||||
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.42.0.tgz",
|
||||
"integrity": "sha512-krvhwGFrMCMGhybGkxJIvlWVVnoCSpYCn7NhEN43+uvlg2vOkYWpq8be+L3NMlOfwe4ZrKQ7hCh1EmS4yhLKow=="
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "liquidjs-demo-nodejs",
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"liquidjs": {
|
||||
"version": "9.32.1",
|
||||
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.32.1.tgz",
|
||||
"integrity": "sha512-U/ymmm4M3sNJszHlF0Gzneky17qk+vWmu3nFkWKdniQhqaZNk6eZQdbcKkFGFPN4I9ijrBRjDsLBLysu292j8w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
-41
@@ -381,7 +381,7 @@ This works for any library, not just `react-router-dom`.
|
||||
## Importing a Component
|
||||
|
||||
This project setup supports ES6 modules thanks to Webpack.<br>
|
||||
While you can still use `require()` and `module.exports`, we encourage you to use [`import` and `export`](http://exploringjs.com/es6/ch_modules.html) instead.
|
||||
While you can still use `require()` and `module.exports`, we encourage you to use [`import` and `export`](https://exploringjs.com/es6/ch_modules.html) instead.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -414,7 +414,7 @@ class DangerButton extends Component {
|
||||
export default DangerButton;
|
||||
```
|
||||
|
||||
Be aware of the [difference between default and named exports](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281). It is a common source of mistakes.
|
||||
Be aware of the [difference between default and named exports](https://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281). It is a common source of mistakes.
|
||||
|
||||
We suggest that you stick to using default imports and exports when a module only exports a single thing (for example, a component). That’s what you get when you use `export default Button` and `import Button from './Button'`.
|
||||
|
||||
@@ -422,15 +422,15 @@ Named exports are useful for utility modules that export several functions. A mo
|
||||
|
||||
Learn more about ES6 modules:
|
||||
|
||||
- [When to use the curly braces?](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281)
|
||||
- [Exploring ES6: Modules](http://exploringjs.com/es6/ch_modules.html)
|
||||
- [When to use the curly braces?](https://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281)
|
||||
- [Exploring ES6: Modules](https://exploringjs.com/es6/ch_modules.html)
|
||||
- [Understanding ES6: Modules](https://leanpub.com/understandinges6/read#leanpub-auto-encapsulating-code-with-modules)
|
||||
|
||||
## Code Splitting
|
||||
|
||||
Instead of downloading the entire app before users can use it, code splitting allows you to split your code into small chunks which you can then load on demand.
|
||||
|
||||
This project setup supports code splitting via [dynamic `import()`](http://2ality.com/2017/01/import-operator.html#loading-code-on-demand). Its [proposal](https://github.com/tc39/proposal-dynamic-import) is in stage 3. The `import()` function-like form takes the module name as an argument and returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which always resolves to the namespace object of the module.
|
||||
This project setup supports code splitting via [dynamic `import()`](https://2ality.com/2017/01/import-operator.html#loading-code-on-demand). Its [proposal](https://github.com/tc39/proposal-dynamic-import) is in stage 3. The `import()` function-like form takes the module name as an argument and returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which always resolves to the namespace object of the module.
|
||||
|
||||
Here is an example:
|
||||
|
||||
@@ -476,7 +476,7 @@ You can also use it with `async` / `await` syntax if you prefer it.
|
||||
|
||||
### With React Router
|
||||
|
||||
If you are using React Router check out [this tutorial](http://serverless-stack.com/chapters/code-splitting-in-create-react-app.html) on how to use code splitting with it. You can find the companion GitHub repository [here](https://github.com/AnomalyInnovations/serverless-stack-demo-client/tree/code-splitting-in-create-react-app).
|
||||
If you are using React Router check out [this tutorial](https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html) on how to use code splitting with it. You can find the companion GitHub repository [here](https://github.com/AnomalyInnovations/serverless-stack-demo-client/tree/code-splitting-in-create-react-app).
|
||||
|
||||
Also check out the [Code Splitting](https://reactjs.org/docs/code-splitting.html) section in React documentation.
|
||||
|
||||
@@ -602,7 +602,7 @@ This project setup minifies your CSS and adds vendor prefixes to it automaticall
|
||||
|
||||
Support for new CSS features like the [`all` property](https://developer.mozilla.org/en-US/docs/Web/CSS/all), [`break` properties](https://www.w3.org/TR/css-break-3/#breaking-controls), [custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables), and [media query ranges](https://www.w3.org/TR/mediaqueries-4/#range-context) are automatically polyfilled to add support for older browsers.
|
||||
|
||||
You can customize your target support browsers by adjusting the `browserslist` key in `package.json` accoring to the [Browserslist specification](https://github.com/browserslist/browserslist#readme).
|
||||
You can customize your target support browsers by adjusting the `browserslist` key in `package.json` according to the [Browserslist specification](https://github.com/browserslist/browserslist#readme).
|
||||
|
||||
For example, this:
|
||||
|
||||
@@ -671,7 +671,7 @@ This works in CSS too:
|
||||
}
|
||||
```
|
||||
|
||||
Webpack finds all relative module references in CSS (they start with `./`) and replaces them with the final paths from the compiled bundle. If you make a typo or accidentally delete an important file, you will see a compilation error, just like when you import a non-existent JavaScript module. The final filenames in the compiled bundle are generated by Webpack from content hashes. If the file content changes in the future, Webpack will give it a different name in production so you don’t need to worry about long-term caching of assets.
|
||||
Webpack finds all relative module references in CSS (they start with `./`) and replaces them with the final paths from the compiled bundle. If you make a typo or accidentally delete an important file, you will see a compilation error, just like when you import a nonexistent JavaScript module. The final filenames in the compiled bundle are generated by Webpack from content hashes. If the file content changes in the future, Webpack will give it a different name in production so you don’t need to worry about long-term caching of assets.
|
||||
|
||||
Please be advised that this is also a custom feature of Webpack.
|
||||
|
||||
@@ -755,7 +755,7 @@ The `public` folder is useful as a workaround for a number of less common cases:
|
||||
|
||||
- You need a file with a specific name in the build output, such as [`manifest.webmanifest`](https://developer.mozilla.org/en-US/docs/Web/Manifest).
|
||||
- You have thousands of images and need to dynamically reference their paths.
|
||||
- You want to include a small script like [`pace.js`](http://github.hubspot.com/pace/docs/welcome/) outside of the bundled code.
|
||||
- You want to include a small script like [`pace.js`](https://github.hubspot.com/pace/docs/welcome/) outside of the bundled code.
|
||||
- Some library may be incompatible with Webpack and you have no other option but to include it as a `<script>` tag.
|
||||
|
||||
Note that if you add a `<script>` that declares global variables, you also need to read the next section on using them.
|
||||
@@ -813,7 +813,7 @@ Now you are ready to use the imported reactstrap components within your componen
|
||||
Sometimes you might need to tweak the visual styles of Bootstrap (or equivalent package).<br>
|
||||
As of `[email protected]` you can import `.scss` files. This makes it possible to use a package's built-in Sass variables for global style preferences.
|
||||
|
||||
To customize Bootstrap, create a file called `src/custom.scss` (or similar) and import the Bootstrap source stylesheet. Add any overrides _before_ the imported file(s). You can reference [Bootstrap's documentation](http://getbootstrap.com/docs/4.1/getting-started/theming/#css-variables) for the names of the available variables.
|
||||
To customize Bootstrap, create a file called `src/custom.scss` (or similar) and import the Bootstrap source stylesheet. Add any overrides _before_ the imported file(s). You can reference [Bootstrap's documentation](https://getbootstrap.com/docs/4.1/getting-started/theming/#css-variables) for the names of the available variables.
|
||||
|
||||
```scss
|
||||
// Override default variables before the import
|
||||
@@ -1138,7 +1138,7 @@ To tell the development server to proxy any unknown requests to your API server
|
||||
|
||||
This way, when you `fetch('/api/todos')` in development, the development server will recognize that it’s not a static asset, and will proxy your request to `http://localhost:4000/api/todos` as a fallback. The development server will **only** attempt to send requests without `text/html` in its `Accept` header to the proxy.
|
||||
|
||||
Conveniently, this avoids [CORS issues](http://stackoverflow.com/questions/21854516/understanding-ajax-cors-and-security-considerations) and error messages like this in development:
|
||||
Conveniently, this avoids [CORS issues](https://stackoverflow.com/questions/21854516/understanding-ajax-cors-and-security-considerations) and error messages like this in development:
|
||||
|
||||
```
|
||||
Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
|
||||
@@ -1150,7 +1150,7 @@ The `proxy` option supports HTTP, HTTPS and WebSocket connections.<br>
|
||||
If the `proxy` option is **not** flexible enough for you, alternatively you can:
|
||||
|
||||
- [Configure the proxy yourself](#configuring-the-proxy-manually)
|
||||
- Enable CORS on your server ([here’s how to do it for Express](http://enable-cors.org/server_expressjs.html)).
|
||||
- Enable CORS on your server ([here’s how to do it for Express](https://enable-cors.org/server_expressjs.html)).
|
||||
- Use [environment variables](#adding-custom-environment-variables) to inject the right server host and port into your app.
|
||||
|
||||
### "Invalid Host Header" Errors After Configuring Proxy
|
||||
@@ -1324,7 +1324,7 @@ When you run `npm test`, Jest will launch in the watch mode. Every time you save
|
||||
|
||||
The watcher includes an interactive command-line interface with the ability to run all tests, or focus on a search pattern. It is designed this way so that you can keep it open and enjoy fast re-runs. You can learn the commands from the “Watch Usage” note that the watcher prints after every run:
|
||||
|
||||

|
||||

|
||||
|
||||
### Version Control Integration
|
||||
|
||||
@@ -1373,7 +1373,7 @@ This test mounts a component and makes sure that it didn’t throw during render
|
||||
|
||||
When you encounter bugs caused by changing components, you will gain a deeper insight into which parts of them are worth testing in your application. This might be a good time to introduce more specific tests asserting specific expected output or behavior.
|
||||
|
||||
If you’d like to test components in isolation from the child components they render, we recommend using [`shallow()` rendering API](http://airbnb.io/enzyme/docs/api/shallow.html) from [Enzyme](http://airbnb.io/enzyme/). To install it, run:
|
||||
If you’d like to test components in isolation from the child components they render, we recommend using [`shallow()` rendering API](https://airbnb.io/enzyme/docs/api/shallow.html) from [Enzyme](https://airbnb.io/enzyme/). To install it, run:
|
||||
|
||||
```sh
|
||||
npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
|
||||
@@ -1412,9 +1412,9 @@ it('renders without crashing', () => {
|
||||
});
|
||||
```
|
||||
|
||||
Unlike the previous smoke test using `ReactDOM.render()`, this test only renders `<App>` and doesn’t go deeper. For example, even if `<App>` itself renders a `<Button>` that throws, this test will pass. Shallow rendering is great for isolated unit tests, but you may still want to create some full rendering tests to ensure the components integrate correctly. Enzyme supports [full rendering with `mount()`](http://airbnb.io/enzyme/docs/api/mount.html), and you can also use it for testing state changes and component lifecycle.
|
||||
Unlike the previous smoke test using `ReactDOM.render()`, this test only renders `<App>` and doesn’t go deeper. For example, even if `<App>` itself renders a `<Button>` that throws, this test will pass. Shallow rendering is great for isolated unit tests, but you may still want to create some full rendering tests to ensure the components integrate correctly. Enzyme supports [full rendering with `mount()`](https://airbnb.io/enzyme/docs/api/mount.html), and you can also use it for testing state changes and component lifecycle.
|
||||
|
||||
You can read the [Enzyme documentation](http://airbnb.io/enzyme/) for more testing techniques. Enzyme documentation uses Chai and Sinon for assertions but you don’t have to use them because Jest provides built-in `expect()` and `jest.fn()` for spies.
|
||||
You can read the [Enzyme documentation](https://airbnb.io/enzyme/) for more testing techniques. Enzyme documentation uses Chai and Sinon for assertions but you don’t have to use them because Jest provides built-in `expect()` and `jest.fn()` for spies.
|
||||
|
||||
Here is an example from Enzyme documentation that asserts specific output, rewritten to use Jest matchers:
|
||||
|
||||
@@ -1431,8 +1431,8 @@ it('renders welcome message', () => {
|
||||
});
|
||||
```
|
||||
|
||||
All Jest matchers are [extensively documented here](http://facebook.github.io/jest/docs/en/expect.html).<br>
|
||||
Nevertheless you can use a third-party assertion library like [Chai](http://chaijs.com/) if you want to, as described below.
|
||||
All Jest matchers are [extensively documented here](https://facebook.github.io/jest/docs/en/expect.html).<br>
|
||||
Nevertheless you can use a third-party assertion library like [Chai](https://chaijs.com/) if you want to, as described below.
|
||||
|
||||
Additionally, you might find [jest-enzyme](https://github.com/blainekasten/enzyme-matchers) helpful to simplify your tests with readable matchers. The above `contains` code can be written more simply with jest-enzyme.
|
||||
|
||||
@@ -1462,7 +1462,7 @@ import 'jest-enzyme';
|
||||
|
||||
We recommend that you use `expect()` for assertions and `jest.fn()` for spies. If you are having issues with them please [file those against Jest](https://github.com/facebook/jest/issues/new), and we’ll fix them. We intend to keep making them better for React, supporting, for example, [pretty-printing React elements as JSX](https://github.com/facebook/jest/pull/1566).
|
||||
|
||||
However, if you are used to other libraries, such as [Chai](http://chaijs.com/) and [Sinon](http://sinonjs.org/), or if you have existing code using them that you’d like to port over, you can import them normally like this:
|
||||
However, if you are used to other libraries, such as [Chai](https://chaijs.com/) and [Sinon](https://sinonjs.org/), or if you have existing code using them that you’d like to port over, you can import them normally like this:
|
||||
|
||||
```js
|
||||
import sinon from 'sinon';
|
||||
@@ -1509,7 +1509,7 @@ Similarly, `fit()` lets you focus on a specific test without running any other t
|
||||
Jest has an integrated coverage reporter that works well with ES6 and requires no configuration.<br>
|
||||
Run `npm test -- --coverage` (note extra `--` in the middle) to include a coverage report like this:
|
||||
|
||||

|
||||

|
||||
|
||||
Note that tests run much slower with coverage so it is recommended to run it separately from your normal workflow.
|
||||
|
||||
@@ -1640,18 +1640,18 @@ To help you make up your mind, here is a list of APIs that **need jsdom**:
|
||||
- Any browser globals like `window` and `document`
|
||||
- [`ReactDOM.render()`](https://facebook.github.io/react/docs/top-level-api.html#reactdom.render)
|
||||
- [`TestUtils.renderIntoDocument()`](https://facebook.github.io/react/docs/test-utils.html#renderintodocument) ([a shortcut](https://github.com/facebook/react/blob/34761cf9a252964abfaab6faf74d473ad95d1f21/src/test/ReactTestUtils.js#L83-L91) for the above)
|
||||
- [`mount()`](http://airbnb.io/enzyme/docs/api/mount.html) in [Enzyme](http://airbnb.io/enzyme/index.html)
|
||||
- [`mount()`](https://airbnb.io/enzyme/docs/api/mount.html) in [Enzyme](https://airbnb.io/enzyme/index.html)
|
||||
|
||||
In contrast, **jsdom is not needed** for the following APIs:
|
||||
|
||||
- [`TestUtils.createRenderer()`](https://facebook.github.io/react/docs/test-utils.html#shallow-rendering) (shallow rendering)
|
||||
- [`shallow()`](http://airbnb.io/enzyme/docs/api/shallow.html) in [Enzyme](http://airbnb.io/enzyme/index.html)
|
||||
- [`shallow()`](https://airbnb.io/enzyme/docs/api/shallow.html) in [Enzyme](https://airbnb.io/enzyme/index.html)
|
||||
|
||||
Finally, jsdom is also not needed for [snapshot testing](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html).
|
||||
Finally, jsdom is also not needed for [snapshot testing](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html).
|
||||
|
||||
### Snapshot Testing
|
||||
|
||||
Snapshot testing is a feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output. [Read more about snapshot testing.](http://facebook.github.io/jest/blog/2016/07/27/jest-14.html)
|
||||
Snapshot testing is a feature of Jest that automatically generates text snapshots of your components and saves them on the disk so if the UI output changes, you get notified without manually writing any assertions on the component output. [Read more about snapshot testing.](https://facebook.github.io/jest/blog/2016/07/27/jest-14.html)
|
||||
|
||||
### Editor Integration
|
||||
|
||||
@@ -1735,7 +1735,7 @@ Usually, it’s hard to see these states without running a sample app or some ex
|
||||
|
||||
Create React App doesn’t include any tools for this by default, but you can easily add [Storybook for React](https://storybook.js.org) ([source](https://github.com/storybooks/storybook)) or [React Styleguidist](https://react-styleguidist.js.org/) ([source](https://github.com/styleguidist/react-styleguidist)) to your project. **These are third-party tools that let you develop components and see all their states in isolation from your app**.
|
||||
|
||||

|
||||

|
||||
|
||||
You can also deploy your Storybook or style guide as a static app. This way, everyone in your team can view and review different states of UI components without starting a backend server or creating an account in your app.
|
||||
|
||||
@@ -1820,7 +1820,7 @@ following in their [`src/index.js`](src/index.js) file:
|
||||
```js
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
```
|
||||
|
||||
@@ -1854,7 +1854,7 @@ following into account:
|
||||
|
||||
1. Service workers [require HTTPS](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers#you_need_https),
|
||||
although to facilitate local testing, that policy
|
||||
[does not apply to `localhost`](http://stackoverflow.com/questions/34160509/options-for-testing-service-workers-via-http/34161385#34161385).
|
||||
[does not apply to `localhost`](https://stackoverflow.com/questions/34160509/options-for-testing-service-workers-via-http/34161385#34161385).
|
||||
If your production web server does not support HTTPS, then the service worker
|
||||
registration will fail, but the rest of your web app will remain functional.
|
||||
|
||||
@@ -1970,7 +1970,7 @@ serve -h
|
||||
|
||||
You don’t necessarily need a static server in order to run a Create React App project in production. It works just as fine integrated into an existing dynamic one.
|
||||
|
||||
Here’s a programmatic example using [Node](https://nodejs.org/) and [Express](http://expressjs.com/):
|
||||
Here’s a programmatic example using [Node](https://nodejs.org/) and [Express](https://expressjs.com/):
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
@@ -2018,7 +2018,7 @@ If you’re using [Apache HTTP Server](https://httpd.apache.org/), you need to c
|
||||
|
||||
It will get copied to the `build` folder when you run `npm run build`.
|
||||
|
||||
If you’re using [Apache Tomcat](http://tomcat.apache.org/), you need to follow [this Stack Overflow answer](https://stackoverflow.com/a/41249464/4878474).
|
||||
If you’re using [Apache Tomcat](https://tomcat.apache.org/), you need to follow [this Stack Overflow answer](https://stackoverflow.com/a/41249464/4878474).
|
||||
|
||||
Now requests to `/todos/42` will be handled correctly both in development and in production.
|
||||
|
||||
@@ -2029,7 +2029,7 @@ service worker navigation routing can be configured or disabled by
|
||||
[`eject`ing](#npm-run-eject) and then modifying the
|
||||
[`navigateFallback`](https://github.com/GoogleChrome/sw-precache#navigatefallback-string)
|
||||
and [`navigateFallbackWhitelist`](https://github.com/GoogleChrome/sw-precache#navigatefallbackwhitelist-arrayregexp)
|
||||
options of the `SWPreachePlugin` [configuration](../config/webpack.config.prod.js).
|
||||
options of the `SWPrecachePlugin` [configuration](../config/webpack.config.prod.js).
|
||||
|
||||
When users install your app to the homescreen of their device the default configuration will make a shortcut to `/index.html`. This may not work for client-side routers which expect the app to be served from `/`. Edit the web app manifest at [`public/manifest.json`](public/manifest.json) and change `start_url` to match the required URL scheme, for example:
|
||||
|
||||
@@ -2043,7 +2043,7 @@ By default, Create React App produces a build assuming your app is hosted at the
|
||||
To override this, specify the `homepage` in your `package.json`, for example:
|
||||
|
||||
```js
|
||||
"homepage": "http://mywebsite.com/relativepath",
|
||||
"homepage": "https://example.com/relativepath",
|
||||
```
|
||||
|
||||
This will let Create React App correctly infer the root path to use in the generated HTML file.
|
||||
@@ -2068,7 +2068,7 @@ If you are not using the HTML5 `pushState` history API or not using client-side
|
||||
"homepage": ".",
|
||||
```
|
||||
|
||||
This will make sure that all the asset paths are relative to `index.html`. You will then be able to move your app from `http://mywebsite.com` to `http://mywebsite.com/relativepath` or even `http://mywebsite.com/relative/path` without having to rebuild it.
|
||||
This will make sure that all the asset paths are relative to `index.html`. You will then be able to move your app from `https://example.com` to `https://example.com/relativepath` or even `https://example.com/relative/path` without having to rebuild it.
|
||||
|
||||
### Customizing Environment Variables for Arbitrary Build Environments
|
||||
|
||||
@@ -2077,7 +2077,7 @@ You can create an arbitrary build environment by creating a custom `.env` file a
|
||||
For example, to create a build environment for a staging environment:
|
||||
|
||||
1. Create a file called `.env.staging`
|
||||
1. Set environment variables as you would any other `.env` file (e.g. `REACT_APP_API_URL=http://api-staging.example.com`)
|
||||
1. Set environment variables as you would any other `.env` file (e.g. `REACT_APP_API_URL=https://api-staging.example.com`)
|
||||
1. Install [env-cmd](https://www.npmjs.com/package/env-cmd)
|
||||
```sh
|
||||
$ npm install env-cmd --save
|
||||
@@ -2201,7 +2201,7 @@ or for a GitHub user page:
|
||||
or for a custom domain page:
|
||||
|
||||
```json
|
||||
"homepage": "https://mywebsite.com",
|
||||
"homepage": "https://example.com",
|
||||
```
|
||||
|
||||
Create React App uses the `homepage` field to determine the root URL in the built HTML file.
|
||||
@@ -2259,7 +2259,7 @@ npm run deploy
|
||||
|
||||
Finally, make sure **GitHub Pages** option in your GitHub project settings is set to use the `gh-pages` branch:
|
||||
|
||||
<img src="http://i.imgur.com/HUjEr9l.png" width="500" alt="gh-pages branch setting">
|
||||
<img src="https://i.imgur.com/HUjEr9l.png" width="500" alt="gh-pages branch setting">
|
||||
|
||||
#### Step 5: Optionally, configure the domain
|
||||
|
||||
@@ -2268,14 +2268,14 @@ You can configure a custom domain with GitHub Pages by adding a `CNAME` file to
|
||||
Your CNAME file should look like this:
|
||||
|
||||
```
|
||||
mywebsite.com
|
||||
example.com
|
||||
```
|
||||
|
||||
#### Notes on client-side routing
|
||||
|
||||
GitHub Pages doesn’t support routers that use the HTML5 `pushState` history API under the hood (for example, React Router using `browserHistory`). This is because when there is a fresh page load for a url like `http://user.github.io/todomvc/todos/42`, where `/todos/42` is a frontend route, the GitHub Pages server returns 404 because it knows nothing of `/todos/42`. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions:
|
||||
GitHub Pages doesn’t support routers that use the HTML5 `pushState` history API under the hood (for example, React Router using `browserHistory`). This is because when there is a fresh page load for a url like `https://user.github.io/todomvc/todos/42`, where `/todos/42` is a frontend route, the GitHub Pages server returns 404 because it knows nothing of `/todos/42`. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions:
|
||||
|
||||
- You could switch from using HTML5 history API to routing with hashes. If you use React Router, you can switch to `hashHistory` for this effect, but the URL will be longer and more verbose (for example, `http://user.github.io/todomvc/#/todos/42?_k=yknaj`). [Read more](https://reacttraining.com/react-router/web/api/Router) about different history implementations in React Router.
|
||||
- You could switch from using HTML5 history API to routing with hashes. If you use React Router, you can switch to `hashHistory` for this effect, but the URL will be longer and more verbose (for example, `https://user.github.io/todomvc/#/todos/42?_k=yknaj`). [Read more](https://reacttraining.com/react-router/web/api/Router) about different history implementations in React Router.
|
||||
- Alternatively, you can use a trick to teach GitHub Pages to handle 404 by redirecting to your `index.html` page with a special redirect parameter. You would need to add a `404.html` file with the redirection code to the `build` folder before deploying your project, and you’ll need to add code handling the redirect parameter to `index.html`. You can find a detailed explanation of this technique [in this guide](https://github.com/rafrex/spa-github-pages).
|
||||
|
||||
#### Troubleshooting
|
||||
@@ -2317,7 +2317,7 @@ MyDirectory in /tmp/build_1234/src
|
||||
|
||||
It means you need to ensure that the lettercase of the file or directory you `import` matches the one you see on your filesystem or on GitHub.
|
||||
|
||||
This is important because Linux (the operating system used by Heroku) is case sensitive. So `MyDirectory` and `mydirectory` are two distinct directories and thus, even though the project builds locally, the difference in case breaks the `import` statements on Heroku remotes.
|
||||
This is important because Linux (the operating system used by Heroku) is case-sensitive. So `MyDirectory` and `mydirectory` are two distinct directories and thus, even though the project builds locally, the difference in case breaks the `import` statements on Heroku remotes.
|
||||
|
||||
##### "Could not find a required file."
|
||||
|
||||
@@ -2442,7 +2442,7 @@ We recommend deleting `node_modules` in your project and running `npm install` (
|
||||
- [facebook/watchman#358](https://github.com/facebook/watchman/issues/358)
|
||||
- [ember-cli/ember-cli#6259](https://github.com/ember-cli/ember-cli/issues/6259)
|
||||
|
||||
It is reported that installing Watchman 4.7.0 or newer fixes the issue. If you use [Homebrew](http://brew.sh/), you can run these commands to update it:
|
||||
It is reported that installing Watchman 4.7.0 or newer fixes the issue. If you use [Homebrew](https://brew.sh/), you can run these commands to update it:
|
||||
|
||||
```
|
||||
watchman shutdown-server
|
||||
@@ -2466,7 +2466,7 @@ If you are completely sure that you didn't terminate the process, consider [addi
|
||||
|
||||
### `npm run build` fails on Heroku
|
||||
|
||||
This may be a problem with case sensitive filenames.
|
||||
This may be a problem with case-sensitive filenames.
|
||||
Please refer to [this section](#resolving-heroku-deployment-errors).
|
||||
|
||||
### Moment.js locales are missing
|
||||
|
||||
Generated
+16737
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"html-react-parser": "^0.4.7",
|
||||
"liquidjs": "^9.1.0",
|
||||
"liquidjs": "^10.8.3",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-promise": "^2.0.3",
|
||||
|
||||
@@ -9,5 +9,5 @@ ReactDOM.render(<App />, document.getElementById('root'));
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
|
||||
Generated
+82
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "liquidjs-demo-typescript",
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "14.18.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.34.tgz",
|
||||
"integrity": "sha512-hcU9AIQVHmPnmjRK+XUUYlILlr9pQrsqSrwov/JK1pnf3GTQowVBhx54FbvM0AU/VXGH4i3+vgXS5EguR7fysA==",
|
||||
"dev": true
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
|
||||
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
|
||||
},
|
||||
"liquidjs": {
|
||||
"version": "10.8.3",
|
||||
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.8.3.tgz",
|
||||
"integrity": "sha512-LqHLYtH3vrkT3LyfOhPU0FJX5KPO4aB6SzGa4HRI29yz8pS0ZxqIe/fWtic8qiust1+qrHI92J67tdt92V4WOA==",
|
||||
"requires": {
|
||||
"commander": "^10.0.0"
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "8.10.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
|
||||
"integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.17",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
|
||||
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg=="
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
"start": "ts-node index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"liquidjs": "*",
|
||||
"liquidjs": "^10.8.3",
|
||||
"ts-node": "^8.10.2",
|
||||
"typescript": "^4.2.4"
|
||||
},
|
||||
|
||||
Generated
+979
@@ -0,0 +1,979 @@
|
||||
{
|
||||
"name": "liquidjs-demo-nodejs",
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@discoveryjs/json-ext": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
|
||||
"integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
|
||||
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"@jridgewell/resolve-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/source-map": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
|
||||
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.17",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
|
||||
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "1.4.14"
|
||||
}
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "8.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.7.tgz",
|
||||
"integrity": "sha512-ehM7cCt2RSFs42mb+lcmhFT9ouIlV92PuaeRGn8N8c98oMjG4Z5pJHA9b1QiCcuqnbPSHcyfiD3mlhqMaHsQIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "*",
|
||||
"@types/json-schema": "*"
|
||||
}
|
||||
},
|
||||
"@types/eslint-scope": {
|
||||
"version": "3.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
|
||||
"integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint": "*",
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "0.0.51",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
|
||||
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz",
|
||||
"integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
|
||||
"integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/helper-numbers": "1.11.1",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.1"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/floating-point-hex-parser": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
|
||||
"integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-api-error": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
|
||||
"integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-buffer": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
|
||||
"integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-numbers": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
|
||||
"integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.11.1",
|
||||
"@webassemblyjs/helper-api-error": "1.11.1",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-bytecode": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
|
||||
"integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
|
||||
"integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@webassemblyjs/helper-buffer": "1.11.1",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
|
||||
"@webassemblyjs/wasm-gen": "1.11.1"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ieee754": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
|
||||
"integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xtuc/ieee754": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/leb128": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
|
||||
"integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/utf8": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
|
||||
"integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/wasm-edit": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
|
||||
"integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@webassemblyjs/helper-buffer": "1.11.1",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
|
||||
"@webassemblyjs/helper-wasm-section": "1.11.1",
|
||||
"@webassemblyjs/wasm-gen": "1.11.1",
|
||||
"@webassemblyjs/wasm-opt": "1.11.1",
|
||||
"@webassemblyjs/wasm-parser": "1.11.1",
|
||||
"@webassemblyjs/wast-printer": "1.11.1"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-gen": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
|
||||
"integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
|
||||
"@webassemblyjs/ieee754": "1.11.1",
|
||||
"@webassemblyjs/leb128": "1.11.1",
|
||||
"@webassemblyjs/utf8": "1.11.1"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-opt": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
|
||||
"integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@webassemblyjs/helper-buffer": "1.11.1",
|
||||
"@webassemblyjs/wasm-gen": "1.11.1",
|
||||
"@webassemblyjs/wasm-parser": "1.11.1"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-parser": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
|
||||
"integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@webassemblyjs/helper-api-error": "1.11.1",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.1",
|
||||
"@webassemblyjs/ieee754": "1.11.1",
|
||||
"@webassemblyjs/leb128": "1.11.1",
|
||||
"@webassemblyjs/utf8": "1.11.1"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-printer": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
|
||||
"integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webpack-cli/configtest": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
|
||||
"integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
|
||||
"dev": true
|
||||
},
|
||||
"@webpack-cli/info": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
|
||||
"integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"envinfo": "^7.7.3"
|
||||
}
|
||||
},
|
||||
"@webpack-cli/serve": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
|
||||
"integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
|
||||
"dev": true
|
||||
},
|
||||
"@xtuc/long": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.8.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
|
||||
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-import-assertions": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
|
||||
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.21.4",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
|
||||
"integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001400",
|
||||
"electron-to-chromium": "^1.4.251",
|
||||
"node-releases": "^2.0.6",
|
||||
"update-browserslist-db": "^1.0.9"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001423",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001423.tgz",
|
||||
"integrity": "sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ==",
|
||||
"dev": true
|
||||
},
|
||||
"chrome-trace-event": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
|
||||
"integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
|
||||
"dev": true
|
||||
},
|
||||
"clone-deep": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
||||
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4",
|
||||
"kind-of": "^6.0.2",
|
||||
"shallow-clone": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"colorette": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
|
||||
"integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.4.284",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
|
||||
"integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
|
||||
"dev": true
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
|
||||
"integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"envinfo": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
||||
"integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
|
||||
"dev": true
|
||||
},
|
||||
"es-module-lexer": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
|
||||
"integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
|
||||
"dev": true
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
|
||||
"dev": true
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"esrecurse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estraverse": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"estraverse": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true
|
||||
},
|
||||
"events": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||
"dev": true
|
||||
},
|
||||
"fastest-levenshtein": {
|
||||
"version": "1.0.16",
|
||||
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
|
||||
"integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
|
||||
"dev": true
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"glob-to-regexp": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
|
||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
|
||||
"dev": true
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.10",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
|
||||
"dev": true
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"hello-liquid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hello-liquid/-/hello-liquid-1.0.0.tgz",
|
||||
"integrity": "sha512-WNmZp5s647BN2WHPq4FHVH85CcqNVet5DXIVw1UtVMaV+MJHFA+ylge0hqHSw0iOI/Ojrx8KEKZurYZix5PekQ=="
|
||||
},
|
||||
"import-local": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
|
||||
"integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pkg-dir": "^4.2.0",
|
||||
"resolve-cwd": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"interpret": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
|
||||
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
|
||||
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||
"integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
|
||||
"dev": true
|
||||
},
|
||||
"jest-worker": {
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
|
||||
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"merge-stream": "^2.0.0",
|
||||
"supports-color": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"liquidjs": {
|
||||
"version": "9.42.0",
|
||||
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.42.0.tgz",
|
||||
"integrity": "sha512-krvhwGFrMCMGhybGkxJIvlWVVnoCSpYCn7NhEN43+uvlg2vOkYWpq8be+L3NMlOfwe4ZrKQ7hCh1EmS4yhLKow=="
|
||||
},
|
||||
"loader-runner": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
|
||||
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
|
||||
"dev": true
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
},
|
||||
"neo-async": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
|
||||
"integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true
|
||||
},
|
||||
"path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pkg-dir": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"find-up": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"rechoir": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
|
||||
"integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"resolve": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-core-module": "^2.9.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"resolve-cwd": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
|
||||
"integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"resolve-from": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
|
||||
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
|
||||
"dev": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
|
||||
"integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
|
||||
"integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"shallow-clone": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
|
||||
"integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.2"
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true
|
||||
},
|
||||
"tapable": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"terser": {
|
||||
"version": "5.15.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
|
||||
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/source-map": "^0.3.2",
|
||||
"acorn": "^8.5.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
}
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "5.3.6",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
|
||||
"integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/trace-mapping": "^0.3.14",
|
||||
"jest-worker": "^27.4.5",
|
||||
"schema-utils": "^3.1.1",
|
||||
"serialize-javascript": "^6.0.0",
|
||||
"terser": "^5.14.1"
|
||||
}
|
||||
},
|
||||
"update-browserslist-db": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
|
||||
"integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escalade": "^3.1.1",
|
||||
"picocolors": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"graceful-fs": "^4.1.2"
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "5.74.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
|
||||
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^0.0.51",
|
||||
"@webassemblyjs/ast": "1.11.1",
|
||||
"@webassemblyjs/wasm-edit": "1.11.1",
|
||||
"@webassemblyjs/wasm-parser": "1.11.1",
|
||||
"acorn": "^8.7.1",
|
||||
"acorn-import-assertions": "^1.7.6",
|
||||
"browserslist": "^4.14.5",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^5.10.0",
|
||||
"es-module-lexer": "^0.9.0",
|
||||
"eslint-scope": "5.1.1",
|
||||
"events": "^3.2.0",
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"json-parse-even-better-errors": "^2.3.1",
|
||||
"loader-runner": "^4.2.0",
|
||||
"mime-types": "^2.1.27",
|
||||
"neo-async": "^2.6.2",
|
||||
"schema-utils": "^3.1.0",
|
||||
"tapable": "^2.1.1",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"watchpack": "^2.4.0",
|
||||
"webpack-sources": "^3.2.3"
|
||||
}
|
||||
},
|
||||
"webpack-cli": {
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
|
||||
"integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@discoveryjs/json-ext": "^0.5.0",
|
||||
"@webpack-cli/configtest": "^1.2.0",
|
||||
"@webpack-cli/info": "^1.5.0",
|
||||
"@webpack-cli/serve": "^1.7.0",
|
||||
"colorette": "^2.0.14",
|
||||
"commander": "^7.0.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"fastest-levenshtein": "^1.0.12",
|
||||
"import-local": "^3.0.2",
|
||||
"interpret": "^2.2.0",
|
||||
"rechoir": "^0.7.0",
|
||||
"webpack-merge": "^5.7.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"webpack-merge": {
|
||||
"version": "5.8.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
|
||||
"integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone-deep": "^4.0.1",
|
||||
"wildcard": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"wildcard": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
|
||||
"integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
title: LiquidJS
|
||||
subtitle: "A simple, expressive and safe template engine."
|
||||
description: "LiquidJS is a simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript."
|
||||
description: "LiquidJS is a simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript."
|
||||
author: Harttle
|
||||
language:
|
||||
- en
|
||||
@@ -19,14 +19,15 @@ pretty_urls:
|
||||
trailing_html: false
|
||||
|
||||
theme: navy
|
||||
skip_render: "api/**/*"
|
||||
highlight:
|
||||
enable: false
|
||||
skip_render: "api/**"
|
||||
ignore: "api/**"
|
||||
include: "api/**"
|
||||
syntax_highlighter: prismjs
|
||||
prismjs:
|
||||
enable: true
|
||||
preprocess: true
|
||||
line_number: true
|
||||
tab_replace: ''
|
||||
line_threshold: 0
|
||||
tab_replace: ""
|
||||
|
||||
algolia:
|
||||
applicationID: 0X19J927JZ
|
||||
@@ -34,5 +35,4 @@ algolia:
|
||||
indexName: liquidjs
|
||||
twitter: harttleharttle
|
||||
github: harttle/liquidjs
|
||||
patreon: harttle
|
||||
oc: liquidjs
|
||||
|
||||
Generated
+535
-1741
File diff suppressed because it is too large
Load Diff
+3
-4
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"hexo": {
|
||||
"version": "5.4.0"
|
||||
"version": "7.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "hexo generate",
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"cheerio": "^0.22.0",
|
||||
"hexo": "^5.4.0",
|
||||
"hexo": "^7.3.0",
|
||||
"hexo-algolia": "^1.3.1",
|
||||
"hexo-clean-css": "^1.0.0",
|
||||
"hexo-filter-nofollow": "^2.0.2",
|
||||
@@ -28,11 +28,10 @@
|
||||
"hexo-uglify": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"all-contributors-cli": "^6.8.1",
|
||||
"eslint": "^6.0.1",
|
||||
"eslint-config-hexo": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ const { readFileSync } = require('fs')
|
||||
const cheerio = require('cheerio')
|
||||
const fullUrlFor = hexo.extend.helper.get('full_url_for').bind(hexo)
|
||||
|
||||
const localizedPath = ['tutorials', 'filters', 'tags', 'playground', 'api']
|
||||
const localizedPath = ['tutorials', 'filters', 'tags', 'playground']
|
||||
|
||||
hexo.extend.helper.register('page_nav', function () {
|
||||
const type = this.page.canonical_path.split('/')[0]
|
||||
|
||||
@@ -8,15 +8,18 @@ tutorials:
|
||||
express: use-in-expressjs.html
|
||||
advanced:
|
||||
caching: caching.html
|
||||
registeration: register-filters-tags.html
|
||||
escaping: escaping.html
|
||||
registration: register-filters-tags.html
|
||||
access_scope_in_filters: access-scope-in-filters.html
|
||||
parse_parameters: parse-parameters.html
|
||||
render_tag_content: render-tag-content.html
|
||||
drops: drops.html
|
||||
sync_and_async: sync-and-async.html
|
||||
whitespace: whitespace-control.html
|
||||
plugins: plugins.html
|
||||
operators: operators.html
|
||||
truth: truthy-and-falsy.html
|
||||
dos: dos.html
|
||||
miscellaneous:
|
||||
migration9: migrate-to-9.html
|
||||
changelog: changelog.html
|
||||
@@ -27,29 +30,45 @@ filters:
|
||||
overview: overview.html
|
||||
abs: abs.html
|
||||
append: append.html
|
||||
array_to_sentence_string: array_to_sentence_string.html
|
||||
at_least: at_least.html
|
||||
at_most: at_most.html
|
||||
capitalize: capitalize.html
|
||||
ceil: ceil.html
|
||||
cgi_escape: cgi_escape.html
|
||||
compact: compact.html
|
||||
concat: concat.html
|
||||
date: date.html
|
||||
date_to_long_string: date_to_long_string.html
|
||||
date_to_rfc822: date_to_rfc822.html
|
||||
date_to_string: date_to_string.html
|
||||
date_to_xmlschema: date_to_xmlschema.html
|
||||
default: default.html
|
||||
divided_by: divided_by.html
|
||||
downcase: downcase.html
|
||||
escape: escape.html
|
||||
escape_once: escape_once.html
|
||||
find: find.html
|
||||
find_exp: find_exp.html
|
||||
first: first.html
|
||||
floor: floor.html
|
||||
group_by: group_by.html
|
||||
group_by_exp: group_by_exp.html
|
||||
inspect: inspect.html
|
||||
join: join.html
|
||||
json: json.html
|
||||
jsonify: jsonify.html
|
||||
last: last.html
|
||||
lstrip: lstrip.html
|
||||
map: map.html
|
||||
minus: minus.html
|
||||
modulo: modulo.html
|
||||
newline_to_br: newline_to_br.html
|
||||
normalize_whitespace: normalize_whitespace.html
|
||||
number_of_words: number_of_words.html
|
||||
plus: plus.html
|
||||
pop: pop.html
|
||||
push: push.html
|
||||
prepend: prepend.html
|
||||
raw: raw.html
|
||||
remove: remove.html
|
||||
@@ -61,22 +80,30 @@ filters:
|
||||
reverse: reverse.html
|
||||
round: round.html
|
||||
rstrip: rstrip.html
|
||||
shift: shift.html
|
||||
size: size.html
|
||||
slice: slice.html
|
||||
slugify: slugify.html
|
||||
sort: sort.html
|
||||
sort_natural: sort_natural.html
|
||||
split: split.html
|
||||
strip: strip.html
|
||||
strip_html: strip_html.html
|
||||
strip_newlines: strip_newlines.html
|
||||
sum: sum.html
|
||||
times: times.html
|
||||
to_integer: to_integer.html
|
||||
truncate: truncate.html
|
||||
truncatewords: truncatewords.html
|
||||
uniq: uniq.html
|
||||
unshift: unshift.html
|
||||
upcase: upcase.html
|
||||
uri_escape: uri_escape.html
|
||||
url_decode: url_decode.html
|
||||
url_encode: url_encode.html
|
||||
where: where.html
|
||||
where_exp: where_exp.html
|
||||
xml_escape: xml_escape.html
|
||||
|
||||
tags:
|
||||
overview: overview.html
|
||||
@@ -101,53 +128,3 @@ tags:
|
||||
tablerow: tablerow.html
|
||||
unless: unless.html
|
||||
when: case.html
|
||||
|
||||
api:
|
||||
quick_entry:
|
||||
Liquid: "../classes/liquid_.liquid.html"
|
||||
LiquidOptions: "../interfaces/liquid_options_.liquidoptions.html"
|
||||
FS: "../interfaces/fs_fs_.fs.html"
|
||||
Cache: "../interfaces/cache_cache_.cache.html"
|
||||
classes:
|
||||
BlankDrop: "../classes/drop_blank_drop_.blankdrop.html"
|
||||
Context: "../classes/context_context_.context.html"
|
||||
DelimitedToken: "../classes/tokens_delimited_token_.delimitedtoken.html"
|
||||
Drop: "../classes/drop_drop_.drop.html"
|
||||
EmptyDrop: "../classes/drop_empty_drop_.emptydrop.html"
|
||||
Expression: "../classes/render_expression_.expression.html"
|
||||
FilterToken: "../classes/tokens_filter_token_.filtertoken.html"
|
||||
ForloopDrop: "../classes/drop_forloop_drop_.forloopdrop.html"
|
||||
HTMLToken: "../classes/tokens_html_token_.htmltoken.html"
|
||||
HashToken: "../classes/tokens_hash_token_.hashtoken.html"
|
||||
LRU: "../classes/cache_lru_.lru.html"
|
||||
Liquid: "../classes/liquid_.liquid.html"
|
||||
LiteralToken: "../classes/tokens_literal_token_.literaltoken.html"
|
||||
NullDrop: "../classes/drop_null_drop_.nulldrop.html"
|
||||
NumberToken: "../classes/tokens_number_token_.numbertoken.html"
|
||||
OperatorToken: "../classes/tokens_operator_token_.operatortoken.html"
|
||||
OutputToken: "../classes/tokens_output_token_.outputtoken.html"
|
||||
ParseError: "../classes/util_error_.parseerror.html"
|
||||
ParseStream: "../classes/parser_parse_stream_.parsestream.html"
|
||||
Parser: "../classes/parser_parser_.parser.html"
|
||||
PropertyaccessToken: "../classes/tokens_property_access_token_.propertyaccesstoken.html"
|
||||
QuotedToken: "../classes/tokens_quoted_token_.quotedtoken.html"
|
||||
RangeToken: "../classes/tokens_range_token_.rangetoken.html"
|
||||
Render: "../classes/render_render_.render.html"
|
||||
RenderError: "../classes/util_error_.rendererror.html"
|
||||
TablerowloopDrop: "../classes/drop_tablerowloop_drop_.tablerowloopdrop.html"
|
||||
TagToken: "../classes/tokens_tag_token_.tagtoken.html"
|
||||
Token: "../classes/tokens_token_.token.html"
|
||||
TokenizationError: "../classes/util_error_.tokenizationerror.html"
|
||||
Tokenizer: "../classes/parser_tokenizer_.tokenizer.html"
|
||||
WordToken: "../classes/tokens_word_token_.wordtoken.html"
|
||||
enums:
|
||||
BlockMode: "../enums/context_block_mode_.blockmode.html"
|
||||
TokenKind: "../enums/parser_token_kind_.tokenkind.html"
|
||||
interfaces:
|
||||
Cache: "../interfaces/cache_cache_.cache.html"
|
||||
FilterImplOptions: "../interfaces/template_filter_filter_impl_options_.filterimploptions.html"
|
||||
FS: "../interfaces/fs_fs_.fs.html"
|
||||
LiquidOptions: "../interfaces/liquid_options_.liquidoptions.html"
|
||||
NormalizedFullOptions: "../interfaces/liquid_options_.normalizedfulloptions.html"
|
||||
PlainObject: "../interfaces/context_scope_.plainobject.html"
|
||||
TagImplOptions: "../interfaces/template_tag_tag_impl_options_.tagimploptions.html"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: array_to_sentence_string
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert an array into a sentence. Useful for listing tags. Optional argument for connector.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "foo,bar,baz" | split: "," | array_to_sentence_string }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
foo, bar, and baz
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "foo,bar,baz" | split: "," | array_to_sentence_string: "or" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
foo, bar, or baz
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: cgi_escape
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
CGI escape a string for use in a URL. Replaces any special characters with appropriate `%XX` replacements. CGI escape normally replaces a space with a plus `+` sign.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "foo, bar; baz?" | cgi_escape }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
foo%2C+bar%3B+baz%3F
|
||||
```
|
||||
+17
-17
@@ -3,15 +3,18 @@ title: date
|
||||
---
|
||||
{% since %}v1.9.1{% endsince %}
|
||||
|
||||
# Format
|
||||
* Converts a timestamp into another date format
|
||||
* LiquidJS tries to be conformant with Shopify/Liquid which is using Ruby's core [Time#strftime(string)](http://www.ruby-doc.org/core/Time.html#method-i-strftime)
|
||||
* Refer [format flags](https://ruby-doc.org/core/strftime_formatting_rdoc.html)
|
||||
* Not all options are supported though - refer [differences here](/tutorials/differences.html#Differences)
|
||||
* The input is firstly converted to `Date` object via [new Date()][jsDate]
|
||||
* Date format can be provided individually as a filter option
|
||||
* If not provided, then `%A, %B %-e, %Y at %-l:%M %P %z` format will be used as default format
|
||||
* Override this using [`dateFormat`](/api/interfaces/LiquidOptions.html#dateFormat) LiquidJS option, to set your preferred default format for all date filters
|
||||
Date filter is used to convert a timestamp into the specified format.
|
||||
|
||||
* LiquidJS tries to conform to Shopify/Liquid, which uses Ruby's core [Time#strftime(string)](https://www.ruby-doc.org/core/Time.html#method-i-strftime). There're differences with [Ruby's format flags](https://ruby-doc.org/core/strftime_formatting_rdoc.html):
|
||||
* `%Z` (since v10.11.1) is replaced by the passed-in timezone name from `LiquidOption` or in-place value (see TimeZone below). If passed-in timezone is an offset number instead of string, it'll behave like `%z`. If there's none passed-in timezone, it returns [the runtime's default time zone](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/resolvedOptions#timezone).
|
||||
* LiquidJS provides an additional `%q` flag for date ordinals. e.g. `{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb`
|
||||
* Date literals are firstly converted to `Date` object via [new Date()][jsDate], that means literal values are considered in runtime's time zone by default.
|
||||
* The format filter argument is optional:
|
||||
* If not provided, it defaults to `%A, %B %-e, %Y at %-l:%M %P %z`.
|
||||
* The above default can be overridden by [`dateFormat`](/api/interfaces/LiquidOptions.html#dateFormat) LiquidJS option.
|
||||
* LiquidJS `date` supports locale specific weekdays and month names, which will fallback to English where `Intl` is not supported.
|
||||
* Ordinals (`%q`) and Jekyll specific date filters are English-only.
|
||||
* [`locale`](/api/interfaces/LiquidOptions.html#locale) can be set when creating Liquid instance. Defaults to `Intl.DateTimeFormat().resolvedOptions.locale`).
|
||||
|
||||
### Examples
|
||||
```liquid
|
||||
@@ -23,16 +26,14 @@ title: date
|
||||
```
|
||||
|
||||
# TimeZone
|
||||
* By default, dates will be converted to local timezone before output
|
||||
* You can override that by,
|
||||
* setting a timezone for each individual `date` filter via the second parameter
|
||||
* using the [`timezoneOffset`](/api/interfaces/LiquidOptions.html#timezoneOffset) LiquidJS option
|
||||
* Its default value is your local timezone offset which can be obtained by `new Date().getTimezoneOffset()`
|
||||
* During output, LiquidJS uses local timezone which can override by:
|
||||
* setting a timezone in-place when calling `date` filter, or
|
||||
* setting the [`timezoneOffset`](/api/interfaces/LiquidOptions.html#timezoneOffset) LiquidJS option
|
||||
* It defaults to runtime's time one.
|
||||
* Offset can be set as,
|
||||
* minutes: `-360` means `'+06:00'` and `360` means `'-06:00'`
|
||||
* timeZone ID: `Asia/Colombo` or `America/New_York`
|
||||
* Use minutes for better performance with repeated processing of templates with many dates like, converting template for each email recipient
|
||||
* Refer [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for TZ database values
|
||||
* See [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for TZ database values
|
||||
|
||||
### Examples
|
||||
```liquid
|
||||
@@ -41,7 +42,6 @@ title: date
|
||||
{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }} => 1991-01-01T04:30:00
|
||||
```
|
||||
|
||||
|
||||
# Input
|
||||
* `date` works on strings if they contain well-formatted dates
|
||||
* Note that LiquidJS is using [JavaScript Date][jsDate] to parse the input string, that means [IETF-compliant RFC 2822 timestamps](https://datatracker.ietf.org/doc/html/rfc2822#page-14) and strings in [a version of ISO8601](https://www.ecma-international.org/ecma-262/11.0/#sec-date.parse) are supported.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: date_to_long_string
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert a date to long format. Same with Jekyll `date_to_long_string` filter.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ site.time | date_to_long_string }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
07 November 2008
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ site.time | date_to_long_string: "ordinal" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
7th November 2008
|
||||
```
|
||||
|
||||
Note that JavaScript `Date` has not timezone information, see [date][date] filter for details.
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: date_to_rfc822
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert a Date into the RFC-822 format used for RSS feeds, same as Jekyll filter `date_to_rfc822`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ site.time | date_to_rfc822 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Mon, 07 Nov 2008 13:07:54 -0800
|
||||
```
|
||||
|
||||
Note that JavaScript `Date` has not timezone information, see [date][date] filter for details.
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: date_to_string
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert a date to short format. Same with Jekyll `date_to_string` filter.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ site.time | date_to_string }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
07 Nov 2008
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ site.time | date_to_string: "ordinal", "US" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Nov 7th, 2008
|
||||
```
|
||||
|
||||
Note that JavaScript `Date` has not timezone information, see [date][date] filter for details.
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: date_to_xmlschema
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert a Date into XML Schema (ISO 8601) format, same as Jekyll filter `date_to_xmlschema`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ site.time | date_to_xmlschema }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2008-11-07T13:07:54-08:00
|
||||
```
|
||||
|
||||
Note that JavaScript `Date` has not timezone information, see [date][date] filter for details.
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: find
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Return the first object in an array for which the queried attribute has the given value or return `nil` if no item in the array satisfies the given criteria. For the following `members` array:
|
||||
|
||||
```javascript
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack' }
|
||||
]
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ members | find: "graduation_year", 2014 | json }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
{"graduation_year":2014,"name":"John"}
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: find_exp
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Return the first object in an array for which the given expression evaluates to true or return `nil` if no item in the array satisfies the evaluated expression.
|
||||
|
||||
```javascript
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack' }
|
||||
]
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ members | find_exp: "item", "item.graduation_year == 2014" | json }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
{"graduation_year":2014,"name":"John"}
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: group_by
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Group an array's items by a given property. For `members` array:
|
||||
|
||||
```javascript
|
||||
const members = [
|
||||
{ graduation_year: 2003, name: 'Jay' },
|
||||
{ graduation_year: 2003, name: 'John' },
|
||||
{ graduation_year: 2004, name: 'Jack' }
|
||||
]
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ members | group_by: "graduation_year" | json: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
[
|
||||
{
|
||||
"name": 2003,
|
||||
"items": [
|
||||
{
|
||||
"graduation_year": 2003,
|
||||
"name": "Jay"
|
||||
},
|
||||
{
|
||||
"graduation_year": 2003,
|
||||
"name": "John"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": 2004,
|
||||
"items": [
|
||||
{
|
||||
"graduation_year": 2004,
|
||||
"name": "Jack"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: group_by_exp
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Group an array's items using a Liquid expression. For `members` array below:
|
||||
|
||||
```javascript
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2009, name: 'Jack' }
|
||||
]
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ members | group_by_exp: "item", "item.graduation_year | truncate: 3, ''" | json: 2 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
[
|
||||
{
|
||||
"name": "201",
|
||||
"items": [
|
||||
{
|
||||
"graduation_year": 2013,
|
||||
"name": "Jay"
|
||||
},
|
||||
{
|
||||
"graduation_year": 2014,
|
||||
"name": "John"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "200",
|
||||
"items": [
|
||||
{
|
||||
"graduation_year": 2009,
|
||||
"name": "Jack"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: inspect
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Similar with `json`, but `inspect` allows cyclic structure. For the scope below:
|
||||
|
||||
```
|
||||
const foo = {
|
||||
bar: 'BAR'
|
||||
}
|
||||
foo.foo = foo
|
||||
const scope = { foo }
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% foo | inspect %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
{"bar":"BAR","foo":"[Circular]"}
|
||||
```
|
||||
|
||||
## Formatting
|
||||
|
||||
An additional `space` argument can be specified for the indent width.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ foo | inspect: 4 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
{
|
||||
"bar": "BAR",
|
||||
"foo": "[Circular]"
|
||||
}
|
||||
```
|
||||
@@ -16,3 +16,24 @@ Output
|
||||
```text
|
||||
["foo","bar","coo"]
|
||||
```
|
||||
|
||||
## Space
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
An additional `space` parameter can be specified to format the JSON.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign arr = "foo bar coo" | split: " " %}
|
||||
{{ arr | json: 4 }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
[
|
||||
"foo",
|
||||
"bar",
|
||||
"coo"
|
||||
]
|
||||
```
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: jsonify
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
See [json][json].
|
||||
|
||||
[json]: /filters/json.html
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: normalize_whitespace
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Replace any occurrence of whitespace with a single space.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "a \n b" | normalize_whitespace }}
|
||||
```
|
||||
|
||||
Output
|
||||
```html
|
||||
a b
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: number_of_words
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Count the number of words in some text. This filter takes an optional argument to control the handling of Chinese-Japanese-Korean (CJK) characters in the input string:
|
||||
- Passing `'cjk'` as the argument will count every CJK character detected as one word irrespective of being separated by whitespace.
|
||||
- Passing `'auto'` (auto-detect) works similar to `'cjk'` but is more performant if the filter is used on a variable string that may or may not contain CJK chars.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Hello world!" | number_of_words }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "你好hello世界world" | number_of_words }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "你好hello世界world" | number_of_words: "cjk" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
6
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "你好hello世界world" | number_of_words: "auto" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
6
|
||||
```
|
||||
@@ -3,17 +3,17 @@ title: Filters
|
||||
description: Description and demo for each Liquid filter
|
||||
---
|
||||
|
||||
LiquidJS implements business-logic independent filters that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demoes for all the filters implemented by LiquidJS.
|
||||
LiquidJS implements business-logic independent filters that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demos for all the filters implemented by LiquidJS.
|
||||
|
||||
There's 40+ filters supported by LiquidJS. These filters can be categorized into these groups:
|
||||
|
||||
Categories | Filters
|
||||
--- | ---
|
||||
Math | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most
|
||||
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last,remove, remove_first, remove_last, truncate, truncatewords
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br
|
||||
Array | slice, map, sort, sort_natural, uniq, where, first, last, join, reverse, concat, compact, size
|
||||
Date | date
|
||||
Misc | default, json, raw
|
||||
String | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last,remove, remove_first, remove_last, truncate, truncatewords, normalize_whitespace, number_of_words, array_to_sentence_string
|
||||
HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br, xml_escape, cgi_escape, uri_escape, slugify
|
||||
Array | slice, map, sort, sort_natural, uniq, where, where_exp, group_by, group_by_exp, find, find_exp, first, last, join, reverse, concat, compact, size, push, pop, shift, unshift
|
||||
Date | date, date_to_xmlschema, date_to_rfc822, date_to_string, date_to_long_string
|
||||
Misc | default, json, jsonify, inspect, raw, to_integer
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: pop
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Pop an element from the array. It's NON-DESTRUCTIVE, i.e. it does not mutate the array, but rather make a copy and mutate that.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign fruits = "apples, oranges, peaches" | split: ", " %}
|
||||
|
||||
{% assign everything = fruits | pop %}
|
||||
|
||||
{% for item in everything %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- apples
|
||||
- oranges
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: push
|
||||
---
|
||||
|
||||
{% since %}v10.8.0{% endsince %}
|
||||
|
||||
Push an element into array. It's NON-DESTRUCTIVE, i.e. it does not mutate the array, but rather make a copy and mutate that.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign fruits = "apples, oranges" | split: ", " %}
|
||||
|
||||
{% assign everything = fruits | push: "peaches" %}
|
||||
|
||||
{% for item in everything %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- apples
|
||||
- oranges
|
||||
- peaches
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: shift
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Shift an element from the array. It's NON-DESTRUCTIVE, i.e. it does not mutate the array, but rather make a copy and mutate that.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign fruits = "apples, oranges, peaches" | split: ", " %}
|
||||
|
||||
{% assign everything = fruits | shift %}
|
||||
|
||||
{% for item in everything %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- oranges
|
||||
- peaches
|
||||
```
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
title: slugify
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert a string into a lowercase URL "slug". The slugify filter accepts 2 options:
|
||||
|
||||
1. `mode: string`. The default is `"default"`. They are as follows (with what they filter):
|
||||
- `"none"`: no characters
|
||||
- `"raw"`: spaces
|
||||
- `"default"`: spaces and non-alphanumeric characters
|
||||
- `"pretty"`: spaces and non-alphanumeric characters except for `._~!$&'()+,;=@`
|
||||
- `"ascii"`: spaces, non-alphanumeric, and non-ASCII characters
|
||||
- `"latin"`: like default, except Latin characters are first transliterated (e.g. àèïòü to aeiou).
|
||||
2. `case: boolean`. The default is `false`. The original case of slug will be retained if set to `true`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The _config.yml file" | slugify }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-config-yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The _config.yml file" | slugify: "pretty" }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-_config.yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The _cönfig.yml file" | slugify: "ascii" }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-c-nfig-yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The cönfig.yml file" | slugify: "latin" }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
the-config-yml-file
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "The cönfig.yml file" | slugify: "latin", true }}
|
||||
```
|
||||
Output
|
||||
```
|
||||
The-config-yml-file
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: sum
|
||||
---
|
||||
|
||||
{% since %}v10.10.0{% endsince %}
|
||||
|
||||
Computes the sum of all the numbers in an array.
|
||||
An optional argument specifies which property of the array's items to sum up.
|
||||
|
||||
In this example, assume the object `cart.products` contains an array of all products in the cart of a website.
|
||||
Assume each cart product has a `qty` property that gives the count of that product instance in the cart.
|
||||
Using the `sum` filter we can calculate the total number of products in the cart.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
The cart has {{ order.products | sum: "qty" }} products.
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
The cart has 7 products.
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: to_integer
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Convert values to number.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "123" | to_integer | json }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
123
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: unshift
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
Unshift an element to the front of the array. It's NON-DESTRUCTIVE, i.e. it does not mutate the array, but rather make a copy and mutate that.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign fruits = "oranges, peaches" | split: ", " %}
|
||||
|
||||
{% assign everything = fruits | unshift: "apples" %}
|
||||
|
||||
{% for item in everything %}
|
||||
- {{ item }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- apples
|
||||
- oranges
|
||||
- peaches
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: uri_escape
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Percent encodes any special characters in a URI. URI escape normally replaces a space with `%20`. [Reserved characters][reserved] will not be escaped.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "https://example.com/?q=foo, \bar?" | uri_escape }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
https://example.com/?q=foo,%20%5Cbar?
|
||||
```
|
||||
|
||||
[reserved]: https://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters
|
||||
@@ -79,4 +79,28 @@ Output
|
||||
Featured product: Hawaiian print sweater vest
|
||||
```
|
||||
|
||||
Additionally, `property` can be any valid Liquid variable expression as used in output syntax, except that the scope of this expression is within each item. For the following `products` array:
|
||||
|
||||
```javascript
|
||||
const products = [
|
||||
{ meta: { details: { class: 'A' } }, order: 1 },
|
||||
{ meta: { details: { class: 'B' } }, order: 2 },
|
||||
{ meta: { details: { class: 'B' } }, order: 3 }
|
||||
]
|
||||
```
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% assign selected = products | where: 'meta.details["class"]', "B" %}
|
||||
{% for item in selected -%}
|
||||
- {{ item.order }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
- 2
|
||||
- 3
|
||||
```
|
||||
|
||||
[truthy]: ../tutorials/truthy-and-falsy.html
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: where_exp
|
||||
---
|
||||
|
||||
{% since %}v10.12.0{% endsince %}
|
||||
|
||||
Select all the objects in an array where the expression is true. In this example, assume you have a list of products and you want to show your kitchen products separately. Using `where_exp`, you can create an array containing only the products that have a `"type"` of `"kitchen"`.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
All products:
|
||||
{% for product in products %}
|
||||
- {{ product.title }}
|
||||
{% endfor %}
|
||||
|
||||
{% assign kitchen_products = products | where_exp: "item", "item.type == 'kitchen'" %}
|
||||
|
||||
Kitchen products:
|
||||
{% for product in kitchen_products %}
|
||||
- {{ product.title }}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
All products:
|
||||
- Vacuum
|
||||
- Spatula
|
||||
- Television
|
||||
- Garlic press
|
||||
|
||||
Kitchen products:
|
||||
- Spatula
|
||||
- Garlic press
|
||||
```
|
||||
|
||||
[truthy]: ../tutorials/truthy-and-falsy.html
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: xml_escape
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
Escape some text for use in XML.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "Have you read \'James & the Giant Peach\'?" | xml_escape }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
Have you read 'James & the Giant Peach'?
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
layout: index
|
||||
description: LiquidJS is a simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.
|
||||
description: LiquidJS is a simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript.
|
||||
subtitle: A simple, expressive and safe template engine.
|
||||
---
|
||||
ul#intro-feature-list
|
||||
@@ -13,14 +13,14 @@ ul#intro-feature-list
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
i.icon-rocket
|
||||
h3.intro-feature-title Zero Dependency
|
||||
p.intro-feature-desc Written with zero npm dependency and no native binding, available in both Node.js and browsers. All of the CMD, ESM and CJS bundles are available on CDN.
|
||||
h3.intro-feature-title Pure JavaScript
|
||||
p.intro-feature-desc Written with pure JavaScript with no native bindings, available in both Node.js and browsers. All of the CMD, ESM and CJS bundles are available on CDN.
|
||||
li.intro-feature-wrap
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
i.icon-shopify
|
||||
h3.intro-feature-title Shopify Compatible
|
||||
p.intro-feature-desc All filters and tags from Ruby #[a(href="https://github.com/shopify/liquid") shopify/liquid] are supported by LiquidJS. #[a(href="https://jekyllrb.com/") Jekyll sites], #[a(href="https://pages.github.com/") Github Pages] and #[a(href="https://themes.shopify.com/") Shopify templates] can be ported to Node.js without pain.
|
||||
p.intro-feature-desc All filters and tags from Ruby #[a(href="https://github.com/shopify/liquid") shopify/liquid] are supported by LiquidJS. #[a(href="https://jekyllrb.com/") Jekyll sites], #[a(href="https://pages.github.com/") GitHub Pages] and #[a(href="https://themes.shopify.com/") Shopify templates] can be ported to Node.js without pain.
|
||||
li.intro-feature-wrap
|
||||
.intro-feature
|
||||
.intro-feature-icon
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"short_name": "LiquidJS",
|
||||
"name": "LiquidJS",
|
||||
"description": "A simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.",
|
||||
"description": "A simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript.",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon/apple-touch-icon-57x57.png",
|
||||
|
||||
@@ -15,7 +15,7 @@ Input
|
||||
{% when "cookie", "biscuit" %}
|
||||
This is a cookie
|
||||
{% else %}
|
||||
This is not a cake nor a cookie
|
||||
This is neither a cake nor a cookie
|
||||
{% endcase %}
|
||||
```
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Tags
|
||||
description: Description and demo for each Liquid tag
|
||||
---
|
||||
|
||||
LiquidJS implements business-logic independent tags that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demoes for all the tags implemented by LiquidJS.
|
||||
LiquidJS implements business-logic independent tags that are typically implemented in [shopify/liquid][shopify/liquid]. This section contains the specification and demos for all the tags implemented by LiquidJS.
|
||||
|
||||
There're a dozen of tags supported by LiquidJS, with all tags in [shopify/liquid][shopify/liquid]. These tags can be categorized into these groups:
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ engine.registerFilter('fullURL', function (path) {
|
||||
})
|
||||
```
|
||||
|
||||
See this JSFiddle: <http://jsfiddle.net/ctj364up/1/>
|
||||
See this JSFiddle: <https://jsfiddle.net/ctj364up/1/>
|
||||
|
||||
{% note warn Arrow Functions %}
|
||||
<code>this</code> in arrow functions is bound to current JavaScript context, you'll need to use <code>function(){}</code> instead of <code>()=>{}</code> syntax to access <code>this.context</code> correctly.
|
||||
|
||||
@@ -6,7 +6,7 @@ In a typical website project, we'll have a directory of view templates and they'
|
||||
|
||||
LiquidJS provides multiple ways to cache the parsed templates to improve performance.
|
||||
|
||||
## Programmaticly
|
||||
## Programmatically
|
||||
|
||||
The [.parse()][parse], [.parseFile()][parseFile], [.parseFileSync()][parseFileSync] APIs are used to parse templates from string or files. The result template can be then rendered multiple times with different context.
|
||||
|
||||
@@ -28,7 +28,7 @@ engine.renderSync(tpl, {name: 'alice'}) // 'Alice'
|
||||
engine.renderSync(tpl, {name: 'bob'}) // 'Bob'
|
||||
```
|
||||
|
||||
The template string/file is parsed only once and renderd multiple times using different context. Templates for different files can be stored into a `Map` and can be retrieved directly for subsequent renders.
|
||||
The template string/file is parsed only once and rendered multiple times using different context. Templates for different files can be stored into a `Map` and can be retrieved directly for subsequent renders.
|
||||
|
||||
## The `cache` Option
|
||||
|
||||
|
||||
@@ -20,21 +20,11 @@ Getting started and building is described in [CONTRIBUTING.md](https://github.co
|
||||
|
||||
## Financial Support
|
||||
|
||||
LiquidJS is Open Source and Free. To help it live and thrive, please consider contribute on [Open Collective][oc]. To acknowledge your contribution, your name and avatar will be listed here, on LiquidJS [homepage](https://liquidjs.com/) and on [Github README][liquidjs]. Please provide your Github ID by openning an issue or contacting me through Twitter (harttleharttle), I can help add you into [the contributors table](https://github.com/harttle/liquidjs#contributors-).
|
||||
|
||||
### Backers
|
||||
If you personally like LiquidJS and find it's useful to you, you can become a backer!
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/backers.svg?avatarHeight=72"></object>
|
||||
|
||||
### Sponsors
|
||||
If LiquidJS is benefiting your business/company, please sponsor us to make it better!
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/sponsors.svg?avatarHeight=72"></object>
|
||||
LiquidJS is Open Source and Free. To help it live and thrive, especially when LiquidJS is benefiting your business, please consider contribute on [GitHub Sponsors](https://github.com/sponsors/harttle) or [Open Collective][oc]. If I'm missing anything, find me via Twitter (harttleharttle) or email (harttleharttle at gmail), to add you into [the contributors table](https://github.com/harttle/liquidjs#contributors-).
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/contribute/backer-10665/checkout
|
||||
[shopify/liquid]: https://shopify.github.io/liquid/
|
||||
[caniuse-promises]: http://caniuse.com/#feat=promises
|
||||
[caniuse-promises]: https://caniuse.com/#feat=promises
|
||||
[pp]: https://github.com/taylorhakes/promise-polyfill
|
||||
[tutorial]: https://shopify.github.io/liquid/basics/introduction/
|
||||
[liquidjs]: https://github.com/harttle/liquidjs
|
||||
|
||||
@@ -4,9 +4,9 @@ title: Differences with Shopify/liquid
|
||||
|
||||
## Compatibility
|
||||
|
||||
Being compatible the Ruby version is one of our priorities. Liquid language is originally [implemented in Ruby][ruby-liquid] and used by Shopify, Jekyll and thus Github Pages, as you can see it's one of the most popular template engines in Ruby. There're lots of people using LiquidJS to serve their templates originally written for Shopify themes and Jekyll sites.
|
||||
Being compatible with the Ruby version is one of our priorities. Liquid language is originally [implemented in Ruby][ruby-liquid] and used by Shopify and Jekyll (and thus GitHub Pages). As you can see it's one of the most popular template engines in Ruby. There're lots of people using LiquidJS to serve their templates originally written for Shopify themes and Jekyll sites.
|
||||
|
||||
So "being compatible" means serve developers from Shopify and Jekyll well:
|
||||
So "being compatible" means serving developers from Shopify and Jekyll well:
|
||||
|
||||
- **Well-formed Liquid template should work just fine in LiquidJS**. For example, `forloop.index` should be 1-indexed, `nil` should be rendered as empty string rather than `undefined`, etc. Although some features (e.g. [#236][#236]) are not feasible in JavaScript, at least we're trying to implement all the semantics of Liquid language.
|
||||
- **All filters and tags in [shopify/liquid][ruby-liquid] are supposed to be built in LiquidJS**. But not those business-logic specific tags/filters typically defined by Shopify platform. Those features should be maintained as [plugins][plugins]. For filters/tags that are not business-logic specific, like `{% layout %}`, and extremely useful, feel free to file an issue.
|
||||
@@ -16,7 +16,7 @@ In the meantime, it's now implemented in JavaScript, that means it has to be mor
|
||||
* **Async as first-class citizen**. Filters and tags can be implemented asynchronously by return a `Promise`.
|
||||
* **Also can be sync**. For scenarios that are not I/O intensive, render synchronously can be much faster. You can call synchronous APIs like `.renderSync()` as long as all the filters and tags in template support to be rendered synchronously. All builtin filters/tags support both sync and async render.
|
||||
* **[Abstract file system][afs]**. Along with async feature, LiquidJS can be used to serve templates stored in Databases [#414][#414], on remote HTTP server [#485][#485], and so on.
|
||||
* **Additional tags and filters** like `layout` and `json`.
|
||||
* **Additional tags and filters** like `layout` and `json`, `inspect`, `where_exp`, `group_by`, etc., see below for details.
|
||||
|
||||
## Differences
|
||||
|
||||
@@ -29,11 +29,16 @@ Though we're trying to be compatible with the Ruby version, there are still some
|
||||
* Iteration order for objects. The iteration order of JavaScript objects, and thus LiquidJS objects, is a combination of the insertion order for string keys, and ascending order for number-like keys, while the iteration order of Ruby Hash is simply the insertion order.
|
||||
* Sort stability. The [sort][sort] stability is also not defined in both shopify/liquid and LiquidJS, but it's [considered stable][stable-sort] for LiquidJS in Node.js 12+ and Google Chrome 70+.
|
||||
* Trailing unmatched characters inside filters are allowed in shopify/liquid but not in LiquidJS. It means filter arguments without a colon like `{%raw%}{{ "a b" | split " "}}{%endraw%}` will throw an error in LiquidJS. This is intended to improve Liquid usability, see [#208][#208] and [#212][#212].
|
||||
* LiquidJS has additional tags: [layout][layout] and corresponding `block` tag.
|
||||
* LiquidJS [date][date] filter supports `%q` for date ordinals like `{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb`
|
||||
* LiquidJS has more tags/filters than [the Liquid language][liquid]:
|
||||
* LiquidJS-defined tags: [layout][layout], [render][render] and corresponding `block` tag.
|
||||
* LiquidJS-defined filters: [json][json], group_by, group_by_exp, where_exp, jsonify, inspect, etc.
|
||||
* Tags/filters that don't depend on Shopify platform are borrowed from [Shopify][shopify-tags].
|
||||
* Tags/filters that don't depend on Jekyll framework are borrowed from [Jekyll][jekyll-filters].
|
||||
* Some tags/filters behave differently: [date][date] filter, malformed tags (like duplicated `else`, extra args for `endif`) throw errors in LiquidJS.
|
||||
|
||||
[date]: https://liquidjs.com/filters/date.html
|
||||
[layout]: https://liquidjs.com/tags/layout.html
|
||||
[layout]: ../tags/layout.html
|
||||
[render]: ../tags/render.html
|
||||
[json]: https://liquidjs.com/filters/json.html
|
||||
[#26]: https://github.com/harttle/liquidjs/pull/26
|
||||
[#59]: https://github.com/harttle/liquidjs/issues/59
|
||||
@@ -47,3 +52,6 @@ Though we're trying to be compatible with the Ruby version, there are still some
|
||||
[plugins]: ./plugins.html#Plugin-List
|
||||
[ruby-liquid]: https://github.com/Shopify/liquid
|
||||
[afs]: https://liquidjs.com/tutorials/render-file.html#Abstract-File-System
|
||||
[liquid]: https://shopify.github.io/liquid/basics/introduction/
|
||||
[shopify-tags]: https://shopify.dev/docs/api/liquid/tags
|
||||
[jekyll-filters]: https://jekyllrb.com/docs/liquid/filters/
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: DoS Prevention
|
||||
---
|
||||
|
||||
When the template or data context cannot be trusted, enabling DoS prevention options is crucial. LiquidJS provides 3 options for this purpose: `parseLimit`, `renderLimit`, and `memoryLimit`.
|
||||
|
||||
## TL;DR
|
||||
|
||||
Setting these options can largely ensure that your LiquidJS instance won't hang for extended periods or consume excessive memory. These limits are based on the available JavaScript APIs, so they are not precise hard limits but thresholds to help prevent your process from failing or hanging.
|
||||
|
||||
```typescript
|
||||
const liquid = new Liquid({
|
||||
parseLimit: 1e8, // typical size of your templates in each render
|
||||
renderLimit: 1000, // limit each render to be completed in 1s
|
||||
memoryLimit: 1e9, // memory available for LiquidJS (1e9 for 1GB)
|
||||
})
|
||||
```
|
||||
|
||||
When a `parse()` or `render()` cannot be completed within given resource, it throws.
|
||||
|
||||
## parseLimit
|
||||
|
||||
[parseLimit][parseLimit] restricts the size (character length) of templates parsed in each `.parse()` call, including referenced partials and layouts. Since LiquidJS parses template strings in near O(n) time, limiting total template length is usually sufficient.
|
||||
|
||||
A typical PC handles `1e8` (100M) characters without issues.
|
||||
|
||||
## renderLimit
|
||||
|
||||
Restricting template size alone is insufficient because dynamic loops with large counts can occur in render time. [renderLimit][renderLimit] mitigates this by limiting the time consumed by each `render()` call.
|
||||
|
||||
```liquid
|
||||
{%- for i in (1..10000000) -%}
|
||||
order: {{i}}
|
||||
{%- endfor -%}
|
||||
```
|
||||
|
||||
Render time is checked on a per-template basis (before rendering each template). In the above example, there are 2 templates in the loop: `order: ` and `{{i}}`, render time will be checked 10000000x2 times.
|
||||
|
||||
For time-consuming tags and filters within a single template, the process can still hang. For fully controlled rendering, consider using a process manager like [paralleljs][paralleljs].
|
||||
|
||||
## memoryLimit
|
||||
|
||||
Even with small number of templates and iterations, memory usage can grow exponentially. In the following example, memory doubles with each iteration:
|
||||
|
||||
```liquid
|
||||
{% assign array = "1,2,3" | split: "," %}
|
||||
{% for i in (1..32) %}
|
||||
{% assign array = array | concat: array %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
[memoryLimit][memoryLimit] restricts memory-sensitive filters to prevent excessive memory allocation. As [JavaScript uses GC to manage memory](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management), `memoryLimit` limits only the total number of objects allocated by memory sensitive filters in LiquidJS thus may not reflect the actual memory footprint.
|
||||
|
||||
[paralleljs]: https://www.npmjs.com/package/paralleljs
|
||||
[parseLimit]: /api/interfaces/LiquidOptions.html#parseLimit
|
||||
[renderLimit]: /api/interfaces/LiquidOptions.html#renderLimit
|
||||
[memoryLimit]: /api/interfaces/LiquidOptions.html#memoryLimit
|
||||
@@ -0,0 +1,201 @@
|
||||
---
|
||||
title: Liquid Drops
|
||||
---
|
||||
|
||||
LiquidJS also provides a mechanism similar to [Shopify Drops][shopify-drops], allowing template authors to incorporate custom functionality in resolving variable values.
|
||||
|
||||
{% note info Drop for JavaScript %}
|
||||
<em>Drop</em> interface is implemented differently in LiquidJS compared to built-in filters and other template functionalities. Since LiquidJS runs in JavaScript, custom Drops need to be reimplemented in JavaScript anyway. There's no compatibility between JavaScript classes and Ruby classes.
|
||||
{% endnote %}
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```javascript
|
||||
import { Liquid, Drop } from 'liquidjs'
|
||||
|
||||
class SettingsDrop extends Drop {
|
||||
constructor() {
|
||||
super()
|
||||
this.foo = 'FOO'
|
||||
}
|
||||
bar() {
|
||||
return 'BAR'
|
||||
}
|
||||
}
|
||||
|
||||
const engine = new Liquid()
|
||||
const template = `foo: {{settings.foo}}, bar: {{settings.bar}}`
|
||||
const context = { settings: new SettingsDrop() }
|
||||
// Outputs: "foo: FOO, bar: BAR"
|
||||
engine.parseAndRender(template, context).then(html => console.log(html))
|
||||
```
|
||||
|
||||
[Runkit link](https://runkit.com/embed/2is7di4mc7kk)
|
||||
|
||||
As shown above, besides reading properties from context scopes, you can also call methods. You only need to create a custom class inherited from `Drop`.
|
||||
|
||||
{% note tip Async Methods %}
|
||||
LiquidJS is fully async-friendly. You can safely return a Promise in your Drop methods or define your methods in Drop as `async`.
|
||||
{% endnote %}
|
||||
|
||||
## liquidMethodMissing
|
||||
|
||||
For cases when there isn't a fixed set of properties, you can leverage `liquidMethodMissing` to dynamically resolve the value of a variable name.
|
||||
|
||||
```javascript
|
||||
import { Liquid, Drop } from 'liquidjs'
|
||||
|
||||
class SettingsDrop extends Drop {
|
||||
liquidMethodMissing(key) {
|
||||
return key.toUpperCase()
|
||||
}
|
||||
}
|
||||
|
||||
const engine = new Liquid()
|
||||
// Outputs: "COO"
|
||||
engine.parseAndRender("{{settings.coo}}", { settings: new SettingsDrop() })
|
||||
.then(html => console.log(html))
|
||||
```
|
||||
|
||||
`liquidMethodMissing` supports Promise, meaning you can make async calls within it. A more useful case can be fetching the value dynamically from the database. By using Drops, you can avoid hardcoding each property into the context. For example:
|
||||
|
||||
```javascript
|
||||
import { Liquid, Drop } from 'liquidjs'
|
||||
|
||||
class DBDrop extends Drop {
|
||||
async liquidMethodMissing(key) {
|
||||
const record = await db.getRecordByKey(key)
|
||||
return record.value
|
||||
}
|
||||
}
|
||||
|
||||
const engine = new Liquid()
|
||||
const context = { db: new DBDrop() }
|
||||
engine.parseAndRender("{{db.coo}}", context).then(html => console.log(html))
|
||||
```
|
||||
|
||||
## valueOf
|
||||
|
||||
Drops can implement a `valueOf()` method, the return value of which can be used to replace itself in the output. For example:
|
||||
|
||||
```javascript
|
||||
import { Liquid, Drop } from 'liquidjs'
|
||||
|
||||
class ColorDrop extends Drop {
|
||||
valueOf() {
|
||||
return 'red'
|
||||
}
|
||||
}
|
||||
|
||||
const engine = new Liquid()
|
||||
const context = { color: new ColorDrop() }
|
||||
// Outputs: "red"
|
||||
engine.parseAndRender("{{color}}", context).then(html => console.log(html))
|
||||
```
|
||||
|
||||
## toLiquid
|
||||
|
||||
`toLiquid()` is not a method of `Drop`, but it can be used to return a `Drop`. In cases where you have a fixed structure in the `context` that cannot change its values, you can implement `toLiquid()` to let LiquidJS use the returned value instead of itself to render the templates.
|
||||
|
||||
```javascript
|
||||
import { Liquid, Drop } from 'liquidjs'
|
||||
|
||||
const context = {
|
||||
person: {
|
||||
firstName: "Jun",
|
||||
lastName: "Yang",
|
||||
name: "Jun Yang",
|
||||
toLiquid: () => ({
|
||||
firstName: this.firstName,
|
||||
lastName: this.lastName,
|
||||
// use a different `name`
|
||||
name: "Yang, Jun"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const engine = new Liquid()
|
||||
// Outputs: "Yang, Jun"
|
||||
engine.parseAndRender("{{person.name}}", context).then(html => console.log(html))
|
||||
```
|
||||
|
||||
Of course, you can also return a `PersonDrop` instance in the `toLiquid()` method and implement this functionality within `PersonDrop`:
|
||||
|
||||
```javascript
|
||||
import { Liquid, Drop } from 'liquidjs'
|
||||
|
||||
class PersonDrop extends Drop {
|
||||
constructor(person) {
|
||||
super()
|
||||
this.person = person
|
||||
}
|
||||
name() {
|
||||
return this.person.lastName + ", " + this.person.firstName
|
||||
}
|
||||
}
|
||||
|
||||
const context = {
|
||||
person: {
|
||||
firstName: "Jun",
|
||||
lastName: "Yang",
|
||||
name: "Jun Yang",
|
||||
toLiquid: function () { return new PersonDrop(this) }
|
||||
}
|
||||
}
|
||||
|
||||
const engine = new Liquid()
|
||||
// Outputs: "Yang, Jun"
|
||||
engine.parseAndRender("{{person.name}}", context).then(html => console.log(html))
|
||||
```
|
||||
|
||||
{% note info <code>toLiquid()</code> vs. <code>valueOf()</code> Difference %}
|
||||
<ul>
|
||||
<li><code>valueOf()</code> is typically used to define how the current variable should be rendered, while <code>toLiquid()</code> is often used to convert an object into a Drop or another scope provided to the template.</li>
|
||||
<li><code>valueOf()</code> is a method exclusive to Drops; whereas <code>toLiquid()</code> can be used on any scope object.</li>
|
||||
<li><code>valueOf()</code> is called when the variable itself is about to be rendered, replacing itself; whereas <code>toLiquid()</code> is called when its properties are about to be read.</li>
|
||||
</ul>
|
||||
{% endnote %}
|
||||
|
||||
## Special Drops
|
||||
|
||||
LiquidJS itself implements several built-in drops to facilitate template writing. This part is compatible with Shopify Liquid, as we need templates to be portable.
|
||||
|
||||
### blank
|
||||
|
||||
Useful to check whether a string variable is `false`, `null`, `undefined`, an empty string, or a string containing only blank characters.
|
||||
|
||||
```liquid
|
||||
{% unless author == blank %}
|
||||
{{author}}
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### empty
|
||||
|
||||
Useful to check if an array, string, or object is empty.
|
||||
|
||||
```liquid
|
||||
{% if authors == empty %}
|
||||
Author list is empty
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
{% note info <code>empty</code> implementation %}
|
||||
For arrays and strings, LiquidJS checks their `.length` property. For objects, LiquidJS calls `Object.keys()` to check whether they have keys.
|
||||
{% endnote %}
|
||||
|
||||
### nil
|
||||
|
||||
`nil` Drop is used to check whether a variable is not defined or defined as `null` or `undefined`, essentially equivalent to JavaScript `== null` check.
|
||||
|
||||
```liquid
|
||||
{% if nonexistent == nil %}
|
||||
null variable
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### Other Drops
|
||||
|
||||
There are still several Drops for specific tags, like `forloop`, `tablerowloop`, `block`, which are covered by respective tag documents.
|
||||
|
||||
[shopify-drops]: https://github.com/Shopify/liquid/wiki/Introduction-to-Drops
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Escaping
|
||||
---
|
||||
|
||||
Escaping is important in all languages, including LiquidJS. While escaping has 2 different meanings for a template engine:
|
||||
|
||||
1. Escaping for the output, i.e. HTML escape. Used to escape HTML special characters so the output will not break HTML structures, aka HTML safe.
|
||||
2. Escaping for the language itself, i.e. Liquid escape. Used to output strings that's considered special in Liquid language. This will be useful when you're writing an article in Liquid template to introduce Liquid language.
|
||||
|
||||
## HTML Escape
|
||||
|
||||
By default output is not escaped. While you can use [escape][escape] filter for this:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "1 < 2" | escape }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 < 2
|
||||
```
|
||||
|
||||
There's also [escape_once][escape_once], [newline_to_br][newline_to_br], [strip_html][strip_html] filters for you to fine tune your output.
|
||||
|
||||
In cases where variables are mostly not trusted, [outputEscape][outputEscape] can be set to `"escape"` to apply escape by default. In this case, when you need some output not to be escaped, [raw][raw] filter can be used:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "1 < 2" }}
|
||||
{{ "<button>OK</button>" | raw }}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
1 < 2
|
||||
<button>OK</button>
|
||||
```
|
||||
|
||||
## Liquid Escape
|
||||
|
||||
To disable Liquid language and output strings like `{{` and `{%`, the [raw][raw] tag can be used.
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{% raw %}
|
||||
In LiquidJS, {{ this | escape }} will be HTML-escaped, but
|
||||
{{{ that }}} will not.
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
In LiquidJS, {{ this | escape }} will be HTML-escaped, but
|
||||
{{{ that }}} will not.
|
||||
```
|
||||
|
||||
Within strings literals in LiquidJS template, `\` can be used to escape special characters in string syntax. For example:
|
||||
|
||||
Input
|
||||
```liquid
|
||||
{{ "\"" }}
|
||||
```
|
||||
|
||||
Output
|
||||
```liquid
|
||||
"
|
||||
```
|
||||
|
||||
[outputEscape]: ./options.html#outputEscape
|
||||
[escape]: ../filters/escape.html
|
||||
[raw]: ../filters/raw.html
|
||||
[escape_once]: ../filters/escape.html
|
||||
[strip_html]: ../filters/strip_html.html
|
||||
[newline_to_br]: ../filters/newline_to_br.html
|
||||
[raw]: ../tags/raw.html
|
||||
@@ -3,7 +3,7 @@ title: The Liquid Template Language
|
||||
describe: A short introduction to the Liquid template language and some simple demos.
|
||||
---
|
||||
|
||||
LiquidJS is a simple, expressive and safe [Shopify][shopify/liquid] / Github Pages compatible template engine in pure JavaScript. The purpose of this repo is to provide a standard Liquid implementation for the JavaScript community. Liquid is originally implemented in Ruby and used by Github Pages, Jekyll and Shopify, see [Differences with Shopify/liquid][diff].
|
||||
LiquidJS is a simple, expressive and safe [Shopify][shopify/liquid] / GitHub Pages compatible template engine in pure JavaScript. The purpose of this repo is to provide a standard Liquid implementation for the JavaScript community. Liquid is originally implemented in Ruby and used by GitHub Pages, Jekyll and Shopify, see [Differences with Shopify/liquid][diff].
|
||||
|
||||
LiquidJS syntax is relatively simple. There're 2 types of markups in LiquidJS:
|
||||
|
||||
|
||||
@@ -26,4 +26,4 @@ LiquidJS 9 has some fundamental improvements, including bugfixes, new features a
|
||||
|
||||
* LiquidJS no longer has a default export, use `import {Liquid} from 'liquidjs'` instead. The `window.Liquid` for the UMD bundle is also changed to `window.liquidjs.Liquid`;
|
||||
* The duplicate static method `Liquid.evalValue` is removed, use the instance method `liquid.evalValue` instead;
|
||||
* Shipped to Node.js 8, the CJS bundle (main entry in Node.js) nolonger supports Node.js ≤ 6. ESM (dist/liquid.node.esm.js) and UMD (dist/liquid.browser.umd.js, dist/liquid.browser.min.js) bundles are not affected.
|
||||
* Shipped to Node.js 8, the CJS bundle (main entry in Node.js) no longer supports Node.js ≤ 6. ESM (dist/liquid.node.esm.js) and UMD (dist/liquid.browser.umd.js, dist/liquid.browser.min.js) bundles are not affected.
|
||||
@@ -98,10 +98,18 @@ Before 2.0.1, <code>extname</code> is set to `.liquid` by default. To change tha
|
||||
|
||||
## jsTruthy
|
||||
|
||||
**jsTruthy** is used to use standard Javascript truthiness rather than the Shopify.
|
||||
**jsTruthy** is used to use standard JavaScript truthiness rather than the Shopify.
|
||||
|
||||
it defaults to false. For example, when set to true, a blank string would evaluate to false with jsTruthy. With Shopify's truthiness, a blank string is true.
|
||||
|
||||
## outputEscape
|
||||
|
||||
[outputEscape][outputEscape] can be used to automatically escape output strings. It can be one of `"escape"`, `"json"`, or `(val: unknown) => string`, defaults to `undefined`.
|
||||
|
||||
- For untrusted output variables, set `outputEscape: "escape"` makes them be HTML escaped by default. You'll need [raw][raw] filter for direct output.
|
||||
- `"json"` is useful when you're using LiquidJS to create valid JSON files.
|
||||
- It can even be a function which allows you to control what variables are output throughout LiquidJS. Please note the input can be any type other than string, e.g. an filter returned an non-string value.
|
||||
|
||||
## Date
|
||||
|
||||
**timezoneOffset** is used to specify a different timezone to output dates, your local timezone will be used if not specified. For example, set `timezoneOffset: 0` to output all dates in UTC/GMT 00:00.
|
||||
@@ -132,8 +140,8 @@ it defaults to false. For example, when set to true, a blank string would evalu
|
||||
|
||||
**ownPropertyOnly** hides scope variables from prototypes, useful when you're passing a not sanitized object into LiquidJS or need to hide prototypes from templates. Defaults to `true`.
|
||||
|
||||
{% note info Non-existent Tags %}
|
||||
Non-existent tags always throw errors during parsing and this behavior can not be customized.
|
||||
{% note info Nonexistent Tags %}
|
||||
Nonexistent tags always throw errors during parsing and this behavior cannot be customized.
|
||||
{% endnote %}
|
||||
|
||||
## Parameter Order
|
||||
@@ -151,3 +159,5 @@ Parameter orders are ignored by default, for ea `{% for i in (1..8) reversed lim
|
||||
[wc]: ./whitespace-control.html
|
||||
[intro]: ./intro-to-liquid.html
|
||||
[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude
|
||||
[raw]: ../filters/raw.html
|
||||
[outputEscape]: /api/interfaces/LiquidOptions.html#outputEscape
|
||||
|
||||
@@ -23,7 +23,7 @@ engine.registerTag('random', {
|
||||
})
|
||||
```
|
||||
|
||||
Here's a JSFiddle version: <http://jsfiddle.net/ctj364up/2/>
|
||||
Here's a JSFiddle version: <https://jsfiddle.net/ctj364up/2/>
|
||||
|
||||
## Parse Parameters as Values
|
||||
|
||||
@@ -58,9 +58,9 @@ engine.registerTag('random', {
|
||||
})
|
||||
```
|
||||
|
||||
Calling this tag in scope `{ bar: "bar", obj: { coo: "coo" } }` yields exactly the same result as the first example. See this JSFiddle: <http://jsfiddle.net/ctj364up/3/>
|
||||
Calling this tag in scope `{ bar: "bar", obj: { coo: "coo" } }` yields exactly the same result as the first example. See this JSFiddle: <https://jsfiddle.net/ctj364up/3/>
|
||||
|
||||
{% note info Async ans Promises %}
|
||||
{% note info Async and Promises %}
|
||||
Async calls in LiquidJS are implemented by generators directly, for we can call generators in synchronous manner so this tag implementation is also valid for `renderSync()`, `parseAndRenderSync()`, `renderFileSync()`. If you need to await a promise in tag implementation, simply replace `await somePromise` with `yield somePromise` and keep `* render()` instead of `async render()` will do the trick. See <a href="/tutorials/sync-and-async.html">Sync and Async</a> for more details.
|
||||
{% endnote %}
|
||||
|
||||
@@ -92,7 +92,7 @@ engine.registerTag('random', {
|
||||
})
|
||||
```
|
||||
|
||||
Rendering `{% random from:2, to:max %}` in scope `{ max: 10 }` will generate a random number in the range [2, 10]. See this JSFiddle: <http://jsfiddle.net/ctj364up/4/>
|
||||
Rendering `{% raw %}{% random from:2, to:max %}{% endraw %}` in scope `{ max: 10 }` will generate a random number in the range [2, 10]. See this JSFiddle: <https://jsfiddle.net/ctj364up/4/>
|
||||
|
||||
|
||||
[register-tags]: /tutorials/register-filters-tags.html
|
||||
|
||||
@@ -36,7 +36,7 @@ engine
|
||||
|
||||
## Plugin List
|
||||
|
||||
Since this library excludes certain features that are available on the Shopify platform but not on the [Shopify/liquid](https://github.com/Shopify/liquid/) repo, see <https://github.com/harttle/liquidjs#differences-and-limitations>.
|
||||
Since this library excludes certain features that are available on the Shopify platform but not on the [Shopify/liquid](https://github.com/Shopify/liquid/) repo, see [Differences with Shopify/liquid][differences].
|
||||
|
||||
Here's a list of plugins that backfill those features. Feel free to add yours, this file is publicly editable.
|
||||
|
||||
@@ -44,4 +44,5 @@ Here's a list of plugins that backfill those features. Feel free to add yours, t
|
||||
* Color Filters: https://github.com/harttle/liquidjs-color-filters
|
||||
|
||||
[liquid]: /api/classes/Liquid.html
|
||||
[register]: /harttle/liquidjs/wiki/Register-Filters-Tags
|
||||
[register]: /harttle/liquidjs/wiki/Register-Filters-Tags
|
||||
[differences]: /tutorials/differences.html
|
||||
|
||||
@@ -52,23 +52,23 @@ var engine = new Liquid({
|
||||
|
||||
{% note tip Relative Paths %}Relative paths in <code>root</code> will be resolved against <code>cwd()</code>.{% endnote %}
|
||||
|
||||
When `{% raw %}{% render "foo" %}{% endraw %}` is renderd or `liquid.renderFile('foo')` is called, the following files will be looked up and the first existing file will be used:
|
||||
When `{% raw %}{% render "foo" %}{% endraw %}` is rendered or `liquid.renderFile('foo')` is called, the following files will be looked up and the first existing file will be used:
|
||||
|
||||
- `cwd()`/views/foo.liquid
|
||||
- `cwd()`/views/partials/foo.liquid
|
||||
|
||||
If none of the above files exists, an `ENOENT` error will be throwed. Here's a demo for Node.js: [demo/nodejs](https://github.com/harttle/liquidjs/tree/master/demo/nodejs).
|
||||
If none of the above files exists, an `ENOENT` error will be thrown. Here's a demo for Node.js: [demo/nodejs](https://github.com/harttle/liquidjs/tree/master/demo/nodejs).
|
||||
|
||||
When LiquidJS is used in browser, say current location is <https://example.com/bar/index.html>, only the first `root` will be used and the file to be fetched is:
|
||||
|
||||
- <https://example.com/bar/foo.liquid>
|
||||
|
||||
If fetch fails, a 404/500 error or network failures for example, an `ENOENT` error will be throwed.
|
||||
If fetch fails, a 404/500 error or network failures for example, an `ENOENT` error will be thrown.
|
||||
Here's a demo for browsers: [demo/browser](https://github.com/harttle/liquidjs/tree/master/demo/browser).
|
||||
|
||||
## Abstract File System
|
||||
|
||||
LiquidJS defines an abstract file system interface in [src/fs/fs.ts][ifs] and the default implementation is [src/fs/fs-impl.ts][fs-node] for Node.js and [src/build/fs-impl-browser.ts][fs-browser] for the browser bundle.
|
||||
LiquidJS defines an [abstract file system interface][ifs] and the default implementation is [src/fs/fs-impl.ts][fs-node] for Node.js and [src/build/fs-impl-browser.ts][fs-browser] for the browser bundle.
|
||||
|
||||
The `Liquid` constructor provides a [fs][fs] option to specify the file system implementation. It's supposed to be used to define customized template fetching logic, i.e. fetch template from a database table, like:
|
||||
|
||||
@@ -100,6 +100,23 @@ var engine = new Liquid({
|
||||
|
||||
{% note warn Path Traversal Vulnerability %}The default value of <code>contains()</code> always returns true. That means when specifying an abstract file system, you'll need to provide a proper <code>contains()</code> to avoid expose such vulnerabilities.{% endnote %}
|
||||
|
||||
## In-memory Template
|
||||
|
||||
To facilitate rendering w/o files, there's a `templates` option to specify a mapping of filenames and their content. LiquidJS will read templates from the mapping.
|
||||
|
||||
```typescript
|
||||
const engine = new Liquid({
|
||||
templates: {
|
||||
'views/entry': 'header {% include "../partials/footer" %}',
|
||||
'partials/footer': 'footer'
|
||||
}
|
||||
})
|
||||
engine.renderFileSync('views/entry'))
|
||||
// Result: 'header footer'
|
||||
```
|
||||
|
||||
Note that file system options like `root`, `layouts`, `partials`, `relativeReference` will be ignored when `templates` is specified.
|
||||
|
||||
[fs]: /api/interfaces/LiquidOptions.html#fs
|
||||
[ifs]: /api/interfaces/FS.html
|
||||
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts
|
||||
|
||||
@@ -24,8 +24,8 @@ Expected output:
|
||||
|
||||
Firstly, [register][register-tags] a tag with name `wrap` and parse the content into `this.tpls`. Here in `parse(tagToken, remainTokens)`,
|
||||
|
||||
- `tagToken` is current token `{% wrap %}`, and
|
||||
- `remainTokens` is an array of all tokens following `{% wrap %}` until the end of this template file.
|
||||
- `tagToken` is current token `{%raw%}{% wrap %}{%endraw%}`, and
|
||||
- `remainTokens` is an array of all tokens following `{%raw%}{% wrap %}{%endraw%}` until the end of this template file.
|
||||
|
||||
Basically, what we need to do is take/`.shift()` enough tags from `remainTokens` until we got a `endwrap` token (the name can be arbitrary, but in convention, we need it to be `endwrap`). And if there's no `endwrap` until the end of template file, we need to throw an tag-not-closed `Error`.
|
||||
|
||||
@@ -57,7 +57,7 @@ engine.registerTag('wrap', {
|
||||
})
|
||||
```
|
||||
|
||||
`.renderTemplates()` can be async, we need `yield` to wait it complete. More details on async in LiquidJS, please refer to [Sync and Async][async]. Other parts of `render()` method is quite straightforward. Here's a JSFiddle version: <http://jsfiddle.net/por0zcn1/3/>
|
||||
`.renderTemplates()` can be async, we need `yield` to wait it complete. More details on async in LiquidJS, please refer to [Sync and Async][async]. Other parts of `render()` method is quite straightforward. Here's a JSFiddle version: <https://jsfiddle.net/por0zcn1/3/>
|
||||
|
||||
## Using ParseStream
|
||||
|
||||
@@ -75,7 +75,7 @@ parse(tagToken, remainTokens) {
|
||||
}
|
||||
```
|
||||
|
||||
Here's a JSFiddle version: <http://jsfiddle.net/por0zcn1/4/>. For simplicity, the following examples are implemented using `ParseStream`.
|
||||
Here's a JSFiddle version: <https://jsfiddle.net/por0zcn1/4/>. For simplicity, the following examples are implemented using `ParseStream`.
|
||||
|
||||
## Manipulate the Context
|
||||
|
||||
@@ -123,7 +123,7 @@ engine.registerTag('repeat', {
|
||||
})
|
||||
```
|
||||
|
||||
The `parse()` is exactly the same as `wrap` tag, we repeat the content simply by calling `.renderTemplates(this.tpls)` twice during `render()`. Here's the JSFiddle: <http://jsfiddle.net/por0zcn1/2/>
|
||||
The `parse()` is exactly the same as `wrap` tag, we repeat the content simply by calling `.renderTemplates(this.tpls)` twice during `render()`. Here's the JSFiddle: <https://jsfiddle.net/por0zcn1/2/>
|
||||
|
||||
{% note warn Use Push & Pop in Pairs %}
|
||||
`context.push()` and `context.pop()` have to be used in pairs. Failing to `pop()` the *Scope* you pushed will leak the *Scope* to latter templates and may corrupt the *Context* stack.
|
||||
|
||||
@@ -49,7 +49,7 @@ Pre-built UMD bundles are also available:
|
||||
|
||||
{% note info Working Demo %} Here's a living demo on jsFiddle: <a href="https://jsfiddle.net/pd4jhzLs/1/" target="_blank">jsfiddle.net/pd4jhzLs/1/</a>, and the source code is also available in <a href="https://github.com/harttle/liquidjs/blob/master/demo/browser/" target="_blank">liquidjs/demo/browser/</a>.{% endnote %}
|
||||
|
||||
{% note warn Compatibility %} You may need a <a href="https://github.com/taylorhakes/promise-polyfill" target="_blank">Promise polyfill</a> for legacy browsers like IE and Android UC, see <a href="http://caniuse.com/#feat=promises" target="_blank">caniuse statistics</a>. {% endnote %}
|
||||
{% note warn Compatibility %} You may need a <a href="https://github.com/taylorhakes/promise-polyfill" target="_blank">Promise polyfill</a> for legacy browsers like IE and Android UC, see <a href="https://caniuse.com/#feat=promises" target="_blank">caniuse statistics</a>. {% endnote %}
|
||||
|
||||
## LiquidJS in CLI
|
||||
|
||||
@@ -100,4 +100,4 @@ Most of the [options available through the JavaScript API][options] are also ava
|
||||
A ReactJS demo is also added by [@stevenanthonyrevo](https://github.com/stevenanthonyrevo), see [liquidjs/demo/reactjs/](https://github.com/harttle/liquidjs/blob/master/demo/reactjs/).
|
||||
|
||||
[intro]: ./intro-to-liquid.html
|
||||
[options]: ./options.md
|
||||
[options]: ./options.html
|
||||
|
||||
@@ -60,7 +60,7 @@ var engine = new Liquid({
|
||||
```
|
||||
|
||||
[cache]: /api/interfaces/LiquidOptions.html#cache
|
||||
[express-views]: http://expressjs.com/en/guide/using-template-engines.html
|
||||
[express-views]: https://expressjs.com/en/guide/using-template-engines.html
|
||||
[parseFile]: /api/classes/Liquid.html#parseFile
|
||||
[parseFileSync]: /api/classes/Liquid.html#parseFileSync
|
||||
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: array_to_sentence_string
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
把数组转化为句子,用于做标签列表。有一个可选的连接词参数。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "foo,bar,baz" | split: "," | array_to_sentence_string }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
foo, bar, and baz
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "foo,bar,baz" | split: "," | array_to_sentence_string: "or" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
foo, bar, or baz
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: cgi_escape
|
||||
---
|
||||
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
把字符串 CGI 转义,用于 URL。用对应的 `%XX` 替换特殊字符,空格会被转义为 `+` 号。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ "foo, bar; baz?" | cgi_escape }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
foo%2C+bar%3B+baz%3F
|
||||
```
|
||||
@@ -6,6 +6,14 @@ title: date
|
||||
|
||||
把时间戳转换为字符串。LiquidJS 尝试跟 Shopify/Liquid 保持一致,它用的是 Ruby 核心的 [Time#strftime(string)](http://www.ruby-doc.org/core/Time.html#method-i-strftime)。此外 LiquidJS 会先通过 [new Date()][newDate] 尝试把输入转换为 Date 对象。
|
||||
|
||||
但 LiquidJS 支持的格式与 [Ruby 的 flag](https://ruby-doc.org/core/strftime_formatting_rdoc.html) 有些不同:
|
||||
* `%Z`(自 v10.11.1 起支持)只有在传入了时区时才起作用(可以通过 `LiquidOption` 传入,也可以在创建日期时单独传入,见下文)。如果传入的时区是个数字,那么它的表现将会与 `%z` 相同。如果没有传入时区,将会返回 [运行时默认时区](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/resolvedOptions#timezone)。
|
||||
* LiquidJS 提供额外的 `%q` 用来处理序数:`{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb`
|
||||
* 日期字面量会通过 [new Date()][jsDate] 转化为 `Date` 对象,这意味着字面量默认使用运行时默认时区。
|
||||
* 格式字参数是可选的:
|
||||
* 如果不传,默认为 `%A, %B %-e, %Y at %-l:%M %P %z`。
|
||||
* 上述默认值可以通过 [`dateFormat`](/api/interfaces/LiquidOptions.html#dateFormat) 参数覆盖。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ article.published_at | date: "%a, %b %d, %y" }}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: date_to_long_string
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
把日期转换为长格式(只支持 US/UK 两种),与 Jekyll 的 `date_to_long_string` 过滤器一样。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ site.time | date_to_long_string }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
07 November 2008
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ site.time | date_to_long_string: "ordinal" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
7th November 2008
|
||||
```
|
||||
|
||||
|
||||
注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: date_to_rfc822
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
把日期转换为 RFC-822 格式用于 RSS feed,与 Jekyll 的 `date_to_rfc822` 过滤器一样。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ site.time | date_to_rfc822 }}
|
||||
```
|
||||
|
||||
输入
|
||||
```text
|
||||
Mon, 07 Nov 2008 13:07:54 -0800
|
||||
```
|
||||
|
||||
注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: date_to_string
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
把日期转换为短格式(只支持 US/UK 两种),与 Jekyll 的 `date_to_string` 过滤器一样。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ site.time | date_to_string }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
07 Nov 2008
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ site.time | date_to_string: "ordinal", "US" }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
Nov 7th, 2008
|
||||
```
|
||||
|
||||
注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: date_to_xmlschema
|
||||
---
|
||||
{% since %}v10.13.0{% endsince %}
|
||||
|
||||
把日期转换为 XML Schema (ISO 8601) 格式,与 Jekyll 的 `date_to_xmlschema` 过滤器一样。
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ site.time | date_to_xmlschema }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
2008-11-07T13:07:54-08:00
|
||||
```
|
||||
|
||||
注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。
|
||||
|
||||
[date]: ./date.html
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: find
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
在数组中找到给定的属性为给定的值的第一个元素并返回;如果没有这样的元素则返回 `nil`。对于 `members` 数组:
|
||||
|
||||
```javascript
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack' }
|
||||
]
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ members | find: "graduation_year", 2014 | json }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
{"graduation_year":2014,"name":"John"}
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: find_exp
|
||||
---
|
||||
|
||||
{% since %}v10.11.0{% endsince %}
|
||||
|
||||
找到数组中给定的表达式值为 `true` 的第一个元素,如果没有这样的元素则返回 `nil`。对于下面的 `members` 数组:
|
||||
|
||||
```javascript
|
||||
const members = [
|
||||
{ graduation_year: 2013, name: 'Jay' },
|
||||
{ graduation_year: 2014, name: 'John' },
|
||||
{ graduation_year: 2014, name: 'Jack' }
|
||||
]
|
||||
```
|
||||
|
||||
输入
|
||||
```liquid
|
||||
{{ members | find_exp: "item", "item.graduation_year == 2014" | json }}
|
||||
```
|
||||
|
||||
输出
|
||||
```text
|
||||
{"graduation_year":2014,"name":"John"}
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user