├── .appveyor.yml
├── .bmp.yml
├── .changelog
├── CHANGELOG.tpl#mkd
└── config.yml
├── .codacy.yml
├── .codeclimate.yml
├── .codecov.yml
├── .commitlint.config.js
├── .deps-lock
├── .gitattributes
├── package-lock.json
└── yarn.lock
├── .ecrc.JS.json
├── .editorconfig
├── .eslintrc.js
├── .gitattributes
├── .github
└── workflows
│ └── CI.yml
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── .remarkrc.js
├── .rollup.config.types.js
├── .scrutinizer.yml
├── .vscode
├── cspell.dictionaries
│ ├── acronyms+names.wordlist.txt
│ ├── jargon.wordlist.txt
│ ├── people.wordlist.txt
│ └── shell.wordlist.txt
├── cspell.json
├── extensions.json
└── settings.json
├── .yarn
└── releases
│ └── yarn-1.22.19.cjs
├── .yarnrc
├── .yarnrc.yml
├── CHANGELOG.mkd
├── LICENSE
├── README.md
├── VERSION
├── cjs
└── package.json
├── dist
├── cjs
│ ├── esm-wrapper
│ │ ├── mod.esm.js
│ │ └── package.json
│ ├── lib
│ │ └── XDGAppPaths.js
│ ├── mod.cjs.d.ts
│ ├── mod.cjs.js
│ └── platform-adapters
│ │ ├── _base.js
│ │ └── node.js
├── esm
│ ├── lib
│ │ └── XDGAppPaths.js
│ ├── mod.esm.js
│ ├── package.json
│ └── platform-adapters
│ │ ├── _base.js
│ │ └── node.js
├── types
│ ├── mod.cjs.d.ts
│ └── mod.d.ts
└── xdg-app-paths.tgz
├── eg
├── show-paths.cjs.js
├── show-paths.esm.mjs
├── show-paths.local.deno.ts
├── show-paths.remote(CDN).deno.ts
├── show-paths.remote.deno.ts
└── show-paths.ts
├── package.json
├── src
├── esm-wrapper
│ ├── mod.esm.js
│ └── package.json
├── lib
│ └── XDGAppPaths.ts
├── mod.cjs.ts
├── mod.deno.ts
├── mod.esm.ts
├── mod.test.ts
└── platform-adapters
│ ├── _base.ts
│ ├── deno.deno.ts
│ └── node.ts
├── test
├── dist.test.js
├── fixtures
│ ├── cli-display-name.cjs.js
│ ├── cli-display-name.esm-wrapper.mjs
│ ├── cli-display-name.esm.mjs
│ ├── cli-display-name.ts
│ └── cli-display-name.umd.js
├── integration.test.js
├── types.test-d.ts
└── unit.test.js
├── tsconfig.json
├── tsconfig
├── tsconfig.cjs.json
├── tsconfig.eslint.json
├── tsconfig.esm.json
├── tsconfig.lab.json
├── tsconfig.types.json
└── tsconfig.umd.json
└── vendor
├── .gitattributes
└── types
└── deno.d.ts
/.appveyor.yml:
--------------------------------------------------------------------------------
1 | # spell-checker:ignore repo
2 |
3 | version: '{build} ~ {branch}'
4 |
5 | branches:
6 | except:
7 | - gh-pages
8 |
9 | environment:
10 | matrix:
11 | - nodejs_version: '14'
12 | - nodejs_version: '12'
13 | - nodejs_version: '10'
14 | # - nodejs_version: '8'
15 | # - nodejs_version: '6'
16 | # - nodejs_version: "4"
17 |
18 | # platform:
19 | # - x86
20 | # - x64
21 |
22 | # Install scripts. (runs after repo cloning)
23 | install:
24 | # Get the latest stable version of Node.js or io.js
25 | # - ps: Install-Product node $env:nodejs_version $env:platform
26 | - ps: Install-Product node $env:nodejs_version
27 | # install modules
28 | - npm install
29 |
30 | # Post-install test scripts.
31 | test_script:
32 | # Output useful info for debugging.
33 | - node --version
34 | - npm --version
35 | # run tests
36 | - npm test
37 |
38 | # After successful build.
39 | on_success:
40 | # Post code coverage information
41 | - npm run coverage
42 |
43 | # Don't actually build.
44 | build: off
45 |
--------------------------------------------------------------------------------
/.bmp.yml:
--------------------------------------------------------------------------------
1 | version: 8.3.0
2 | commit: '%.%.%'
3 | files:
4 | package.json: '"version": "%.%.%"'
5 | README.md:
6 | - 'git:github.com/rivy/js.xdg-app-paths#v%.%.%'
7 | - 'https://cdn.jsdelivr.net/gh/rivy/js.xdg-app-paths@v%.%.%'
8 | - 'https://deno.land/x/xdg_app_paths@v%.%.%'
9 | VERSION: '%.%.%'
10 |
--------------------------------------------------------------------------------
/.changelog/CHANGELOG.tpl#mkd:
--------------------------------------------------------------------------------
1 | {{- /* */ -}}
2 | {{- /* # v2022-08-20 */ -}}
3 |
4 | {{- define "format-commit" -}}
5 | * {{ if .Scope }}{{ .Type | smartLowerFirstWord }} *({{ .Scope }})*: {{ .Subject | smartLowerFirstWord }}{{ else }}{{ .Header | smartLowerFirstWord }}{{ end }} ∾ [`{{ .Hash.Short }}`]({{ commitURL .Hash.Long }})
6 | {{ end -}}
7 |
8 | {{- define "format-commit-group" }}
9 | #### {{ .Title }}
10 |
11 | {{ range .Commits }}{{ template "format-commit" . -}}{{ end -}}
12 | {{ end -}}
13 |
14 |
15 |
16 |
17 |
18 |
19 | # CHANGELOG
[{{ $.Info.Title }}]({{ $.Info.RepositoryURL }})
20 |
21 |
22 |
23 | > This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
24 | >
25 | > The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) using [conventional/semantic commits](https://nitayneeman.com/posts/understanding-semantic-commit-messages-using-git-and-angular).[`@`](https://archive.is/jnup8)
26 |
27 |
28 |
29 | {{- if .Unreleased.CommitGroups }}
30 |
31 | ---
32 |
33 | {{/* */ -}}
34 | ## [Unreleased]
35 | {{ range .Unreleased.CommitGroups }}{{ template "format-commit-group" . }}{{ end -}}
36 | {{ end }}
37 |
38 | {{- $first := true }}{{ range .Versions }}
39 |
40 | ---
41 | {{ $output := false -}}
42 | {{/* */}}
43 | ## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
44 | {{ if (index .Commits 0).Body }}
45 | {{ (index .Commits 0).Body }}
46 | {{ end }}
47 | [{{ .Tag.Name }}; details]
48 | {{ if .CommitGroups -}}
49 | {{ range .CommitGroups }}{{ if eq .Title "Features" }}{{ $output = true }}{{ template "format-commit-group" . }}{{- end -}}{{- end -}}
50 | {{ range .CommitGroups }}{{ if eq .Title "Enhancements" }}{{ $output = true }}{{ template "format-commit-group" . }}{{- end -}}{{- end -}}
51 | {{ range .CommitGroups }}{{ if eq .Title "Changes" }}{{ $output = true }}{{ template "format-commit-group" . }}{{- end -}}{{- end -}}
52 | {{ range .CommitGroups }}{{ if eq .Title "Fixes" }}{{ $output = true }}{{ template "format-commit-group" . }}{{- end -}}{{- end -}}
53 | {{ range .CommitGroups }}{{ if not (eq .Title "Features" "Enhancements" "Changes" "Fixes") }}{{ $output = true }}{{ template "format-commit-group" . }}{{- end -}}{{- end -}}
54 | {{- end -}}
55 |
56 | {{ if .RevertCommits }}{{ $output = true }}
57 | #### Reverts
58 |
59 | {{ range .RevertCommits -}}
60 | * {{ .Revert.Header }}
61 | {{ end -}}
62 | {{ end -}}
63 |
64 | {{ if .MergeCommits }}{{ $output = true }}
65 | #### Pull Requests
66 |
67 | {{ range .MergeCommits -}}
68 | * {{ .Header }}
69 | {{ end -}}
70 | {{ end -}}
71 |
72 | {{ if .NoteGroups -}}{{ $output = true }}
73 | {{ range .NoteGroups -}}
74 | #### {{ .Title }}
75 |
76 | {{ range .Notes }}
77 | {{- .Body }}
78 | {{ end -}}
79 | {{ end -}}
80 | {{ end -}}
81 |
82 | {{- if not $output }}
83 |
84 |
85 | *No changelog for this release.*
86 | {{ end }}
87 |
88 | {{- end -}}
89 |
90 |
--------------------------------------------------------------------------------
/.changelog/config.yml:
--------------------------------------------------------------------------------
1 | # `git-changelog` configuration
2 | # ref:
3 | # v2022-08-20
4 |
5 | # spell-checker: ignore bugfix maint
6 |
7 | info:
8 | title: xdg-app-paths
9 | repository_url: https://github.com/rivy/js.xdg-app-paths
10 | style: github
11 | template: CHANGELOG.tpl#mkd
12 | options:
13 | commits:
14 | filters:
15 | Type:
16 | - change
17 | - docs
18 | - feat
19 | - fix
20 | - maint
21 | - perf
22 | - refactor
23 | - test
24 | - update
25 | # - version
26 | type_maps:
27 | # basic types (enables type match case-insensitivity)
28 | change: change
29 | docs: docs
30 | feat: feat
31 | fix: fix
32 | maint: maint
33 | perf: perf
34 | refactor: refactor
35 | test: test
36 | update: update
37 | # aggregating types
38 | add: change
39 | added: change
40 | bugfix: fix
41 | build: maint
42 | changed: change
43 | chore: maint
44 | deps: update
45 | fixed: fix
46 | fixes: fix
47 | tests: test
48 | updated: update
49 | upkeep: maint
50 | commit_groups:
51 | group_by: Type
52 | sort_by: Title
53 | title_maps:
54 | change: Changes
55 | docs: Documentation
56 | feat: Features
57 | fix: Fixes
58 | maint: Maintenance
59 | perf: Enhancements
60 | refactor: Refactoring
61 | test: Test Improvements
62 | update: Dependency Updates
63 | # version: Version Changes
64 | header:
65 | pattern: "^(\\w+)([!])\\s*[~:]?\\s(.*)$|^(\\w+)\\s*\\/(\\S+)\\s*[~:]?\\s(.*)$|^(\\w+)(?:\\s*\\(([^)]+)\\))?\\s*[~:]?\\s(.*)$"
66 | pattern_maps:
67 | - Type
68 | - Scope
69 | - Subject
70 | - Type
71 | - Scope
72 | - Subject
73 | - Type
74 | - Scope
75 | - Subject
76 | tag:
77 | # pattern: "^([RrVv](-[Vv]?)?)?\\d.*$"
78 | pattern: "^(?i)([v])?\\d.*$"
79 | notes:
80 | keywords:
81 | - BREAKING CHANGE
82 |
--------------------------------------------------------------------------------
/.codacy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # CodeClimate configuration
3 | # ref:
4 | # v2002-07-18 [rivy]
5 | # note: use "Configuration file" setting in 'REPO/Code patterns/ESLint' and 'REPO/Code patterns/RemarkLint'
6 |
7 | # spell-checker:ignore (people) Roy Ivy III * rivy
8 |
9 | engines:
10 | duplication:
11 | exclude_paths:
12 | - 'eg/**'
13 | - 'tests/**'
14 | - '**.spec.js'
15 | - '**.spec.ts'
16 | - '**.test.js'
17 | - '**.test.ts'
18 | exclude_paths:
19 | - '.changelog/**'
20 | - 'CHANGELOG.mkd'
21 | - 'dist/**'
22 | - 'vendor/**'
23 |
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | # v2002-07-18 [rivy]
2 | # JavaScript/TypeScript
3 | # CodeClimate configuration; ref: https://docs.codeclimate.com/docs/advanced-configuration
4 |
5 | # spell-checker:ignore (names) EditorConfig MarkdownLint ShellCheck StyleLint (people) Roy Ivy III * rivy
6 |
7 | version: '2' # required to adjust maintainability checks
8 | checks:
9 | argument-count:
10 | config:
11 | threshold: 4
12 | complex-logic:
13 | config:
14 | threshold: 4
15 | file-lines:
16 | config:
17 | threshold: 250
18 | method-complexity:
19 | config:
20 | threshold: 20 ## default: 5
21 | method-count:
22 | config:
23 | threshold: 20
24 | method-lines:
25 | config:
26 | threshold: 40 ## default: 25
27 | nested-control-flow:
28 | config:
29 | threshold: 4
30 | return-statements:
31 | config:
32 | threshold: 4
33 | # similar-code:
34 | # config:
35 | # threshold: # has language-specific defaults; an override will affect all languages
36 | # identical-code:
37 | # config:
38 | # threshold: # has language-specific defaults; an override will affect all languages.
39 |
40 | plugins:
41 | duplication:
42 | enabled: true
43 | exclude_patterns:
44 | - 'eg/'
45 | - 'dist/'
46 | - 'vendor/'
47 | editorconfig:
48 | enabled: true
49 | # ref: https://docs.codeclimate.com/docs/eslint
50 | # * disabled; `eslint-plugin-import` fails and `eslint-plugin-functional` is not supported
51 | # eslint:
52 | # enabled: true
53 | # ref: https://docs.codeclimate.com/docs/markdownlint , https://github.com/markdownlint/markdownlint
54 | # * disabled; not configurable per-file/occurrence
55 | # markdownlint:
56 | # enabled: true
57 | shellcheck:
58 | enabled: true
59 | stylelint:
60 | enabled: true
61 |
--------------------------------------------------------------------------------
/.codecov.yml:
--------------------------------------------------------------------------------
1 | comment: false
2 |
3 | coverage:
4 | status:
5 | project:
6 | default:
7 | informational: true
8 | changes:
9 | default:
10 | informational: true
11 | patch:
12 | default:
13 | informational: true
14 |
--------------------------------------------------------------------------------
/.commitlint.config.js:
--------------------------------------------------------------------------------
1 | // CommitLint configuration
2 | // ref:
3 | // v2022-08-20 [rivy]
4 |
5 | // spell-checker:ignore (names) commitLint (people) Roy Ivy III * rivy (words) maint
6 |
7 | /* @prettier */ // note: (dprint) {.dprint.json}.prettier.associations should contain the name of this file
8 |
9 | const isNPMTestDist = !!process.env['npm_config_test_dist'];
10 | const isTestDist = !!process.env['test_dist'];
11 | const isTestRelease = !!process.env['test_release'];
12 |
13 | /** Relax linting rules/strictures (for development; *not* when submitting for distribution/release). */
14 | const relaxedReview = !(isNPMTestDist || isTestDist || isTestRelease);
15 |
16 | const commitTags = [
17 | 'Add',
18 | 'Added',
19 | 'Bugfix',
20 | 'Build',
21 | 'Change',
22 | 'Changed',
23 | 'Chore',
24 | 'Deps',
25 | 'Docs',
26 | 'Feat',
27 | 'Fix',
28 | 'Fixed',
29 | 'Fixes',
30 | 'FORK',
31 | 'Maint',
32 | 'Perf',
33 | 'Refactor',
34 | 'Style',
35 | 'Test',
36 | 'Tests',
37 | 'Update',
38 | 'Updated',
39 | 'Upkeep',
40 | // * git automated messages
41 | 'Automatic',
42 | 'Auto-merged',
43 | 'Merge',
44 | 'Merged',
45 | 'Revert',
46 | // * ok for relaxed review (ie, development), otherwise *not ok*
47 | ...(relaxedReview ? ['VERSION', 'WIP', 'X'] : []),
48 | ];
49 |
50 | module.exports = {
51 | extends: ['@commitlint/config-conventional'],
52 | parserPreset: {
53 | parserOpts: {
54 | // headerPattern ~ tested at
55 | headerPattern: /^(\s*\w[\w-]*)(?:\s*(?:[/(]([\w,/]+)[)]?))?!?\s*[~:]?\s*(.*)$/,
56 | headerCorrespondence: ['type', 'scope', 'subject'],
57 | },
58 | },
59 | plugins: [
60 | {
61 | rules: {
62 | '@local/DEBUG': (parsed, when, value) => {
63 | return [true, console.log({ parsed, when, value })];
64 | },
65 | },
66 | },
67 | ],
68 | // ref: [Commit messages starting with fixup! do not trigger any errors](https://github.com/conventional-changelog/commitlint/issues/3206)
69 | // ref: [tests for default ignores](https://github.com/conventional-changelog/commitlint/blob/914782aad70d353b/%40commitlint/is-ignored/src/defaults.ts#L20-L26)
70 | defaultIgnores: false,
71 | ignores: [
72 | (msg) => msg.match(/^\s*\d+([.]\d+)*/) /* version commit */,
73 | relaxedReview
74 | ? (msg) => msg.match(/^\s*(fixup|squash)!/) /* fixup! or squash! commit */
75 | : undefined,
76 | ].filter((v) => v != null),
77 | rules: {
78 | // '@local/DEBUG': [1, 'always'],
79 | 'body-max-line-length': [0],
80 | // ## maint [2020-01-07; rivy] ~ 'footer-leading-blank' disabled until is fixed
81 | // ## ... refs: ,
82 | 'footer-leading-blank': [0],
83 | 'header-max-length': [1, 'always', 90],
84 | 'scope-case': [2, 'always', ['camel-case', 'lower-case', 'pascal-case', 'upper-case']],
85 | 'subject-case': [0],
86 | 'subject-empty': [relaxedReview ? 1 : 2, 'never'],
87 | 'type-case': [2, 'always', ['lower-case', 'sentence-case']],
88 | 'type-enum': [2, 'always', [...commitTags.map((v) => v.toLowerCase()), ...commitTags]],
89 | },
90 | };
91 |
--------------------------------------------------------------------------------
/.deps-lock/.gitattributes:
--------------------------------------------------------------------------------
1 | # treat third-party code/tools directory as binary by default
2 | # * note: use `git diff --text ...` to override and show differences as text
3 | * binary
4 | .gitattributes !binary
5 |
--------------------------------------------------------------------------------
/.ecrc.JS.json:
--------------------------------------------------------------------------------
1 | {
2 | "#": "EditorConfig-checker Config (for JS projects)",
3 | "#ref": "",
4 | "#version": "v2023-02-05 [rivy]",
5 | "#x-spell": "/* spell-checker:ignore (people) Roy Ivy III * rivy */",
6 | "Exclude": ["([._@#$]?build|[._@#$]?coverage|dist|target|vendor|[.]yarn)/.*"],
7 | "SpacesAfterTabs": true,
8 | "Disable": { "MaxLineLength": true }
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig (is awesome!; ref: http://EditorConfig.org)
2 | # ref: [EditorConfig ~ Level-0 Coding Standard](https://themightyprogrammer.dev/article/editor-config) @@
3 | # v2022.07.30; rivy
4 |
5 | # spell-checker:ignore (people) Roy Ivy III * rivy (words) akefile makefile makefiles EOLs EOLNs MSVC NuShell POSIX VCproj
6 |
7 | # * top-most EditorConfig file
8 | root = true
9 |
10 | [*]
11 | # default ~ utf-8, unix-style newlines with a newline ending every file, 4 space indentation (and tab width)
12 | charset = utf-8
13 | end_of_line = lf
14 | indent_size = 4
15 | indent_style = space
16 | insert_final_newline = true
17 | max_line_length = 100
18 | smart_tabs = unset # ## unstable; ref:
19 | tab_width = unset # default to 'indent_size'
20 | trim_trailing_whitespace = true
21 |
22 | [{[Mm]akefile{,.*},*.{mak,mk,[Mm][Aa][Kk],[Mm][Kk]},[Gg][Nn][Uu]makefile}]
23 | # makefiles ~ TAB-style indentation
24 | indent_style = tab
25 |
26 | [*.{bash,sh}]
27 | # Linux/POSIX shell scripts
28 | indent_size = 4
29 | indent_style = space
30 |
31 | [*.{bat,cmd,[Bb][Aa][Tt],[Cc][Mm][Dd]}]
32 | # BAT/CMD ~ DOS/Win requires BAT/CMD files to have CRLF EOLNs
33 | end_of_line = crlf
34 |
35 | [*.{cjs,js,json,mjs,ts}]
36 | # js/ts ~ Prettier/XO-style == TAB indention + SPACE alignment
37 | indent_size = 2
38 | indent_style = tab
39 | smart_tabs = true # ## unstable; ref:
40 |
41 | [*.go]
42 | # go ~ TAB-style indentation (SPACE-style alignment); ref: @@
43 | indent_style = tab
44 | smart_tabs = true # ## unstable; ref:
45 |
46 | [*.jq]
47 | # `jq` script files
48 | indent_size = 2
49 | indent_style = space
50 |
51 | [*.{markdown,md,mkd,[Mm][Dd],[Mm][Kk][Dd],[Mm][Dd][Oo][Ww][Nn],[Mm][Kk][Dd][Oo][Ww][Nn],[Mm][Aa][Rr][Kk][Dd][Oo][Ww][Nn]}]
52 | # markdown
53 | indent_size = 2
54 | indent_style = space
55 |
56 | [*.{nu,[Nn][Uu]}]
57 | # `nushell` script files · [NuShell]()
58 | indent_size = 2
59 | indent_style = space
60 |
61 | [*.{sln,vc{,x}proj{,.*},[Ss][Ln][Nn],[Vv][Cc]{,[Xx]}[Pp][Rr][Oo][Jj]{,.*}}]
62 | # MSVC sln/vcproj/vcxproj files, when used, will persistently revert to CRLF EOLNs and eat final EOLs
63 | end_of_line = crlf
64 | insert_final_newline = false
65 |
66 | [*.{yaml,yml,[Yy][Aa][Mm][Ll],[Yy][Mm][Ll]}]
67 | # YAML
68 | indent_size = 2
69 | indent_style = space
70 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // ESLint configuration
2 | // ref:
3 | // v2023-02-05 [rivy]
4 |
5 | // spell-checker:ignore (names) rivy ; (options) iife
6 |
7 | /* @prettier */ // note: (dprint) {.dprint.json}.prettier.associations should contain the name of this file
8 |
9 | const useDeno = true;
10 | const usePrettier = !useDeno;
11 |
12 | module.exports = {
13 | root: true,
14 | env: { es6: true },
15 | ignorePatterns: [
16 | '[._@#$]build',
17 | '[._@#$]coverage',
18 | '.eslintrc.js',
19 | '.nyc_output',
20 | '.yarn',
21 | 'build',
22 | 'coverage',
23 | 'dist',
24 | 'node_modules',
25 | 'vendor',
26 | ],
27 | parser: '@typescript-eslint/parser',
28 | // avoid `parserOptions` ~ [2020-10-29]/rivy ~ use is causing issues for eslint evaluation of files outside of `src` (see https://github.com/typescript-eslint/typescript-eslint/issues/1723)
29 | // parserOptions: { ecmaVersion: 6, project: ['./tsconfig.json', './tsconfig.eslint.json'] },
30 | plugins: ['import', 'functional', '@typescript-eslint'],
31 | extends: [
32 | 'eslint:recommended',
33 | 'plugin:@typescript-eslint/recommended',
34 | 'plugin:eslint-comments/recommended',
35 | 'plugin:functional/lite',
36 | 'plugin:import/typescript',
37 | 'plugin:security/recommended',
38 | 'plugin:security-node/recommended',
39 | ...(usePrettier ? ['prettier', 'prettier/@typescript-eslint'] : []),
40 | ],
41 | reportUnusedDisableDirectives: true,
42 | rules: {
43 | // ref: https://eslint.org/docs/rules
44 | '@typescript-eslint/explicit-module-boundary-types': 'off',
45 | '@typescript-eslint/no-unused-vars': [
46 | 'error',
47 | {
48 | argsIgnorePattern: '^_',
49 | varsIgnorePattern: '^_',
50 | },
51 | ],
52 | 'eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
53 | 'eslint-comments/no-unused-disable': 'warn',
54 | 'import/order': ['error', { 'newlines-between': 'always', alphabetize: { order: 'asc' } }],
55 | 'no-console': ['warn'], // ref: https://eslint.org/docs/rules/no-console
56 | 'no-restricted-syntax': [
57 | 'error',
58 | {
59 | selector: `CallExpression[callee.object.name='console'][callee.property.name!=/^(log|warn|error|info|trace)$/]`,
60 | message: 'Unexpected property on console object was called',
61 | },
62 | ],
63 | 'no-undefined': ['error'], // ref: https://eslint.org/docs/rules/no-undefined
64 | 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], // ref: https://eslint.org/docs/rules/no-unused-vars
65 | 'sort-imports': ['error', { ignoreDeclarationSort: true, ignoreCase: true }],
66 | 'wrap-iife': ['error', 'inside'], // correlate with Prettier formatting choice; ref: https://eslint.org/docs/rules/wrap-iife
67 | },
68 | overrides: [{ files: ['*.js'], rules: { '@typescript-eslint/no-var-requires': 'off' } }],
69 | // globals: { BigInt: true, console: true, WebAssembly: true },
70 | // globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly' },
71 | };
72 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # v2023.02.05 [rivy]
2 | # spell-checker:ignore (people) Roy Ivy III * rivy (words) deps EOLs MSVC
3 |
4 | # default; use LF EOLs for text files
5 | * text=auto eol=lf
6 |
7 | # CRLF required; force required CRLF EOLs for WinOS BAT/CMD and MSVC SLN files
8 | *.[bB][aA][tT] text eol=crlf
9 | *.[cC][mM][dD] text eol=crlf
10 | *.[sS][lL][nN] text eol=crlf
11 |
12 | # binaries; force binary interpretation (for diff sanity and avoidance of CRLF/LF issues)
13 | # * `yarn` config files; ref: @@
14 | .yarn/**/* binary
15 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | # v2022-07-13 [rivy]
4 | # spell-checker:ignore (names) MacOS deps ; (people) Roy Ivy III * rivy
5 |
6 | on: [push]
7 |
8 | jobs:
9 | build:
10 | name: Build
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | os: [macos-latest, ubuntu-latest, windows-latest]
16 | node-version: [10.x, 12.x, 14.x, 16.x, 18.x]
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Use Node.js ${{ matrix.node-version }}
21 | uses: actions/setup-node@v1
22 | with:
23 | node-version: ${{ matrix.node-version }}
24 | - run: npm install
25 | - run: npm run show:deps
26 | - run: npm run build --if-present
27 | - run: npm test
28 | env:
29 | CI: true
30 | - run: npm run coverage "--cov-send=--flags=${{ matrix.os }}"
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # v2023-02-04 [rivy]
2 | # spell-checker:ignore (people) Roy Ivy III * rivy (words) globstar
3 |
4 | # NOTE: Git GLOBSTAR syntax [see `git help gitignore`]
5 | # * ref: [.gitignore] http://git-scm.com/docs/gitignore @@ http://archive.is/Rk6rO
6 | # * ref: [Generate a 'gitignore'](https://gitignore.io) ; eg,
7 |
8 | # ignore intermediate/undistributed build artifacts
9 | build
10 | [._@#$]build
11 | target
12 |
13 | # ignore coverage data
14 | coverage
15 | [._@#$]coverage
16 | .nyc_output
17 |
18 | # ignore JS import/package-related files
19 | node_modules
20 | package-lock.json
21 | yarn.lock
22 | # * allow packaging of lock files into '.deps-lock'
23 | !.deps-lock/package-lock.json
24 | !.deps-lock/yarn.lock
25 |
26 | # ignore `yarn`-related files (allows use of "modern" v2+ `yarn`)
27 | # * ref: @@
28 | .pnp.*
29 | .yarn/*
30 | !.yarn/patches
31 | !.yarn/plugins
32 | !.yarn/releases
33 | !.yarn/sdks
34 | !.yarn/versions
35 | # * use `.yarnrc.yml` for `yarn` config
36 | .yarnrc
37 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | # no need for package-lock for a library
2 | package-lock=false
3 | # suppress occasional annoying npm update messages
4 | update-notifier=false
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Prettier "ignore" list
2 | # v2023-02-05 [rivy]
3 | # * note: glob patterns support use of `?`, `*`, `**`, and `[...]`, but *not* `{...}`
4 |
5 | # spell-checker:ignore (people) Roy Ivy III * rivy
6 |
7 | # * build/coverage/dev artifacts
8 | [._@#$]build
9 | [._@#$]coverage
10 | .nyc_output
11 | build
12 | coverage
13 | CHANGELOG
14 | CHANGELOG.*
15 | dist
16 | target
17 |
18 | # * format-sensitive files
19 | .changelog/*.tpl
20 | .changelog/*.tpl.*
21 |
22 | # * third-party code
23 | **/node_modules
24 | **/*-lock.json
25 | .history
26 | .vscode
27 | .yarn
28 | package.json
29 | vendor
30 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // Prettier configuration
2 | // ref:
3 | // v2022-08-20 [rivy]
4 |
5 | // spell-checker:ignore (people) Roy Ivy III * rivy
6 |
7 | /* @prettier */ // note: (dprint) {.dprint.json}.prettier.associations should contain the name of this file
8 |
9 | module.exports = {
10 | // $schema: 'http://json.schemastore.org/prettierrc',
11 | printWidth: 100,
12 | proseWrap: 'preserve',
13 | singleQuote: true,
14 | tabWidth: 2,
15 | useTabs: true,
16 | // ## overrides/[*.markdown]/tabWidth": "// set this to 4 when/if https://github.com/prettier/prettier/issues/5019 is fixed",
17 | overrides: [{ files: ['*.md', '*.mkd', '*.markdown'], options: { tabWidth: 2, useTabs: false } }],
18 | };
19 |
--------------------------------------------------------------------------------
/.remarkrc.js:
--------------------------------------------------------------------------------
1 | // remark configuration (ref: )
2 | // ref:
3 | // v2022-08-20 [rivy]
4 |
5 | // spell-checker:ignore (people) Roy Ivy III * rivy (words) frontmatter retext
6 |
7 | /* @prettier */ // note: (dprint) {.dprint.json}.prettier.associations should contain the name of this file
8 |
9 | exports.plugins = [
10 | require('remark-footnotes'),
11 | // require('remark-frontmatter'),
12 | [
13 | require('remark-retext'),
14 | require('unified')().use({
15 | plugins: [
16 | require('retext-english'),
17 | require('retext-syntax-urls'),
18 | // [require('retext-spell'), require('dictionary-en')],
19 | [require('retext-sentence-spacing'), { preferred: 1 }],
20 | require('retext-repeated-words'),
21 | require('retext-passive'),
22 | ],
23 | }),
24 | ],
25 | 'remark-preset-lint-consistent',
26 | 'remark-preset-lint-recommended',
27 | 'remark-preset-lint-markdown-style-guide',
28 | ['remark-lint-emphasis-marker', 'consistent'],
29 | ['remark-lint-file-extension', false],
30 | ['remark-lint-heading-increment', false],
31 | ['remark-lint-list-item-indent', 'mixed'],
32 | ['remark-lint-list-item-spacing', false],
33 | ['remark-lint-maximum-heading-length', false],
34 | ['remark-lint-maximum-line-length', false],
35 | ['remark-lint-no-duplicate-headings', false],
36 | ['remark-lint-unordered-list-marker-style', 'consistent'],
37 | ];
38 |
--------------------------------------------------------------------------------
/.rollup.config.types.js:
--------------------------------------------------------------------------------
1 | // `rollup` configuration
2 | // ref:
3 | // v2002-07-14 [rivy]
4 | // setup: `npm i rollup @rollup/plugin-typescript` or `npm i rollup rollup-plugin-typescript2` (for visible TS error output)
5 |
6 | // spell-checker:ignore (people) Roy Ivy III * rivy
7 |
8 | import dts from 'rollup-plugin-dts';
9 |
10 | export default [
11 | // bundle TypeScript typings (TypeScript is unable/unwilling to do so...)
12 | // * ref: ,
13 | // * ref:
14 | {
15 | input: './build/types/src/mod.esm.d.ts',
16 | output: [{ file: './dist/types/mod.d.ts', format: 'esm' }],
17 | plugins: [dts()],
18 | },
19 | {
20 | input: './build/types/src/mod.cjs.d.ts',
21 | output: [{ file: './dist/types/mod.cjs.d.ts', format: 'cjs' }],
22 | plugins: [dts()],
23 | // * note: for correct interpretation of types by VSCode, './dist/types/mod.cjs.d.ts' requires a subsequent text replacement ("export { _default as default }" => "export = _default")
24 | },
25 | ];
26 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | # JavaScript/TypeScript (NodeJS-v10+)
2 | # ref: https://scrutinizer-ci.com/docs/configuration/build_reference
3 | # spell-checker:ignore () eqeqeq
4 | build:
5 | environment:
6 | node: v10.14.2
7 | nodes:
8 | analysis:
9 | tests:
10 | override:
11 | - js-scrutinizer-run
12 |
13 | checks:
14 | javascript:
15 | no_implicit_undefined_return: true
16 | no_else_return: true
17 | no_alert: true
18 | eqeqeq: true
19 | no_loop_var_assign: true
20 | no_param_assign: true
21 | no_var: true
22 |
23 | filter:
24 | dependency_paths:
25 | - 'node_modules/'
26 | excluded_paths:
27 | - 'dist/'
28 | - 'src/types/'
29 | - 'test/'
30 | - 'vendor/'
31 | - '*.spec.js'
32 | - '*.spec.ts'
33 | - '*.test.js'
34 | - '*.test.ts'
35 |
--------------------------------------------------------------------------------
/.vscode/cspell.dictionaries/acronyms+names.wordlist.txt:
--------------------------------------------------------------------------------
1 | # * abbreviations / acronyms
2 | AST # abstract syntax tree
3 | CICD # continuous integration/deployment
4 | CPU
5 | CPUs
6 | DevOps
7 | EOF
8 | EOL
9 | EOLN
10 | FIFO
11 | FIFOs
12 | FOSS # free open source software
13 | FQDN # fully qualified domain name
14 | GID # group ID
15 | GIDs
16 | GNUEABI
17 | GNUEABIhf
18 | MSVC
19 | MSRV # minimum supported rust version
20 | OSS # open source software
21 | POSIX
22 | POSIXLY
23 | RISC
24 | RISCV
25 | RNG # random number generator
26 | RNGs
27 | UID # user ID
28 | UIDs
29 | UUID # universally unique identifier
30 | WASI
31 | WASM
32 | aarch
33 | flac
34 | lzma
35 |
36 | # * names
37 | BusyBox
38 | Codacy
39 | Cygwin
40 | Deno
41 | Dprint
42 | EditorConfig
43 | FreeBSD
44 | Gmail
45 | Irix
46 | JSDelivr
47 | MS-DOS
48 | MSDOS
49 | MacOS
50 | MinGW
51 | Minix
52 | NetBSD
53 | Novell
54 | npmJS
55 | NuShell
56 | OpenBSD
57 | POSIX
58 | PowerPC
59 | SELinux
60 | SkyPack
61 | Solaris
62 | SysV
63 | Xenix
64 | Yargs
65 |
--------------------------------------------------------------------------------
/.vscode/cspell.dictionaries/jargon.wordlist.txt:
--------------------------------------------------------------------------------
1 | arity
2 | autogenerate
3 | autogenerated
4 | autogenerates
5 | bitmask
6 | bitrot
7 | canonicalization
8 | canonicalize
9 | colorizable
10 | colorize
11 | committish
12 | cyclomatic
13 | dedup
14 | demangle
15 | denoland
16 | deque
17 | dequeue
18 | discoverability
19 | duplicative
20 | enqueue
21 | executable
22 | executables
23 | falsey
24 | flamegraph
25 | gibibytes
26 | glob
27 | globbed
28 | globbing
29 | hardfloat
30 | hardlink
31 | hardlinks
32 | hashsums
33 | kibi
34 | kibibytes
35 | mebi
36 | mebibytes
37 | mergeable
38 | multibyte
39 | nonportable
40 | peekable
41 | performant
42 | polyfill
43 | ponyfill
44 | precompiled
45 | precompute
46 | preload
47 | prepend
48 | prepended
49 | primality
50 | pseudoprime
51 | pseudoprimes
52 | readonly
53 | regen
54 | reparse
55 | seedable
56 | semver
57 | shortcode
58 | shortcodes
59 | stringify
60 | stringification
61 | symlink
62 | symlinks
63 | syscall
64 | syscalls
65 | tokenize
66 | transpile
67 | transpilation
68 | truthy
69 | unbuffered
70 | unportable
71 | vendored
72 | whitespace
73 | wordlist
74 | wordlists
75 |
76 | # * abbreviations
77 | consts
78 | deps
79 | dev
80 | eval
81 | maint
82 | procs
83 |
--------------------------------------------------------------------------------
/.vscode/cspell.dictionaries/people.wordlist.txt:
--------------------------------------------------------------------------------
1 | Dimitri Benin * BendingBender
2 | Oden * ops991923
3 | Roy Ivy III * rivy
4 | Selwyn * siilwyn
5 | Simon Kjellberg * simon.kjellberg
6 | Sindre Sorhus * SindreSorhus
7 |
--------------------------------------------------------------------------------
/.vscode/cspell.dictionaries/shell.wordlist.txt:
--------------------------------------------------------------------------------
1 | # * POSIX
2 | TMPDIR
3 | csh
4 | globstar
5 | nullglob
6 | passwd
7 | pipefail
8 | popd
9 | pushd
10 | sh
11 | tcsh
12 | zsh
13 |
14 | # * Windows
15 | APPDATA
16 | COMSPEC
17 | HKCU
18 | HKLM
19 | HOMEDRIVE
20 | HOMEPATH
21 | LOCALAPPDATA
22 | PATHEXT
23 | PATHEXT
24 | SYSTEMROOT
25 | USERDOMAIN
26 | USERNAME
27 | USERPROFILE
28 |
29 | # * `git`
30 | gitattributes
31 | gitignore
32 |
33 | # * `make` (`gmake`)
34 | CURDIR
35 | GNUMAKEFLAGS
36 | GNUMakefile
37 | LIBPATTERNS
38 | MAKECMDGOALS
39 | MAKEFILES
40 | MAKEFLAGS
41 | MAKELEVEL
42 | MAKESHELL
43 | SHELLSTATUS
44 | VPATH
45 | abspath
46 | addprefix
47 | addsuffix
48 | endef
49 | firstword
50 | ifeq
51 | ifneq
52 | lastword
53 | notdir
54 | patsubst
55 |
56 | # * `npm`
57 | corepack
58 | preversion
59 |
60 | # * `prettier`
61 | prettierignore
62 |
63 | # * utilities
64 | chglog
65 | commitlint
66 | dprint
67 | gcov
68 | gmake
69 | grcov
70 | grep
71 | markdownlint
72 | mkdir
73 | rimraf
74 | rollup
75 | sed
76 | stty
77 | typedoc
78 | xargs
79 |
--------------------------------------------------------------------------------
/.vscode/cspell.json:
--------------------------------------------------------------------------------
1 | // `cspell` configuration/settings
2 | // ref:
3 | // v2022.08.09 [rivy]
4 | {
5 | "version": "0.2", // configuration/settings file version
6 | "language": "en", // language - current active spelling language
7 | "dictionaries": ["#local", "acronyms+names", "jargon", "people", "shell", "workspace"],
8 | "dictionaryDefinitions": [
9 | { "name": "#local", "path": "./cspell.dictionaries/#local-only.wordlist.txt" },
10 | { "name": "acronyms+names", "path": "./cspell.dictionaries/acronyms+names.wordlist.txt" },
11 | { "name": "jargon", "path": "./cspell.dictionaries/jargon.wordlist.txt" },
12 | { "name": "people", "path": "./cspell.dictionaries/people.wordlist.txt" },
13 | { "name": "shell", "path": "./cspell.dictionaries/shell.wordlist.txt" },
14 | { "name": "workspace", "path": "./cspell.dictionaries/workspace.wordlist.txt" }
15 | ],
16 | // ignorePaths - a list of globs to specify which files are to be ignored
17 | "ignorePaths": ["{,.,_,#,@}build/**", "{,.,_,#,@}coverage/**", "{,.,_,#,@}target/**", "tests/**/fixtures/**", "vendor/**"],
18 | // ignoreWords
19 | "ignoreWords": [],
20 | // words - list of words to be always considered correct
21 | "words": []
22 | }
23 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4 |
5 | // List of extensions which should be recommended for users of this workspace.
6 | "recommendations": [
7 | "davidanson.vscode-markdownlint",
8 | "dbaeumer.vscode-eslint",
9 | "editorconfig.editorconfig",
10 | "esbenp.prettier-vscode",
11 | "streetsidesoftware.code-spell-checker"
12 | ],
13 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
14 | "unwantedRecommendations": [
15 | "dbaeumer.jshint",
16 | "hookyqr.beautify"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "[javascript]": {
3 | // "editor.defaultFormatter": "dprint.dprint"
4 | "editor.defaultFormatter": "esbenp.prettier-vscode"
5 | },
6 | "[json]": {
7 | // "editor.defaultFormatter": "dprint.dprint"
8 | "editor.defaultFormatter": "esbenp.prettier-vscode"
9 | },
10 | "[jsonc]": {
11 | // "editor.defaultFormatter": "dprint.dprint"
12 | "editor.defaultFormatter": "esbenp.prettier-vscode"
13 | },
14 | "[typescript]": {
15 | // "editor.defaultFormatter": "dprint.dprint"
16 | "editor.defaultFormatter": "esbenp.prettier-vscode"
17 | },
18 | "deno.enable": false,
19 | "editor.formatOnSave": true,
20 | "files.exclude": {
21 | "**/.git": true,
22 | "**/.svn": true,
23 | "**/.hg": true,
24 | "**/CVS": true,
25 | "**/.DS_Store": true,
26 | "node_modules": true,
27 | ".history": true,
28 | ".nyc_output": true
29 | },
30 | "indentRainbow.ignoreLinePatterns": [
31 | "/[\t]+[ ]/g" // TAB indentaion with space alignment
32 | // "/[ \t]* [*]/g",
33 | // "/[ \t]+[/]{2}/g"
34 | ],
35 | "todo-tree.filtering.excludeGlobs": [
36 | "build",
37 | "dist",
38 | "vendor"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/.yarnrc:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | yarn-path ".yarn/releases/yarn-1.22.19.cjs"
6 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | enableGlobalCache: true
2 |
3 | logFilters:
4 | - code: YN0032
5 | level: discard
6 | - code: YN0061
7 | level: discard
8 |
9 | nodeLinker: node-modules
10 |
11 | yarnPath: .yarn/releases/yarn-1.22.19.cjs
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Roy Ivy III
4 | Copyright (c) Sindre Sorhus (sindresorhus.com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7 |
8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 |
10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | # [xdg-app-paths](https://github.com/rivy/js.xdg-app-paths)
20 |
21 | > Determine ([XDG](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)-compatible) paths for storing application files (cache, config, data, etc)
22 |
23 | [![Build status (GHA)][gha-image]][gha-url]
24 | [![Build status (AppVeyor)][appveyor-image]][appveyor-url]
25 | [![Coverage status][coverage-image]][coverage-url]
26 | [![License][license-image]][license-url]
27 | [![Style Guide][style-image]][style-url]
28 |
29 | [![Repository][repository-image]][repository-url]
30 | [![Deno version][deno-image]][deno-url]
31 | [![NPM version][npm-image]][npm-url]
32 | [![NodeJS version][nodejsv-image]][repository-url]
33 | [![npmJS Downloads][downloads-image]][downloads-url]
34 | [![JSDelivr Downloads][jsdelivr-image]][jsdelivr-url]
35 |
36 |
44 |
45 | ## Installation (CJS/ESM/TypeScript)
46 |
47 |
48 |
49 | ```shell
50 | npm install xdg-app-paths
51 | # or... `npm install "git:github.com/rivy/js.xdg-app-paths"`
52 | # or... `npm install "git:github.com/rivy/js.xdg-app-paths#v8.3.0"`
53 | # or... `npm install "https://cdn.jsdelivr.net/gh/rivy/js.xdg-app-paths@v8.3.0/dist/xdg-app-paths.tgz"`
54 | # or... `npm install "https://cdn.jsdelivr.net/gh/rivy/js.xdg-app-paths@COMMIT_SHA/dist/xdg-app-paths.tgz"`
55 | ```
56 |
57 | ## Usage
58 |
59 | #### CommonJS (CJS)
60 |
61 | ```js
62 | // MyApp.js
63 | const xdgAppPaths = require('xdg-app-paths/cjs');
64 |
65 | const cache = xdgAppPaths.cache();
66 | //(nix)=> '/home/rivy/.cache/MyApp.js'
67 | //(win)=> 'C:\\Users\\rivy\\AppData\\Local\\MyApp\\Cache'
68 |
69 | const config = xdgAppPaths.config();
70 | //(nix)=> '/home/rivy/.config/MyApp.js'
71 | //(win)=> 'C:\\Users\\rivy\\AppData\\Roaming\\MyApp\\Config'
72 |
73 | const data = xdgAppPaths.data();
74 | //(nix)=> '/home/rivy/.local/share/MyApp.js'
75 | //(win)=> 'C:\\Users\\rivy\\AppData\\Roaming\\MyApp\\Data'
76 | ```
77 |
78 | #### ECMAScript (ESM)/TypeScript
79 |
80 | ```js
81 | import xdgAppPaths from 'xdg-app-paths';
82 | const configDirs = xdgAppPaths.configDirs();
83 | //...
84 | ```
85 |
86 | #### Deno
87 |
88 |
89 |
90 | ```ts
91 | import xdgAppPaths from 'https://deno.land/x/xdg_app_paths@v8.3.0/src/mod.deno.ts';
92 | //or (via CDN, [ie, JSDelivr with GitHub version/version-range, commit, 'latest' support])...
93 | //import xdgAppPaths from 'https://cdn.jsdelivr.net/gh/rivy/js.xdg-app-paths@v8.3.0/src/mod.deno.ts';
94 | //import xdgAppPaths from 'https://cdn.jsdelivr.net/gh/rivy/js.xdg-app-paths@COMMIT_SHA/src/mod.deno.ts';
95 | const configDirs = xdgAppPaths.configDirs();
96 | //...
97 | ```
98 |
99 | ## API
100 |
101 | ### Construction/Initialization
102 |
103 | #### `XDGAppPaths( Options? )`
104 |
105 | ```js
106 | // CJS
107 | const xdgAppPaths = require('xdg-app-paths/cjs');
108 | // or ...
109 | const xdgAppPaths = require('xdg-app-paths/cjs')(options);
110 |
111 | // ESM/TypeScript
112 | import xdgAppPaths from 'xdg-app-paths';
113 | // or ...
114 | import XDGAppPaths from 'xdg-app-paths';
115 | const xdgAppPaths = XDGAppPaths(options);
116 |
117 | // Deno
118 | import xdgAppPaths from 'https://deno.land/x/xdg_app_paths/src/mod.deno.ts';
119 | // or ...
120 | import XDGAppPaths from 'https://deno.land/x/xdg_app_paths/src/mod.deno.ts';
121 | const xdgAppPaths = XDGAppPaths(options);
122 | ```
123 |
124 | When importing this module, the object returned is a function object, `XDGAppPaths`, augmented with attached methods. Additional `XDGAppPaths` objects may be constructed by direct call of the imported `XDGAppPaths` object (eg, `const x = xdgAppPaths(...)`) or by using `new` (eg, `const x = new xdgAppPaths(...)`).
125 |
126 | Upon construction, if not supplied with a specified name (via `Options.name`), `XDGAppPaths` will generate an application name which is used to further generate isolated application directories, where needed. "$eval" is used as the fallback value when automatically generating names (ie, for immediate mode scripts such as `node -e "..."`). The generated or supplied name is stored during `XDGAppPaths` construction and subsequently accessible via the `$name()` method.
127 |
128 | ### Interfaces/Types
129 |
130 | ```js
131 | import type { DirOptions, Options, XDGAppPaths } from 'xdg-app-paths'; // TypeScript
132 | //or...
133 | //import type { DirOptions, Options, XDGAppPaths } from 'https://deno.land/x/xdg_app_paths/src/mod.deno.ts'; // Deno
134 | ```
135 |
136 | #### `XDGAppPaths`
137 |
138 | _`XDGAppPaths` API; also, the interface/type of the default function object export_
139 |
140 | ---
141 |
142 | #### `DirOptions`
143 |
144 | _Configuration options supplied to `XDGAppPaths` methods_
145 |
146 |
147 |
148 | > **`DirOptions: boolean` => `{ isolated: boolean }`**
As a shortcut, when `DirOptions` is supplied as a `boolean`, it is directly interpreted as the `isolated` property (ie, `dirOptions = { isolated: dirOptions }`).
149 | >
150 | > ---
151 | >
152 | > **`DirOptions: object`**
• default = `{ isolated: true }`
153 | >
154 | > **`DirOptions.isolated: boolean`**
• default = `true`
_Isolation flag; used to override the default isolation mode, when needed_
155 |
156 |
157 |
158 | #### `Options`
159 |
160 | _Configuration options supplied when constructing `XDGAppPaths`_
161 |
162 |
163 |
164 | > **`Options: string` => `{ name: string }`**
As a shortcut, when `Options` is supplied as a `string`, is interpreted directly as the `name` property (ie, `options = { name: options }`).
165 | >
166 | > ---
167 | >
168 | > **`Options: object`**
• default = `{ name: '', suffix: '', isolated: true }`
169 | >
170 | > **`Options.name: string`**
• default = `''`
_Name of the application; used to generate isolated application paths_
When missing (`undefined`, `null`, or empty (`''`)), it is generated automatically from the process main file name, where determinable. `'$eval'` is used as a final fallback value when the application name cannot otherwise be determined. Note, Deno reports `'$deno$eval'` as the main file name when executing `deno eval ...`.
171 | >
172 | > **`Options.suffix: string`**
• default = `''`
_Suffix which is appended to the application name when generating the application paths_
173 | >
174 | > **`Options.isolated: boolean`**
• default = `true`
_Default isolation flag (used when no isolation flag is supplied for `DirOptions`)_
175 |
176 |
177 |
178 | All interfaces/types listed are exported individually by name (eg, as "XDGAppPaths").
179 |
180 | ### Methods
181 |
182 | All returned path strings are simple, platform-compatible, strings and are _not_ guaranteed to exist. The application is responsible for construction of the directories. If needed, [`make-dir`](https://www.npmjs.com/package/make-dir) or [`mkdirp`](https://www.npmjs.com/package/mkdirp) can be used to create the directories.
183 |
184 | #### `xdgAppPaths.cache( DirOptions? ): string`
185 |
186 | _Returns the directory for non-essential data files_
187 |
188 | > Deletion of the data contained here might cause an application to slow down.
189 |
190 | #### `xdgAppPaths.config( DirOptions? ): string`
191 |
192 | _Returns the directory for config files_
193 |
194 | > Deletion of the data contained here might require the user to reconfigure an application.
195 |
196 | #### `xdgAppPaths.data( DirOptions? ): string`
197 |
198 | _Returns the directory for data files_
199 |
200 | > Deletion of the data contained here might force the user to restore from backups.
201 |
202 | #### `xdgAppPaths.runtime( DirOptions? ): string?`
203 |
204 | _Returns the directory for runtime files; may return `undefined`_
205 |
206 | > Deletion of the data contained here might interfere with a currently executing application but should have no effect on future executions.
207 |
208 | #### `xdgAppPaths.state( DirOptions? ): string`
209 |
210 | _Returns the directory for state files_
211 |
212 | > Deletion of the data contained here should not materially interfere with execution of an application.
213 |
214 | #### `xdgAppPaths.configDirs( DirOptions? ): readonly string[]`
215 |
216 | _Returns a priority-sorted list of possible directories for configuration file storage (includes `paths.config()` as the first entry)_
217 |
218 | #### `xdgAppPaths.dataDirs( DirOptions? ): readonly string[]`
219 |
220 | _Returns a priority-sorted list of possible directories for data file storage (includes `paths.data()` as the first entry)_
221 |
222 | #### `xdgAppPaths.$name(): string`
223 |
224 | _Application name used for path construction (from supplied configuration or auto-generated)_
225 |
226 | #### `xdgAppPaths.$isolated(): boolean`
227 |
228 | _Default isolation mode used by the particular `XDGAppPaths` instance_
229 |
230 | ## Example
231 |
232 | ```js
233 | // MyApp.js
234 | const locatePath = require('locate-path');
235 | const mkdirp = require('mkdirp');
236 | const path = require('path');
237 |
238 | const xdgAppPaths = require('xdg-app-paths/cjs');
239 | // Extend appPaths with a "log" location function
240 | xdgAppPaths.log = function (dirOptions) {
241 | const self = xdgAppPaths; // * bind `self` to `xdgAppPaths` => avoids `this` variability due to caller context
242 | function typeOf(x) {
243 | // use avoids circumvention of eslint variable tracking for `x`
244 | return typeof x;
245 | }
246 |
247 | if (typeOf(dirOptions) === 'boolean') {
248 | dirOptions = { isolated: dirOptions };
249 | }
250 |
251 | if (
252 | typeOf(dirOptions) !== 'object' ||
253 | dirOptions === null ||
254 | typeOf(dirOptions.isolated) !== 'boolean'
255 | ) {
256 | dirOptions = { isolated: self.$isolated() };
257 | }
258 |
259 | return path.join(self.state(dirOptions), (dirOptions.isolated ? '' : self.$name() + '-') + 'log');
260 | };
261 |
262 | // log file
263 | const logPath = path.join(xdgAppPaths.log(), 'debug.txt');
264 | mkdirp.sync(path.dirname(logPath), 0o700);
265 |
266 | // config file
267 | // * search for config file within user preferred directories; otherwise, use preferred directory
268 | const possibleConfigPaths = xdgAppPaths
269 | .configDirs()
270 | .concat(xdgAppPaths.configDirs({ isolated: !xdgAppPaths.$isolated() }))
271 | .map((v) => path.join(v, xdgAppPaths.$name() + '.json'));
272 | const configPath = locatePath.sync(possibleConfigPaths) || possibleConfigPaths[0];
273 | // debug(logPath, 'configPath="%s"', configPath);
274 | mkdirp.sync(path.dirname(configPath), 0o700);
275 |
276 | // cache file
277 | const cacheDir = path.join(xdgAppPaths.cache());
278 | // debug(logPath, 'cacheDir="%s"', cacheDir);
279 | mkdirp.sync(cacheDir, 0o700);
280 | const cachePath = {};
281 | cachePath.orders = path.join(cacheDir, 'orders.json');
282 | cachePath.customers = path.join(cacheDir, 'customers.json');
283 | //...
284 | ```
285 |
286 | ## Supported Platforms
287 |
288 | ### NodeJS
289 |
290 | > #### Requirements
291 | >
292 | > NodeJS >= 4.0[^*]
293 |
294 |
295 |
296 | [^*]: With the conversion to a TypeScript-based project, due to tooling constraints, building and testing are more difficult and more limited on Node platforms earlier than NodeJS-v10. However, the generated CommonJS/UMD project code is fully tested (for NodeJS-v10+) and continues to be compatible with NodeJS-v4+.
297 |
298 | #### CommonJS modules (CJS; `*.js` and `*.cjs`)
299 |
300 | CJS is the basic supported output (with support for NodeJS versions as early as NodeJS-v4).
301 |
302 | ```js
303 | const xdgAppPaths = require('xdg-app-paths/cjs');
304 | console.log(xdgAppPaths.config());
305 | ```
306 |
307 | > Note: for CJS, `require('xdg-app-paths')` is supported for backward-compatibility and will execute correctly at run-time. However, `require('xdg-app-paths')` links to the default package type declarations which, though _correct_ for Deno/ESM/TypeScript, are _incorrect_ for CJS. This, then, leads to incorrect analysis of CJS files by static analysis tools such as TypeScript and Intellisense.
308 | >
309 | > Using `require('xdg-app-paths/cjs')` is preferred as it associates the proper CJS type declarations and provides correct information to static analysis tools.
310 |
311 | #### ECMAScript modules (ESM; `*.mjs`)
312 |
313 | - Requires `XDGAppPaths` `v6.0`+.
314 |
315 | `XDGAppPaths` fully supports ESM imports.
316 |
317 | ```js
318 | import xdgAppPaths from 'xdg-app-paths';
319 | console.log(xdgAppPaths.config());
320 | ```
321 |
322 | ### TypeScript (`*.ts`)
323 |
324 | - Requires `XDGAppPaths` `v6.0`+.
325 |
326 | As of `v6.0`+, `XDGAppPaths` has been converted to a TypeScript-based module.
327 | As a consequence, TypeScript type definitions are automatically generated, bundled, and exported by the module.
328 |
329 | ### Deno
330 |
331 | > #### Requirements
332 | >
333 | > Deno >= v1.8.0[^deno-version-req]
334 |
335 |
336 |
337 | [^deno-version-req]: The `Deno.permissions` API (stabilized in Deno v1.8.0) is required to avoid needless panics or prompts by Deno during static imports of this module/package. Note: Deno v1.3.0+ may be used if the run flag `--unstable` is also used.
338 |
339 | > #### Required Permissions
340 | >
341 | > - `--allow-env` · _allow access to the process environment variables_
342 | > This is a transitive requirement from the 'xdg'/'xdg-portable' module; `XDG` requires access to various environment variable to determine platform and user configuration (eg, XDG configuration variables, location of temp and user directories, ...).
343 | > - `--allow-read` · _allow read(-only) access to the file system_
344 | > This permission is required to use `Deno.mainModule`, which is, in turn, required to auto-generate the application name used for data isolation.
345 |
346 |
347 |
348 | - Requires `XDGAppPaths` `v7.0`+.
349 |
350 | `XDGAppPaths` also fully supports use by Deno.
351 |
352 | ```js deno
353 | import xdgAppPaths from 'https://deno.land/x/xdg_app_paths/src/mod.deno.ts';
354 | console.log(xdgAppPaths.config());
355 | ```
356 |
357 | ## Discussion
358 |
359 | The [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)[@](https://archive.is/J0mTC) defines categories of user information (ie, "cache", "config", "data", ...), defines their standard storage locations, and defines the standard process for user configuration of those locations (using `XDG_CACHE_HOME`, etc).
360 |
361 | Applications supporting the XDG convention are expected to store user-specific files within these locations, either within the common/shared directory (eg, `` `${xdg.cache()}/filename` ``) or within a more isolated application-defined subdirectory (eg, `` `${xdg.config()}/DIR/filename` ``; `DIR` usually being the application name).
362 |
363 | ### Windows ("win32") specific notes
364 |
365 | Windows has an alternate convention, offering just two standard locations for applications to persist data, either `%APPDATA%` (for files which may "roam" with the user between hosts) and `%LOCALAPPDATA%` (for local-machine-only files). All application files are expected to be stored within an application-unique subdirectory in one of those two locations, usually under a directory matching the application name. There is no further popular convention used to segregate the file types (ie, into "cache", "config", ...) in any way similar to the XDG specification.
366 |
367 | So, to support basic XDG-like behavior (that is, segregating the information types into type-specific directories), this module supports a new convention for Windows hosts (taken from [`xdg-portable`](https://www.npmjs.com/package/xdg-portable)), placing the specific types of files into subdirectories under either `%APPDATA%` or `%LOCALAPPDATA%`, as appropriate for the file type. The default directories used for the windows platform are listed by [`xdg-portable`](https://www.npmjs.com/package/xdg-portable#api).
368 |
369 | By default, this module returns paths which are isolated, application-specific sub-directories under the respective common/shared base directories. These sub-directories are purely dedicated to use by the application. If, however, the application requires access to the common/shared areas, the `isolated: false` option may be used during initialization (or as an optional override for specific function calls) to generate and return the common/shared paths. Note, that when using the command/shared directories, take care to use file names which do not collide with those used by other applications.
370 |
371 | ### Origins
372 |
373 | This module was forked from [sindresorhus/env-paths](https://github.com/sindresorhus/env-paths) in order to add cross-platform portability and support simpler cross-platform applications.
374 |
375 | ## Building and Contributing
376 |
377 | [![Repository][repository-image]][repository-url]
378 | [![Build status (GHA)][gha-image]][gha-url]
379 | [![Build status (AppVeyor)][appveyor-image]][appveyor-url]
380 | [![Coverage status][coverage-image]][coverage-url]
381 |
382 | [![Quality status (Codacy)][codacy-image]][codacy-url]
383 | [![Quality status (CodeClimate)][codeclimate-image]][codeclimate-url]
384 | [![Quality status (CodeFactor)][codefactor-image]][codefactor-url]
385 |
386 | ### Build requirements
387 |
388 | - NodeJS >= 10.14
389 | - a JavaScript package/project manager ([`npm`](https://www.npmjs.com/get-npm) or [`yarn`](https://yarnpkg.com))
390 | - [`git`](https://git-scm.com)
391 |
392 | > #### optional
393 | >
394 | > - [`bmp`](https://deno.land/x/bmp@v0.0.6) (v0.0.6+) ... synchronizes version strings within the project
395 | > - [`git-changelog`](https://github.com/rivy-go/git-changelog) (v1.1+) ... enables changelog automation
396 |
397 | ### Quick build/test
398 |
399 | ```shell
400 | npm install-test
401 | ```
402 |
403 | ### Contributions/development
404 |
405 | #### _Reproducible_ setup (for CI or local development)
406 |
407 | ```shell
408 | git clone "https://github.com/rivy/js.xdg-app-paths"
409 | cd js.xdg-app-paths
410 | # * note: for WinOS, replace `cp` with `copy` (or use [uutils](https://github.com/uutils/coreutils))
411 | # npm
412 | cp .deps-lock/package-lock.json .
413 | npm clean-install
414 | # yarn
415 | cp .deps-lock/yarn.lock .
416 | yarn --immutable --immutable-cache --check-cache
417 | ```
418 |
419 | #### Project development scripts
420 |
421 | ```shell
422 | > npm run help
423 | ...
424 | usage: `npm run TARGET` or `npx run-s TARGET [TARGET..]`
425 |
426 | TARGETs:
427 |
428 | build build/compile package
429 | clean remove build artifacts
430 | coverage calculate and display (or send) code coverage [alias: 'cov']
431 | fix fix package issues (automated/non-interactive)
432 | fix:lint fix ESLint issues
433 | fix:style fix Prettier formatting issues
434 | help display help
435 | lint check for package code 'lint'
436 | lint:audit check for `npm audit` violations in project code
437 | lint:commits check for commit flaws (using `commitlint` and `cspell`)
438 | lint:editorconfig check for EditorConfig format flaws (using `editorconfig-checker`)
439 | lint:lint check for code 'lint' (using `eslint`)
440 | lint:markdown check for markdown errors (using `remark`)
441 | lint:spell check for spelling errors (using `cspell`)
442 | lint:style check for format imperfections (using `prettier`)
443 | prerelease clean, rebuild, and fully test (useful prior to publish/release)
444 | realclean remove all generated files
445 | rebuild clean and (re-)build project
446 | refresh clean and rebuild/regenerate all project artifacts
447 | refresh:dist clean, rebuild, and regenerate project distribution
448 | retest clean and (re-)test project
449 | reset:hard remove *all* generated files and reinstall dependencies
450 | show:deps show package dependencies
451 | test test package
452 | test:code test package code (use `--test-code=...` to pass options to testing harness)
453 | test:types test for type declaration errors (using `tsd`)
454 | update update/prepare for distribution [alias: 'dist']
455 | update:changelog update CHANGELOG (using `git changelog ...`)
456 | update:dist update distribution content
457 | verify fully (and verbosely) test package
458 | ```
459 |
460 | #### Packaging & Publishing
461 |
462 | ##### Package
463 |
464 | ```shell
465 | #=== * POSIX
466 | # update project VERSION strings (package.json,...)
467 | # * `bmp --[major|minor|patch]`; next VERSION in M.m.r (semver) format
468 | bmp --minor
469 | VERSION=$(cat VERSION)
470 | git-changelog --next-tag "v${VERSION}" > CHANGELOG.mkd
471 | # create/commit updates and distribution
472 | git add package.json CHANGELOG.mkd README.md VERSION .bmp.yml
473 | git commit -m "${VERSION}"
474 | npm run clean && npm run update:dist && git add dist && git commit --amend --no-edit
475 | # (optional) update/save dependency locks
476 | # * note: `yarn import` of 'package-lock.json' (when available) is faster but may not work for later versions of 'package-lock.json'
477 | rm -f package-lock.json yarn.lock
478 | npm install --package-lock
479 | yarn install
480 | mkdir .deps-lock 2> /dev/null
481 | cp package-lock.json .deps-lock/
482 | cp yarn.lock .deps-lock/
483 | git add .deps-lock
484 | git commit --amend --no-edit
485 | # tag VERSION commit
486 | git tag -f "v${VERSION}"
487 | # (optional) prerelease checkup
488 | npm run prerelease
489 | #=== * WinOS
490 | @rem # update project VERSION strings (package.json,...)
491 | @rem # * `bmp --[major|minor|patch]`; next VERSION in M.m.r (semver) format
492 | bmp --minor
493 | for /f %G in (VERSION) do @set "VERSION=%G"
494 | git-changelog --next-tag "v%VERSION%" > CHANGELOG.mkd
495 | @rem # create/commit updates and distribution
496 | git add package.json CHANGELOG.mkd README.md VERSION .bmp.yml
497 | git commit -m "%VERSION%"
498 | npm run clean && npm run update:dist && git add dist && git commit --amend --no-edit
499 | @rem # (optional) update/save dependency locks
500 | @rem # * note: `yarn import` of 'package-lock.json' (when available) is faster but may not work for later versions of 'package-lock.json'
501 | del package-lock.json yarn.lock 2>NUL
502 | npm install --package-lock
503 | yarn install
504 | mkdir .deps-lock 2>NUL
505 | copy /y package-lock.json .deps-lock >NUL
506 | copy /y yarn.lock .deps-lock >NUL
507 | git add .deps-lock
508 | git commit --amend --no-edit
509 | @rem # tag VERSION commit
510 | git tag -f "v%VERSION%"
511 | @rem # (optional) prerelease checkup
512 | npm run prerelease
513 | ```
514 |
515 | ##### Publish
516 |
517 | ```shell
518 | # publish
519 | # * optional (will be done in 'prePublishOnly' by `npm publish`)
520 | npm run clean && npm run test && npm run dist && git-changelog > CHANGELOG.mkd #expect exit code == 0
521 | git diff-index --quiet HEAD || echo "[lint] ERROR uncommitted changes" # expect no output and exit code == 0
522 | # *
523 | npm publish # `npm publish --dry-run` will perform all prepublication actions and stop just before the actual publish push
524 | # * if published to NPMjs with no ERRORs; push to deno.land with tag push
525 | git push origin --tags
526 | ```
527 |
528 | ### Contributions
529 |
530 | Contributions are welcome.
531 |
532 | Any pull requests should be based off of the default branch (`master`). And, whenever possible, please include tests for any new code, ensuring that local (via `npm test`) and remote CI testing passes.
533 |
534 | By contributing to the project, you are agreeing to provide your contributions under the same [license](./LICENSE) as the project itself.
535 |
536 | ## Related
537 |
538 | - [`xdg-portable`](https://www.npmjs.com/package/xdg-portable) ... XDG Base Directory paths (cross-platform)
539 | - [`env-paths`](https://www.npmjs.com/package/env-paths) ... inspiration for this module
540 |
541 | ## License
542 |
543 | [MIT](./LICENSE) © [Roy Ivy III](https://github.com/rivy)
544 |
545 |
546 |
547 |
548 |
549 |
550 | [repository-image]: https://img.shields.io/github/v/tag/rivy/js.xdg-app-paths?sort=semver&label=%E2%81%A3&logo=github&logoColor=white
551 | [repository-url]: https://github.com/rivy/js.xdg-app-paths
552 | [license-image]: https://img.shields.io/npm/l/xdg-app-paths.svg?color=tomato&style=flat
553 | [license-url]: license
554 | [nodejsv-image]: https://img.shields.io/node/v/xdg-app-paths?color=slateblue
555 | [style-image]: https://img.shields.io/badge/code_style-prettier-mediumvioletred.svg
556 | [style-url]: https://prettier.io
557 |
558 |
559 |
560 | [appveyor-image]: https://img.shields.io/appveyor/ci/rivy/js-xdg-app-paths/master.svg?style=flat&logo=AppVeyor&logoColor=deepskyblue
561 | [appveyor-url]: https://ci.appveyor.com/project/rivy/js-xdg-app-paths
562 | [gha-image]: https://img.shields.io/github/actions/workflow/status/rivy/js.xdg-app-paths/CI.yml?branch=master&label=CI&logo=github
563 | [gha-url]: https://github.com/rivy/js.xdg-app-paths/actions?query=workflow%3ACI
564 |
565 |
566 |
567 | [coverage-image]: https://img.shields.io/codecov/c/github/rivy/js.xdg-app-paths/master.svg
568 | [coverage-url]: https://codecov.io/gh/rivy/js.xdg-app-paths
569 | [codeclimate-url]: https://codeclimate.com/github/rivy/js.xdg-app-paths
570 | [codeclimate-image]: https://img.shields.io/codeclimate/maintainability/rivy/js.xdg-app-paths?label=codeclimate
571 | [codacy-image]: https://img.shields.io/codacy/grade/6f019c41b12b4c35a5ac5693744e4b96?label=codacy
572 | [codacy-url]: https://app.codacy.com/gh/rivy/js.xdg-app-paths/dashboard
573 | [codefactor-image]: https://img.shields.io/codefactor/grade/github/rivy/js.xdg-app-paths?label=codefactor
574 | [codefactor-url]: https://www.codefactor.io/repository/github/rivy/js.xdg-app-paths
575 |
576 |
577 |
578 | [deno-image]: https://img.shields.io/github/v/tag/rivy/js.xdg-app-paths?label=deno
579 | [deno-url]: https://deno.land/x/xdg_app_paths
580 | [downloads-image]: http://img.shields.io/npm/dm/xdg-app-paths.svg?style=flat
581 | [downloads-url]: https://npmjs.org/package/xdg-app-paths
582 | [jsdelivr-image]: https://img.shields.io/jsdelivr/gh/hm/rivy/js.xdg-app-paths?style=flat
583 | [jsdelivr-url]: https://www.jsdelivr.com/package/gh/rivy/js.xdg-app-paths
584 | [npm-image]: https://img.shields.io/npm/v/xdg-app-paths.svg?style=flat
585 | [npm-url]: https://npmjs.org/package/xdg-app-paths
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 8.3.0
2 |
--------------------------------------------------------------------------------
/cjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "commonjs",
3 | "main": "../dist/cjs/mod.cjs.js",
4 | "types": "../dist/cjs/mod.cjs.d.ts"
5 | }
6 |
--------------------------------------------------------------------------------
/dist/cjs/esm-wrapper/mod.esm.js:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import _ from '../mod.cjs.js';
4 | export * from '../mod.cjs.js';
5 | export default _;
6 |
--------------------------------------------------------------------------------
/dist/cjs/esm-wrapper/package.json:
--------------------------------------------------------------------------------
1 | {"type": "module"}
2 |
--------------------------------------------------------------------------------
/dist/cjs/lib/XDGAppPaths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | exports.__esModule = true;
3 | exports.Adapt = void 0;
4 | function isBoolean(t) {
5 | return typeOf(t) === 'boolean';
6 | }
7 | function isObject(t) {
8 | return typeOf(t) === 'object';
9 | }
10 | function isString(t) {
11 | return typeOf(t) === 'string';
12 | }
13 | function typeOf(t) {
14 | return typeof t;
15 | }
16 | function Adapt(adapter_) {
17 | var meta = adapter_.meta, path = adapter_.path, xdg = adapter_.xdg;
18 | var XDGAppPaths_ = (function () {
19 | function XDGAppPaths_(options_) {
20 | if (options_ === void 0) { options_ = {}; }
21 | var _a, _b, _c;
22 | function XDGAppPaths(options) {
23 | if (options === void 0) { options = {}; }
24 | return new XDGAppPaths_(options);
25 | }
26 | var options = (isObject(options_) ? options_ : { name: options_ });
27 | var suffix = (_a = options.suffix) !== null && _a !== void 0 ? _a : '';
28 | var isolated_ = (_b = options.isolated) !== null && _b !== void 0 ? _b : true;
29 | var namePriorityList = [
30 | options.name,
31 | meta.pkgMainFilename(),
32 | meta.mainFilename(),
33 | ];
34 | var nameFallback = '$eval';
35 | var name = path.parse(((_c = namePriorityList.find(function (e) { return isString(e); })) !== null && _c !== void 0 ? _c : nameFallback) + suffix).name;
36 | XDGAppPaths.$name = function $name() {
37 | return name;
38 | };
39 | XDGAppPaths.$isolated = function $isolated() {
40 | return isolated_;
41 | };
42 | function isIsolated(dirOptions) {
43 | var _a;
44 | dirOptions = dirOptions !== null && dirOptions !== void 0 ? dirOptions : { isolated: isolated_ };
45 | var isolated = isBoolean(dirOptions) ? dirOptions : (_a = dirOptions.isolated) !== null && _a !== void 0 ? _a : isolated_;
46 | return isolated;
47 | }
48 | function finalPathSegment(dirOptions) {
49 | return isIsolated(dirOptions) ? name : '';
50 | }
51 | XDGAppPaths.cache = function cache(dirOptions) {
52 | return path.join(xdg.cache(), finalPathSegment(dirOptions));
53 | };
54 | XDGAppPaths.config = function config(dirOptions) {
55 | return path.join(xdg.config(), finalPathSegment(dirOptions));
56 | };
57 | XDGAppPaths.data = function data(dirOptions) {
58 | return path.join(xdg.data(), finalPathSegment(dirOptions));
59 | };
60 | XDGAppPaths.runtime = function runtime(dirOptions) {
61 | return xdg.runtime()
62 | ? path.join(xdg.runtime(), finalPathSegment(dirOptions))
63 | : void 0;
64 | };
65 | XDGAppPaths.state = function state(dirOptions) {
66 | return path.join(xdg.state(), finalPathSegment(dirOptions));
67 | };
68 | XDGAppPaths.configDirs = function configDirs(dirOptions) {
69 | return xdg
70 | .configDirs()
71 | .map(function (s) { return path.join(s, finalPathSegment(dirOptions)); });
72 | };
73 | XDGAppPaths.dataDirs = function dataDirs(dirOptions) {
74 | return xdg
75 | .dataDirs()
76 | .map(function (s) { return path.join(s, finalPathSegment(dirOptions)); });
77 | };
78 | return XDGAppPaths;
79 | }
80 | return XDGAppPaths_;
81 | }());
82 | return { XDGAppPaths: new XDGAppPaths_() };
83 | }
84 | exports.Adapt = Adapt;
85 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWERHQXBwUGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL1hER0FwcFBhdGhzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLFlBQVksQ0FBQzs7O0FBbUZiLFNBQVMsU0FBUyxDQUFJLENBQWM7SUFDbkMsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDO0FBQ2hDLENBQUM7QUFFRCxTQUFTLFFBQVEsQ0FBSSxDQUE4QjtJQUNsRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLENBQUM7QUFDL0IsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFJLENBQUk7SUFDeEIsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDO0FBQy9CLENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBSSxDQUFJO0lBQ3RCLE9BQU8sT0FBTyxDQUFDLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMsS0FBSyxDQUFDLFFBQTBCO0lBQ2hDLElBQUEsSUFBSSxHQUFnQixRQUFRLEtBQXhCLEVBQUUsSUFBSSxHQUFVLFFBQVEsS0FBbEIsRUFBRSxHQUFHLEdBQUssUUFBUSxJQUFiLENBQWM7SUFFckM7UUFDQyxzQkFBWSxRQUErQjtZQUEvQix5QkFBQSxFQUFBLGFBQStCOztZQUMxQyxTQUFTLFdBQVcsQ0FBQyxPQUE4QjtnQkFBOUIsd0JBQUEsRUFBQSxZQUE4QjtnQkFDbEQsT0FBTyxJQUFJLFlBQVksQ0FBQyxPQUFPLENBQWdCLENBQUM7WUFDakQsQ0FBQztZQUVELElBQU0sT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFZLENBQUM7WUFFaEYsSUFBTSxNQUFNLEdBQUcsTUFBQSxPQUFPLENBQUMsTUFBTSxtQ0FBSSxFQUFFLENBQUM7WUFDcEMsSUFBTSxTQUFTLEdBQUcsTUFBQSxPQUFPLENBQUMsUUFBUSxtQ0FBSSxJQUFJLENBQUM7WUFHM0MsSUFBTSxnQkFBZ0IsR0FBNkM7Z0JBQ2xFLE9BQU8sQ0FBQyxJQUFJO2dCQUNaLElBQUksQ0FBQyxlQUFlLEVBQUU7Z0JBQ3RCLElBQUksQ0FBQyxZQUFZLEVBQUU7YUFDbkIsQ0FBQztZQUNGLElBQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQztZQUM3QixJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUN0QixDQUFDLE1BQUEsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFYLENBQVcsQ0FBQyxtQ0FBSSxZQUFZLENBQUMsR0FBRyxNQUFNLENBQ3BFLENBQUMsSUFBSSxDQUFDO1lBRVAsV0FBVyxDQUFDLEtBQUssR0FBRyxTQUFTLEtBQUs7Z0JBQ2pDLE9BQU8sSUFBSSxDQUFDO1lBQ2IsQ0FBQyxDQUFDO1lBQ0YsV0FBVyxDQUFDLFNBQVMsR0FBRyxTQUFTLFNBQVM7Z0JBQ3pDLE9BQU8sU0FBUyxDQUFDO1lBQ2xCLENBQUMsQ0FBQztZQUVGLFNBQVMsVUFBVSxDQUFDLFVBQWlDOztnQkFDcEQsVUFBVSxHQUFHLFVBQVUsYUFBVixVQUFVLGNBQVYsVUFBVSxHQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxDQUFDO2dCQUNuRCxJQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBQSxVQUFVLENBQUMsUUFBUSxtQ0FBSSxTQUFTLENBQUM7Z0JBQ3ZGLE9BQU8sUUFBUSxDQUFDO1lBQ2pCLENBQUM7WUFFRCxTQUFTLGdCQUFnQixDQUFDLFVBQWlDO2dCQUMxRCxPQUFPLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDM0MsQ0FBQztZQUVELFdBQVcsQ0FBQyxLQUFLLEdBQUcsU0FBUyxLQUFLLENBQUMsVUFBaUM7Z0JBQ25FLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM3RCxDQUFDLENBQUM7WUFFRixXQUFXLENBQUMsTUFBTSxHQUFHLFNBQVMsTUFBTSxDQUFDLFVBQWlDO2dCQUNyRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFFLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDO1lBRUYsV0FBVyxDQUFDLElBQUksR0FBRyxTQUFTLElBQUksQ0FBQyxVQUFpQztnQkFDakUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzVELENBQUMsQ0FBQztZQUVGLFdBQVcsQ0FBQyxPQUFPLEdBQUcsU0FBUyxPQUFPLENBQUMsVUFBaUM7Z0JBQ3ZFLE9BQU8sR0FBRyxDQUFDLE9BQU8sRUFBRTtvQkFDbkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBWSxFQUFFLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUNsRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDWCxDQUFDLENBQUM7WUFFRixXQUFXLENBQUMsS0FBSyxHQUFHLFNBQVMsS0FBSyxDQUFDLFVBQWlDO2dCQUNuRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDN0QsQ0FBQyxDQUFDO1lBRUYsV0FBVyxDQUFDLFVBQVUsR0FBRyxTQUFTLFVBQVUsQ0FBQyxVQUFpQztnQkFDN0UsT0FBTyxHQUFHO3FCQUNSLFVBQVUsRUFBRTtxQkFDWixHQUFHLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUExQyxDQUEwQyxDQUFzQixDQUFDO1lBQy9FLENBQUMsQ0FBQztZQUVGLFdBQVcsQ0FBQyxRQUFRLEdBQUcsU0FBUyxRQUFRLENBQUMsVUFBaUM7Z0JBQ3pFLE9BQU8sR0FBRztxQkFDUixRQUFRLEVBQUU7cUJBQ1YsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBMUMsQ0FBMEMsQ0FBc0IsQ0FBQztZQUMvRSxDQUFDLENBQUM7WUFFRixPQUFPLFdBQTBCLENBQUM7UUFDbkMsQ0FBQztRQUNGLG1CQUFDO0lBQUQsQ0FBQyxBQTNFRCxJQTJFQztJQUVELE9BQU8sRUFBRSxXQUFXLEVBQUUsSUFBSSxZQUFZLEVBQWlCLEVBQUUsQ0FBQztBQUMzRCxDQUFDO0FBR1Esc0JBQUsifQ==
--------------------------------------------------------------------------------
/dist/cjs/mod.cjs.d.ts:
--------------------------------------------------------------------------------
1 | /** Configuration options supplied to `XDGAppPaths` methods */
2 | interface DirOptions {
3 | /** Isolation flag; used to override the default isolation mode, when needed. */
4 | readonly isolated?: boolean | null;
5 | }
6 | /** Configuration options supplied when constructing `XDGAppPaths` */
7 | interface Options {
8 | /** Name of the application; used to generate isolated application paths.
9 | > When missing (`undefined`), `null`, or empty (`''`), it is generated automatically from the process main file name, where determinable.
10 | > "$eval" is used as a final fallback value when the application name cannot otherwise be determined.
11 | */
12 | readonly name?: string | null;
13 | /** Suffix which is appended to the application name when generating the application paths. */
14 | readonly suffix?: string | null;
15 | /** Default isolation flag (used when no isolation flag is supplied for `DirOptions`). */
16 | readonly isolated?: boolean | null;
17 | }
18 | /** `XDGAppPaths` (API) - Determine (XDG-compatible) paths for storing application files (cache, config, data, etc) */
19 | interface XDGAppPaths {
20 | /** Create an `XDGAppPaths` object (a preceding `new` is optional). */
21 | (options?: Options | string): XDGAppPaths;
22 | /** Create an `XDGAppPaths` object (`new` is optional). */
23 | new (options?: Options | string): XDGAppPaths;
24 | /** Returns the directory for non-essential data files.
25 | > Deletion of the data contained here might cause an application to slow down.
26 | */
27 | cache(dirOptions?: DirOptions | boolean): string;
28 | /** Returns the directory for config files.
29 | > Deletion of the data contained here might require the user to reconfigure an application.
30 | */
31 | config(dirOptions?: DirOptions | boolean): string;
32 | /** Returns the directory for data files.
33 | > Deletion of the data contained here might force the user to restore from backups.
34 | */
35 | data(dirOptions?: DirOptions | boolean): string;
36 | /** Returns the directory for runtime files; may return `undefined`.
37 | > Deletion of the data contained here might interfere with a currently executing application but should have no effect on future executions.
38 | */
39 | runtime(dirOptions?: DirOptions | boolean): string | undefined;
40 | /** Returns the directory for state files.
41 | > Deletion of the data contained here should not materially interfere with execution of an application.
42 | */
43 | state(dirOptions?: DirOptions | boolean): string;
44 | /** Returns a priority-sorted list of possible directories for configuration file storage (includes `paths.config()` as the first entry). */
45 | configDirs(dirOptions?: DirOptions | boolean): readonly string[];
46 | /** Returns a priority-sorted list of possible directories for data file storage (includes `paths.data()` as the first entry). */
47 | dataDirs(dirOptions?: DirOptions | boolean): readonly string[];
48 | /** Application name used for path construction (from supplied configuration or auto-generated). */
49 | $name(): string;
50 | /** Default isolation mode used by the particular `XDGAppPaths` instance. */
51 | $isolated(): boolean;
52 | }
53 |
54 | declare const _default: XDGAppPaths;
55 |
56 | export = _default;
57 |
--------------------------------------------------------------------------------
/dist/cjs/mod.cjs.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var XDGAppPaths_js_1 = require("./lib/XDGAppPaths.js");
3 | var node_js_1 = require("./platform-adapters/node.js");
4 | module.exports = XDGAppPaths_js_1.Adapt(node_js_1.adapter).XDGAppPaths;
5 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kLmNqcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2QuY2pzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSx1REFBNkM7QUFFN0MsdURBQXNEO0FBRXRELGlCQUFTLHNCQUFLLENBQUMsaUJBQU8sQ0FBQyxDQUFDLFdBQTBCLENBQUMifQ==
--------------------------------------------------------------------------------
/dist/cjs/platform-adapters/_base.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | exports.__esModule = true;
3 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Jhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcGxhdGZvcm0tYWRhcHRlcnMvX2Jhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
--------------------------------------------------------------------------------
/dist/cjs/platform-adapters/node.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 | if (k2 === undefined) k2 = k;
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5 | }) : (function(o, m, k, k2) {
6 | if (k2 === undefined) k2 = k;
7 | o[k2] = m[k];
8 | }));
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
11 | }) : function(o, v) {
12 | o["default"] = v;
13 | });
14 | var __importStar = (this && this.__importStar) || function (mod) {
15 | if (mod && mod.__esModule) return mod;
16 | var result = {};
17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18 | __setModuleDefault(result, mod);
19 | return result;
20 | };
21 | var __importDefault = (this && this.__importDefault) || function (mod) {
22 | return (mod && mod.__esModule) ? mod : { "default": mod };
23 | };
24 | exports.__esModule = true;
25 | exports.adapter = void 0;
26 | var path = __importStar(require("path"));
27 | var xdg_portable_1 = __importDefault(require("xdg-portable"));
28 | exports.adapter = {
29 | atImportPermissions: { env: true, read: true },
30 | meta: {
31 | mainFilename: function () {
32 | var requireMain = typeof require !== 'undefined' && require !== null && require.main
33 | ? require.main
34 | : { filename: void 0 };
35 | var requireMainFilename = requireMain.filename;
36 | var filename = (requireMainFilename !== process.execArgv[0] ? requireMainFilename : void 0) ||
37 | (typeof process._eval === 'undefined' ? process.argv[1] : void 0);
38 | return filename;
39 | },
40 | pkgMainFilename: function () {
41 | return process.pkg ? process.execPath : void 0;
42 | }
43 | },
44 | path: path,
45 | process: process,
46 | xdg: xdg_portable_1["default"]
47 | };
48 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wbGF0Zm9ybS1hZGFwdGVycy9ub2RlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQSx5Q0FBNkI7QUFFN0IsOERBQStCO0FBSWxCLFFBQUEsT0FBTyxHQUFxQjtJQUN4QyxtQkFBbUIsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRTtJQUM5QyxJQUFJLEVBQUU7UUFDTCxZQUFZLEVBQUU7WUFDYixJQUFNLFdBQVcsR0FDaEIsT0FBTyxPQUFPLEtBQUssV0FBVyxJQUFJLE9BQU8sS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLElBQUk7Z0JBQ2pFLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSTtnQkFDZCxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixJQUFNLG1CQUFtQixHQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUM7WUFDakQsSUFBTSxRQUFRLEdBRWIsQ0FBQyxtQkFBbUIsS0FBSyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRzVFLENBQUMsT0FBUSxPQUFlLENBQUMsS0FBSyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUM1RSxPQUFPLFFBQVEsQ0FBQztRQUNqQixDQUFDO1FBQ0QsZUFBZSxFQUFFO1lBRWhCLE9BQVEsT0FBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekQsQ0FBQztLQUNEO0lBQ0QsSUFBSSxNQUFBO0lBQ0osT0FBTyxTQUFBO0lBQ1AsR0FBRywyQkFBQTtDQUNILENBQUMifQ==
--------------------------------------------------------------------------------
/dist/esm/lib/XDGAppPaths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | function isBoolean(t) {
3 | return typeOf(t) === 'boolean';
4 | }
5 | function isObject(t) {
6 | return typeOf(t) === 'object';
7 | }
8 | function isString(t) {
9 | return typeOf(t) === 'string';
10 | }
11 | function typeOf(t) {
12 | return typeof t;
13 | }
14 | function Adapt(adapter_) {
15 | var meta = adapter_.meta, path = adapter_.path, xdg = adapter_.xdg;
16 | var XDGAppPaths_ = (function () {
17 | function XDGAppPaths_(options_) {
18 | if (options_ === void 0) { options_ = {}; }
19 | var _a, _b, _c;
20 | function XDGAppPaths(options) {
21 | if (options === void 0) { options = {}; }
22 | return new XDGAppPaths_(options);
23 | }
24 | var options = (isObject(options_) ? options_ : { name: options_ });
25 | var suffix = (_a = options.suffix) !== null && _a !== void 0 ? _a : '';
26 | var isolated_ = (_b = options.isolated) !== null && _b !== void 0 ? _b : true;
27 | var namePriorityList = [
28 | options.name,
29 | meta.pkgMainFilename(),
30 | meta.mainFilename(),
31 | ];
32 | var nameFallback = '$eval';
33 | var name = path.parse(((_c = namePriorityList.find(function (e) { return isString(e); })) !== null && _c !== void 0 ? _c : nameFallback) + suffix).name;
34 | XDGAppPaths.$name = function $name() {
35 | return name;
36 | };
37 | XDGAppPaths.$isolated = function $isolated() {
38 | return isolated_;
39 | };
40 | function isIsolated(dirOptions) {
41 | var _a;
42 | dirOptions = dirOptions !== null && dirOptions !== void 0 ? dirOptions : { isolated: isolated_ };
43 | var isolated = isBoolean(dirOptions) ? dirOptions : (_a = dirOptions.isolated) !== null && _a !== void 0 ? _a : isolated_;
44 | return isolated;
45 | }
46 | function finalPathSegment(dirOptions) {
47 | return isIsolated(dirOptions) ? name : '';
48 | }
49 | XDGAppPaths.cache = function cache(dirOptions) {
50 | return path.join(xdg.cache(), finalPathSegment(dirOptions));
51 | };
52 | XDGAppPaths.config = function config(dirOptions) {
53 | return path.join(xdg.config(), finalPathSegment(dirOptions));
54 | };
55 | XDGAppPaths.data = function data(dirOptions) {
56 | return path.join(xdg.data(), finalPathSegment(dirOptions));
57 | };
58 | XDGAppPaths.runtime = function runtime(dirOptions) {
59 | return xdg.runtime()
60 | ? path.join(xdg.runtime(), finalPathSegment(dirOptions))
61 | : void 0;
62 | };
63 | XDGAppPaths.state = function state(dirOptions) {
64 | return path.join(xdg.state(), finalPathSegment(dirOptions));
65 | };
66 | XDGAppPaths.configDirs = function configDirs(dirOptions) {
67 | return xdg
68 | .configDirs()
69 | .map(function (s) { return path.join(s, finalPathSegment(dirOptions)); });
70 | };
71 | XDGAppPaths.dataDirs = function dataDirs(dirOptions) {
72 | return xdg
73 | .dataDirs()
74 | .map(function (s) { return path.join(s, finalPathSegment(dirOptions)); });
75 | };
76 | return XDGAppPaths;
77 | }
78 | return XDGAppPaths_;
79 | }());
80 | return { XDGAppPaths: new XDGAppPaths_() };
81 | }
82 | export { Adapt };
83 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWERHQXBwUGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL1hER0FwcFBhdGhzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLFlBQVksQ0FBQztBQW1GYixTQUFTLFNBQVMsQ0FBSSxDQUFjO0lBQ25DLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQztBQUNoQyxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUksQ0FBOEI7SUFDbEQsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDO0FBQy9CLENBQUM7QUFFRCxTQUFTLFFBQVEsQ0FBSSxDQUFJO0lBQ3hCLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLFFBQVEsQ0FBQztBQUMvQixDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUksQ0FBSTtJQUN0QixPQUFPLE9BQU8sQ0FBQyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBQyxRQUEwQjtJQUNoQyxJQUFBLElBQUksR0FBZ0IsUUFBUSxLQUF4QixFQUFFLElBQUksR0FBVSxRQUFRLEtBQWxCLEVBQUUsR0FBRyxHQUFLLFFBQVEsSUFBYixDQUFjO0lBRXJDO1FBQ0Msc0JBQVksUUFBK0I7WUFBL0IseUJBQUEsRUFBQSxhQUErQjs7WUFDMUMsU0FBUyxXQUFXLENBQUMsT0FBOEI7Z0JBQTlCLHdCQUFBLEVBQUEsWUFBOEI7Z0JBQ2xELE9BQU8sSUFBSSxZQUFZLENBQUMsT0FBTyxDQUFnQixDQUFDO1lBQ2pELENBQUM7WUFFRCxJQUFNLE9BQU8sR0FBRyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBWSxDQUFDO1lBRWhGLElBQU0sTUFBTSxHQUFHLE1BQUEsT0FBTyxDQUFDLE1BQU0sbUNBQUksRUFBRSxDQUFDO1lBQ3BDLElBQU0sU0FBUyxHQUFHLE1BQUEsT0FBTyxDQUFDLFFBQVEsbUNBQUksSUFBSSxDQUFDO1lBRzNDLElBQU0sZ0JBQWdCLEdBQTZDO2dCQUNsRSxPQUFPLENBQUMsSUFBSTtnQkFDWixJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUN0QixJQUFJLENBQUMsWUFBWSxFQUFFO2FBQ25CLENBQUM7WUFDRixJQUFNLFlBQVksR0FBRyxPQUFPLENBQUM7WUFDN0IsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDdEIsQ0FBQyxNQUFBLGdCQUFnQixDQUFDLElBQUksQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBWCxDQUFXLENBQUMsbUNBQUksWUFBWSxDQUFDLEdBQUcsTUFBTSxDQUNwRSxDQUFDLElBQUksQ0FBQztZQUVQLFdBQVcsQ0FBQyxLQUFLLEdBQUcsU0FBUyxLQUFLO2dCQUNqQyxPQUFPLElBQUksQ0FBQztZQUNiLENBQUMsQ0FBQztZQUNGLFdBQVcsQ0FBQyxTQUFTLEdBQUcsU0FBUyxTQUFTO2dCQUN6QyxPQUFPLFNBQVMsQ0FBQztZQUNsQixDQUFDLENBQUM7WUFFRixTQUFTLFVBQVUsQ0FBQyxVQUFpQzs7Z0JBQ3BELFVBQVUsR0FBRyxVQUFVLGFBQVYsVUFBVSxjQUFWLFVBQVUsR0FBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsQ0FBQztnQkFDbkQsSUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQUEsVUFBVSxDQUFDLFFBQVEsbUNBQUksU0FBUyxDQUFDO2dCQUN2RixPQUFPLFFBQVEsQ0FBQztZQUNqQixDQUFDO1lBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxVQUFpQztnQkFDMUQsT0FBTyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzNDLENBQUM7WUFFRCxXQUFXLENBQUMsS0FBSyxHQUFHLFNBQVMsS0FBSyxDQUFDLFVBQWlDO2dCQUNuRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDN0QsQ0FBQyxDQUFDO1lBRUYsV0FBVyxDQUFDLE1BQU0sR0FBRyxTQUFTLE1BQU0sQ0FBQyxVQUFpQztnQkFDckUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQztZQUVGLFdBQVcsQ0FBQyxJQUFJLEdBQUcsU0FBUyxJQUFJLENBQUMsVUFBaUM7Z0JBQ2pFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM1RCxDQUFDLENBQUM7WUFFRixXQUFXLENBQUMsT0FBTyxHQUFHLFNBQVMsT0FBTyxDQUFDLFVBQWlDO2dCQUN2RSxPQUFPLEdBQUcsQ0FBQyxPQUFPLEVBQUU7b0JBQ25CLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQVksRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDbEUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ1gsQ0FBQyxDQUFDO1lBRUYsV0FBVyxDQUFDLEtBQUssR0FBRyxTQUFTLEtBQUssQ0FBQyxVQUFpQztnQkFDbkUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzdELENBQUMsQ0FBQztZQUVGLFdBQVcsQ0FBQyxVQUFVLEdBQUcsU0FBUyxVQUFVLENBQUMsVUFBaUM7Z0JBQzdFLE9BQU8sR0FBRztxQkFDUixVQUFVLEVBQUU7cUJBQ1osR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBMUMsQ0FBMEMsQ0FBc0IsQ0FBQztZQUMvRSxDQUFDLENBQUM7WUFFRixXQUFXLENBQUMsUUFBUSxHQUFHLFNBQVMsUUFBUSxDQUFDLFVBQWlDO2dCQUN6RSxPQUFPLEdBQUc7cUJBQ1IsUUFBUSxFQUFFO3FCQUNWLEdBQUcsQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQTFDLENBQTBDLENBQXNCLENBQUM7WUFDL0UsQ0FBQyxDQUFDO1lBRUYsT0FBTyxXQUEwQixDQUFDO1FBQ25DLENBQUM7UUFDRixtQkFBQztJQUFELENBQUMsQUEzRUQsSUEyRUM7SUFFRCxPQUFPLEVBQUUsV0FBVyxFQUFFLElBQUksWUFBWSxFQUFpQixFQUFFLENBQUM7QUFDM0QsQ0FBQztBQUdELE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyJ9
--------------------------------------------------------------------------------
/dist/esm/mod.esm.js:
--------------------------------------------------------------------------------
1 | import { Adapt } from './lib/XDGAppPaths.js';
2 | import { adapter } from './platform-adapters/node.js';
3 | var _ = Adapt(adapter).XDGAppPaths;
4 | export default _;
5 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kLmVzbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2QuZXNtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFdEQsSUFBTSxDQUFDLEdBQWdCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUEwQixDQUFDO0FBR2pFLGVBQWUsQ0FBQyxDQUFDIn0=
--------------------------------------------------------------------------------
/dist/esm/package.json:
--------------------------------------------------------------------------------
1 | {"type": "module"}
2 |
--------------------------------------------------------------------------------
/dist/esm/platform-adapters/_base.js:
--------------------------------------------------------------------------------
1 | export {};
2 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Jhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvcGxhdGZvcm0tYWRhcHRlcnMvX2Jhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
--------------------------------------------------------------------------------
/dist/esm/platform-adapters/node.js:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import xdg from 'xdg-portable';
3 | export var adapter = {
4 | atImportPermissions: { env: true, read: true },
5 | meta: {
6 | mainFilename: function () {
7 | var requireMain = typeof require !== 'undefined' && require !== null && require.main
8 | ? require.main
9 | : { filename: void 0 };
10 | var requireMainFilename = requireMain.filename;
11 | var filename = (requireMainFilename !== process.execArgv[0] ? requireMainFilename : void 0) ||
12 | (typeof process._eval === 'undefined' ? process.argv[1] : void 0);
13 | return filename;
14 | },
15 | pkgMainFilename: function () {
16 | return process.pkg ? process.execPath : void 0;
17 | }
18 | },
19 | path: path,
20 | process: process,
21 | xdg: xdg
22 | };
23 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wbGF0Zm9ybS1hZGFwdGVycy9ub2RlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRTdCLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUkvQixNQUFNLENBQUMsSUFBTSxPQUFPLEdBQXFCO0lBQ3hDLG1CQUFtQixFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO0lBQzlDLElBQUksRUFBRTtRQUNMLFlBQVksRUFBRTtZQUNiLElBQU0sV0FBVyxHQUNoQixPQUFPLE9BQU8sS0FBSyxXQUFXLElBQUksT0FBTyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSTtnQkFDakUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJO2dCQUNkLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pCLElBQU0sbUJBQW1CLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQztZQUNqRCxJQUFNLFFBQVEsR0FFYixDQUFDLG1CQUFtQixLQUFLLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFHNUUsQ0FBQyxPQUFRLE9BQWUsQ0FBQyxLQUFLLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sUUFBUSxDQUFDO1FBQ2pCLENBQUM7UUFDRCxlQUFlLEVBQUU7WUFFaEIsT0FBUSxPQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6RCxDQUFDO0tBQ0Q7SUFDRCxJQUFJLE1BQUE7SUFDSixPQUFPLFNBQUE7SUFDUCxHQUFHLEtBQUE7Q0FDSCxDQUFDIn0=
--------------------------------------------------------------------------------
/dist/types/mod.cjs.d.ts:
--------------------------------------------------------------------------------
1 | /** Configuration options supplied to `XDGAppPaths` methods */
2 | interface DirOptions {
3 | /** Isolation flag; used to override the default isolation mode, when needed. */
4 | readonly isolated?: boolean | null;
5 | }
6 | /** Configuration options supplied when constructing `XDGAppPaths` */
7 | interface Options {
8 | /** Name of the application; used to generate isolated application paths.
9 | > When missing (`undefined`), `null`, or empty (`''`), it is generated automatically from the process main file name, where determinable.
10 | > "$eval" is used as a final fallback value when the application name cannot otherwise be determined.
11 | */
12 | readonly name?: string | null;
13 | /** Suffix which is appended to the application name when generating the application paths. */
14 | readonly suffix?: string | null;
15 | /** Default isolation flag (used when no isolation flag is supplied for `DirOptions`). */
16 | readonly isolated?: boolean | null;
17 | }
18 | /** `XDGAppPaths` (API) - Determine (XDG-compatible) paths for storing application files (cache, config, data, etc) */
19 | interface XDGAppPaths {
20 | /** Create an `XDGAppPaths` object (a preceding `new` is optional). */
21 | (options?: Options | string): XDGAppPaths;
22 | /** Create an `XDGAppPaths` object (`new` is optional). */
23 | new (options?: Options | string): XDGAppPaths;
24 | /** Returns the directory for non-essential data files.
25 | > Deletion of the data contained here might cause an application to slow down.
26 | */
27 | cache(dirOptions?: DirOptions | boolean): string;
28 | /** Returns the directory for config files.
29 | > Deletion of the data contained here might require the user to reconfigure an application.
30 | */
31 | config(dirOptions?: DirOptions | boolean): string;
32 | /** Returns the directory for data files.
33 | > Deletion of the data contained here might force the user to restore from backups.
34 | */
35 | data(dirOptions?: DirOptions | boolean): string;
36 | /** Returns the directory for runtime files; may return `undefined`.
37 | > Deletion of the data contained here might interfere with a currently executing application but should have no effect on future executions.
38 | */
39 | runtime(dirOptions?: DirOptions | boolean): string | undefined;
40 | /** Returns the directory for state files.
41 | > Deletion of the data contained here should not materially interfere with execution of an application.
42 | */
43 | state(dirOptions?: DirOptions | boolean): string;
44 | /** Returns a priority-sorted list of possible directories for configuration file storage (includes `paths.config()` as the first entry). */
45 | configDirs(dirOptions?: DirOptions | boolean): readonly string[];
46 | /** Returns a priority-sorted list of possible directories for data file storage (includes `paths.data()` as the first entry). */
47 | dataDirs(dirOptions?: DirOptions | boolean): readonly string[];
48 | /** Application name used for path construction (from supplied configuration or auto-generated). */
49 | $name(): string;
50 | /** Default isolation mode used by the particular `XDGAppPaths` instance. */
51 | $isolated(): boolean;
52 | }
53 |
54 | declare const _default: XDGAppPaths;
55 |
56 | export = _default;
57 |
--------------------------------------------------------------------------------
/dist/types/mod.d.ts:
--------------------------------------------------------------------------------
1 | /** Configuration options supplied to `XDGAppPaths` methods */
2 | interface DirOptions {
3 | /** Isolation flag; used to override the default isolation mode, when needed. */
4 | readonly isolated?: boolean | null;
5 | }
6 | /** Configuration options supplied when constructing `XDGAppPaths` */
7 | interface Options {
8 | /** Name of the application; used to generate isolated application paths.
9 | > When missing (`undefined`), `null`, or empty (`''`), it is generated automatically from the process main file name, where determinable.
10 | > "$eval" is used as a final fallback value when the application name cannot otherwise be determined.
11 | */
12 | readonly name?: string | null;
13 | /** Suffix which is appended to the application name when generating the application paths. */
14 | readonly suffix?: string | null;
15 | /** Default isolation flag (used when no isolation flag is supplied for `DirOptions`). */
16 | readonly isolated?: boolean | null;
17 | }
18 | /** `XDGAppPaths` (API) - Determine (XDG-compatible) paths for storing application files (cache, config, data, etc) */
19 | interface XDGAppPaths {
20 | /** Create an `XDGAppPaths` object (a preceding `new` is optional). */
21 | (options?: Options | string): XDGAppPaths;
22 | /** Create an `XDGAppPaths` object (`new` is optional). */
23 | new (options?: Options | string): XDGAppPaths;
24 | /** Returns the directory for non-essential data files.
25 | > Deletion of the data contained here might cause an application to slow down.
26 | */
27 | cache(dirOptions?: DirOptions | boolean): string;
28 | /** Returns the directory for config files.
29 | > Deletion of the data contained here might require the user to reconfigure an application.
30 | */
31 | config(dirOptions?: DirOptions | boolean): string;
32 | /** Returns the directory for data files.
33 | > Deletion of the data contained here might force the user to restore from backups.
34 | */
35 | data(dirOptions?: DirOptions | boolean): string;
36 | /** Returns the directory for runtime files; may return `undefined`.
37 | > Deletion of the data contained here might interfere with a currently executing application but should have no effect on future executions.
38 | */
39 | runtime(dirOptions?: DirOptions | boolean): string | undefined;
40 | /** Returns the directory for state files.
41 | > Deletion of the data contained here should not materially interfere with execution of an application.
42 | */
43 | state(dirOptions?: DirOptions | boolean): string;
44 | /** Returns a priority-sorted list of possible directories for configuration file storage (includes `paths.config()` as the first entry). */
45 | configDirs(dirOptions?: DirOptions | boolean): readonly string[];
46 | /** Returns a priority-sorted list of possible directories for data file storage (includes `paths.data()` as the first entry). */
47 | dataDirs(dirOptions?: DirOptions | boolean): readonly string[];
48 | /** Application name used for path construction (from supplied configuration or auto-generated). */
49 | $name(): string;
50 | /** Default isolation mode used by the particular `XDGAppPaths` instance. */
51 | $isolated(): boolean;
52 | }
53 |
54 | declare const _: XDGAppPaths;
55 |
56 | export { DirOptions, Options, XDGAppPaths, _ as default };
57 |
--------------------------------------------------------------------------------
/dist/xdg-app-paths.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rivy/js.xdg-app-paths/625c9f1ca0693c2c047dfb503affa486ea325b87/dist/xdg-app-paths.tgz
--------------------------------------------------------------------------------
/eg/show-paths.cjs.js:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 | // # spell-checker:ignore APPNAME
3 | /* eslint-env es6, node */
4 | 'use strict';
5 |
6 | const path = require('path');
7 |
8 | /* eslint-disable no-console , security-node/detect-crlf , security-node/detect-non-literal-require-calls , security/detect-object-injection */
9 |
10 | const xdgAppPathsModulePath = '../dist/cjs/mod.cjs.js';
11 |
12 | const xdgAppPaths = require(xdgAppPathsModulePath);
13 |
14 | // Extend appPaths with a "log" location function
15 | // eslint-disable-next-line functional/immutable-data
16 | xdgAppPaths.log = function (dirOptions) {
17 | const self = xdgAppPaths; // * bind `self` to `appPaths` => avoids `this` variability due to caller context
18 | function typeOf(x) {
19 | // * use avoids circumvention of eslint variable tracking for `x`
20 | return typeof x;
21 | }
22 |
23 | if (typeOf(dirOptions) === 'boolean') {
24 | dirOptions = { isolated: dirOptions };
25 | }
26 |
27 | if (
28 | typeOf(dirOptions) !== 'object' ||
29 | dirOptions === null ||
30 | typeOf(dirOptions.isolated) !== 'boolean'
31 | ) {
32 | dirOptions = { isolated: self.$isolated() };
33 | }
34 |
35 | return path.join(self.state(dirOptions), (dirOptions.isolated ? '' : self.$name() + '-') + 'log');
36 | };
37 |
38 | function showObjectEntries(obj) {
39 | var strings = [];
40 | Object.keys(obj).forEach((key) => {
41 | const value = obj[key];
42 | const val = typeof value === 'function' ? value() : value;
43 | strings.push(key + ' = ' + val);
44 | });
45 | return strings.join('\n');
46 | }
47 |
48 | console.log({ appPaths: xdgAppPaths });
49 | console.log(showObjectEntries(xdgAppPaths));
50 |
51 | console.log('appPaths.log():', xdgAppPaths.log());
52 | console.log('appPaths.log(false):', xdgAppPaths.log(false));
53 | console.log('appPaths.log(true):', xdgAppPaths.log(true));
54 |
55 | // eslint-disable-next-line functional/immutable-data
56 | delete process.env.XDG_CONFIG_HOME;
57 | // eslint-disable-next-line functional/no-let
58 | let p = require(xdgAppPathsModulePath)('dross');
59 |
60 | console.log({ p });
61 | console.log(showObjectEntries(p));
62 |
63 | p = require(xdgAppPathsModulePath)({ suffix: '-nodejs' });
64 |
65 | console.log({ p });
66 | console.log(showObjectEntries(p));
67 |
68 | p = require(xdgAppPathsModulePath)({ name: 'extraordinaire', suffix: '-nodejs' });
69 |
70 | console.log({ p });
71 | console.log(showObjectEntries(p));
72 |
73 | p = require(xdgAppPathsModulePath)({ name: 'fluffy', isolated: false });
74 |
75 | console.log({ p });
76 | console.log(showObjectEntries(p));
77 |
78 | /* eslint-enable no-console , security-node/detect-crlf , security-node/detect-non-literal-require-calls , security/detect-object-injection */
79 |
--------------------------------------------------------------------------------
/eg/show-paths.esm.mjs:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 | // # spell-checker:ignore APPNAME
3 | /* eslint-env es6, node */
4 | 'use strict';
5 |
6 | import path from 'path';
7 | import { inspect } from 'util';
8 |
9 | /* eslint-disable functional/immutable-data , no-console , security-node/detect-crlf , security/detect-object-injection */
10 |
11 | import xdgAppPaths from '../dist/cjs/esm-wrapper/mod.esm.js';
12 |
13 | function objectEntries(obj) {
14 | const map = {};
15 | Object.keys(obj).forEach((key) => {
16 | const value = obj[key];
17 | const val = typeof value === 'function' ? value() : value;
18 | map[key] = val;
19 | });
20 | return map;
21 | }
22 |
23 | // Extend appPaths with a "log" location function
24 | xdgAppPaths.log = function (dirOptions = null) {
25 | const self = xdgAppPaths; // * bind `self` to `appPaths` => avoids `this` variability due to caller context
26 | function typeOf(x) {
27 | // * use avoids circumvention of eslint variable tracking for `x`
28 | return typeof x;
29 | }
30 |
31 | if (typeOf(dirOptions) === 'boolean') {
32 | dirOptions = { isolated: dirOptions };
33 | }
34 |
35 | if (
36 | typeOf(dirOptions) !== 'object' ||
37 | dirOptions === null ||
38 | typeOf(dirOptions.isolated) !== 'boolean'
39 | ) {
40 | dirOptions = { isolated: self.$isolated() };
41 | }
42 |
43 | return path.join(self.state(dirOptions), (dirOptions.isolated ? '' : self.$name() + '-') + 'log');
44 | };
45 |
46 | function showObjectEntries(obj) {
47 | var strings = [];
48 | Object.keys(obj).forEach((key) => {
49 | const value = obj[key];
50 | const val = typeof value === 'function' ? value() : value;
51 | strings.push(key + ' = ' + val);
52 | });
53 | return strings.join('\n');
54 | }
55 |
56 | console.log({ appPaths: xdgAppPaths });
57 | console.log(showObjectEntries(xdgAppPaths));
58 |
59 | console.log('appPaths.log():', xdgAppPaths.log());
60 | console.log('appPaths.log(false):', xdgAppPaths.log(false));
61 | console.log('appPaths.log(true):', xdgAppPaths.log(true));
62 |
63 | delete process.env.XDG_CONFIG_HOME;
64 | // eslint-disable-next-line functional/no-let
65 | let p = xdgAppPaths('dross');
66 |
67 | console.log('p:', inspect(p));
68 | console.log(objectEntries(p));
69 |
70 | p = xdgAppPaths({ suffix: '-nodejs' });
71 |
72 | console.log('p:', inspect(p));
73 | console.log(objectEntries(p));
74 |
75 | p = xdgAppPaths({ name: 'extraordinaire', suffix: '-nodejs' });
76 |
77 | console.log('p:', inspect(p));
78 | console.log(objectEntries(p));
79 |
80 | p = xdgAppPaths({ name: 'fluffy', isolated: false });
81 |
82 | console.log('p:', inspect(p));
83 | console.log(objectEntries(p));
84 |
85 | /* eslint-enable functional/immutable-data , no-console , security-node/detect-crlf , security/detect-object-injection */
86 |
--------------------------------------------------------------------------------
/eg/show-paths.local.deno.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | // spell-checker:ignore (names) Deno
4 |
5 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
6 | // @ts-ignore // deno-type URL import
7 | import * as path from 'https://deno.land/std@0.150.0/path/mod.ts';
8 |
9 | ///
10 |
11 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12 | // @ts-ignore // Deno alias to suppress other false-positive TS warnings
13 | const deno = Deno;
14 |
15 | const inspect = deno.inspect;
16 |
17 | /* eslint-disable @typescript-eslint/no-explicit-any , functional/immutable-data , no-console , security-node/detect-crlf , security/detect-object-injection */
18 |
19 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
20 | // @ts-ignore // deno-type import
21 | import xdgAppPaths from '../src/mod.deno.ts';
22 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
23 | // @ts-ignore // deno-type import
24 | import type { DirOptions, XDGAppPaths } from '../src/mod.deno.ts';
25 |
26 | function objectEntries(obj: any) {
27 | const map: any = {};
28 | Object.keys(obj).forEach((key) => {
29 | const value = obj[key];
30 | const val = typeof value === 'function' ? value() : value;
31 | map[key] = val;
32 | });
33 | return map;
34 | }
35 |
36 | // eslint-disable-next-line functional/prefer-readonly-type
37 | type XDGAppPathsWithLog = XDGAppPaths & { log: (dirOptions?: DirOptions | boolean) => string };
38 |
39 | // Extend appPaths with a "log" location
40 | (xdgAppPaths as XDGAppPathsWithLog).log = function log(dirOptions?: DirOptions | boolean) {
41 | const self = xdgAppPaths;
42 | dirOptions = dirOptions ?? { isolated: self.$isolated() };
43 | const isolated = typeof dirOptions === 'boolean' ? dirOptions : dirOptions.isolated || true;
44 | return path.join(self.state(isolated), (isolated ? '' : self.$name() + '-') + 'log');
45 | };
46 |
47 | console.log('appPaths:', inspect(xdgAppPaths));
48 | console.log('appPaths.state(false):', xdgAppPaths.state(false));
49 | console.log('appPaths.state(true):', xdgAppPaths.state(true));
50 | console.log(objectEntries(xdgAppPaths));
51 | console.log('appPaths.log(false):', (xdgAppPaths as XDGAppPathsWithLog).log(false));
52 | console.log('appPaths.log(true):', (xdgAppPaths as XDGAppPathsWithLog).log(true));
53 |
54 | const queryEnv = await Deno?.permissions?.query({ name: 'env' });
55 | if (queryEnv?.state !== 'granted') {
56 | console.warn('ERROR: environment permissions are required (re-run with `--allow-env`)');
57 | Deno.exit(1);
58 | }
59 |
60 | deno.env.delete('XDG_CONFIG_HOME');
61 | // eslint-disable-next-line functional/no-let
62 | let p = xdgAppPaths('dross');
63 |
64 | console.log('p:', inspect(p));
65 | console.log(objectEntries(p));
66 |
67 | p = xdgAppPaths({ suffix: '-nodejs' });
68 |
69 | console.log('p:', inspect(p));
70 | console.log(objectEntries(p));
71 |
72 | p = xdgAppPaths({ name: 'extraordinaire', suffix: '-nodejs' });
73 |
74 | console.log('p:', inspect(p));
75 | console.log(objectEntries(p));
76 |
77 | p = xdgAppPaths({ name: 'fluffy', isolated: false });
78 |
79 | console.log('p:', inspect(p));
80 | console.log(objectEntries(p));
81 |
82 | /* eslint-enable @typescript-eslint/no-explicit-any , functional/immutable-data , no-console , security-node/detect-crlf , security/detect-object-injection */
83 |
--------------------------------------------------------------------------------
/eg/show-paths.remote(CDN).deno.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | // * `deno` permission requirements
4 | // --allow-env (transitive from 'xdg-app-paths')
5 | // --allow-read
6 |
7 | /* eslint-disable @typescript-eslint/ban-ts-comment , @typescript-eslint/no-explicit-any , functional/immutable-data , import/order , no-console , security-node/detect-crlf , security/detect-object-injection */
8 |
9 | // @ts-ignore // deno-type URL import
10 | import * as path from 'https://deno.land/std@0.150.0/path/mod.ts';
11 |
12 | ///
13 |
14 | // @ts-ignore // Deno alias to suppress other false-positive TS warnings
15 | const deno = Deno;
16 |
17 | const inspect = deno.inspect;
18 |
19 | // @ts-ignore // deno-type URL import
20 | import xdgAppPaths from 'https://cdn.jsdelivr.net/gh/rivy/js.xdg-app-paths@v8.1.0/src/mod.deno.ts';
21 | // @ts-ignore // deno-type import
22 | import type { DirOptions, XDGAppPaths } from '../src/mod.deno.ts';
23 |
24 | function objectEntries(obj: any) {
25 | const map: any = {};
26 | Object.keys(obj).forEach((key) => {
27 | const value = obj[key];
28 | const val = typeof value === 'function' ? value() : value;
29 | map[key] = val;
30 | });
31 | return map;
32 | }
33 |
34 | // eslint-disable-next-line functional/prefer-readonly-type
35 | type XDGAppPathsWithLog = XDGAppPaths & { log: (dirOptions?: DirOptions | boolean) => string };
36 |
37 | // Extend appPaths with a "log" location
38 | (xdgAppPaths as XDGAppPathsWithLog).log = function log(dirOptions?: DirOptions | boolean) {
39 | const self = xdgAppPaths;
40 | dirOptions = dirOptions ?? { isolated: self.$isolated() };
41 | const isolated = typeof dirOptions === 'boolean' ? dirOptions : dirOptions.isolated || true;
42 | return path.join(self.state(isolated), (isolated ? '' : self.$name() + '-') + 'log');
43 | };
44 |
45 | console.log('appPaths:', inspect(xdgAppPaths));
46 | console.log('appPaths.state(false):', xdgAppPaths.state(false));
47 | console.log('appPaths.state(true):', xdgAppPaths.state(true));
48 | console.log(objectEntries(xdgAppPaths));
49 | console.log('appPaths.log(false):', (xdgAppPaths as XDGAppPathsWithLog).log(false));
50 | console.log('appPaths.log(true):', (xdgAppPaths as XDGAppPathsWithLog).log(true));
51 |
52 | const queryEnv = await Deno?.permissions?.query({ name: 'env' });
53 | if (queryEnv?.state !== 'granted') {
54 | console.warn('ERROR: environment permissions are required (re-run with `--allow-env`)');
55 | Deno.exit(1);
56 | }
57 |
58 | deno.env.delete('XDG_CONFIG_HOME');
59 | // eslint-disable-next-line functional/no-let
60 | let p = xdgAppPaths('dross');
61 |
62 | console.log('p:', inspect(p));
63 | console.log(objectEntries(p));
64 |
65 | p = xdgAppPaths({ suffix: '-nodejs' });
66 |
67 | console.log('p:', inspect(p));
68 | console.log(objectEntries(p));
69 |
70 | p = xdgAppPaths({ name: 'extraordinaire', suffix: '-nodejs' });
71 |
72 | console.log('p:', inspect(p));
73 | console.log(objectEntries(p));
74 |
75 | p = xdgAppPaths({ name: 'fluffy', isolated: false });
76 |
77 | console.log('p:', inspect(p));
78 | console.log(objectEntries(p));
79 |
80 | /* eslint-enable @typescript-eslint/ban-ts-comment , @typescript-eslint/no-explicit-any , functional/immutable-data , import/order , no-console , security-node/detect-crlf , security/detect-object-injection */
81 |
--------------------------------------------------------------------------------
/eg/show-paths.remote.deno.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | // * `deno` permission requirements
4 | // --allow-env (transitive from 'xdg-app-paths')
5 | // --allow-read
6 |
7 | /* eslint-disable @typescript-eslint/ban-ts-comment , @typescript-eslint/no-explicit-any , functional/immutable-data , import/order , no-console , security-node/detect-crlf , security/detect-object-injection */
8 |
9 | // @ts-ignore // deno-type URL import
10 | import * as path from 'https://deno.land/std@0.150.0/path/mod.ts';
11 |
12 | ///
13 |
14 | // @ts-ignore // Deno alias to suppress other false-positive TS warnings
15 | const deno = Deno;
16 |
17 | const inspect = deno.inspect;
18 |
19 | // @ts-ignore // deno-type URL import
20 | import xdgAppPaths from 'https://deno.land/x/xdg_app_paths@v8.1.0/src/mod.deno.ts';
21 | // @ts-ignore // deno-type import
22 | import type { DirOptions, XDGAppPaths } from '../src/mod.deno.ts';
23 |
24 | function objectEntries(obj: any) {
25 | const map: any = {};
26 | Object.keys(obj).forEach((key) => {
27 | const value = obj[key];
28 | const val = typeof value === 'function' ? value() : value;
29 | map[key] = val;
30 | });
31 | return map;
32 | }
33 |
34 | // eslint-disable-next-line functional/prefer-readonly-type
35 | type XDGAppPathsWithLog = XDGAppPaths & { log: (dirOptions?: DirOptions | boolean) => string };
36 |
37 | // Extend appPaths with a "log" location
38 | (xdgAppPaths as XDGAppPathsWithLog).log = function log(dirOptions?: DirOptions | boolean) {
39 | const self = xdgAppPaths;
40 | dirOptions = dirOptions ?? { isolated: self.$isolated() };
41 | const isolated = typeof dirOptions === 'boolean' ? dirOptions : dirOptions.isolated || true;
42 | return path.join(self.state(isolated), (isolated ? '' : self.$name() + '-') + 'log');
43 | };
44 |
45 | console.log('appPaths:', inspect(xdgAppPaths));
46 | console.log('appPaths.state(false):', xdgAppPaths.state(false));
47 | console.log('appPaths.state(true):', xdgAppPaths.state(true));
48 | console.log(objectEntries(xdgAppPaths));
49 | console.log('appPaths.log(false):', (xdgAppPaths as XDGAppPathsWithLog).log(false));
50 | console.log('appPaths.log(true):', (xdgAppPaths as XDGAppPathsWithLog).log(true));
51 |
52 | const queryEnv = await Deno?.permissions?.query({ name: 'env' });
53 | if (queryEnv?.state !== 'granted') {
54 | console.warn('ERROR: environment permissions are required (re-run with `--allow-env`)');
55 | Deno.exit(1);
56 | }
57 |
58 | deno.env.delete('XDG_CONFIG_HOME');
59 | // eslint-disable-next-line functional/no-let
60 | let p = xdgAppPaths('dross');
61 |
62 | console.log('p:', inspect(p));
63 | console.log(objectEntries(p));
64 |
65 | p = xdgAppPaths({ suffix: '-nodejs' });
66 |
67 | console.log('p:', inspect(p));
68 | console.log(objectEntries(p));
69 |
70 | p = xdgAppPaths({ name: 'extraordinaire', suffix: '-nodejs' });
71 |
72 | console.log('p:', inspect(p));
73 | console.log(objectEntries(p));
74 |
75 | p = xdgAppPaths({ name: 'fluffy', isolated: false });
76 |
77 | console.log('p:', inspect(p));
78 | console.log(objectEntries(p));
79 |
80 | /* eslint-enable @typescript-eslint/ban-ts-comment , @typescript-eslint/no-explicit-any , functional/immutable-data , import/order , no-console , security-node/detect-crlf , security/detect-object-injection */
81 |
--------------------------------------------------------------------------------
/eg/show-paths.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import path from 'path';
4 | import { inspect } from 'util';
5 |
6 | /* eslint-disable @typescript-eslint/no-explicit-any , functional/immutable-data , no-console , security-node/detect-crlf , security/detect-object-injection */
7 |
8 | import xdgAppPaths from '../dist/cjs/mod.cjs';
9 | import type { DirOptions, XDGAppPaths } from '../src/mod.esm';
10 |
11 | function objectEntries(obj: any) {
12 | const map: any = {};
13 | Object.keys(obj).forEach((key) => {
14 | const value = obj[key];
15 | const val = typeof value === 'function' ? value() : value;
16 | map[key] = val;
17 | });
18 | return map;
19 | }
20 |
21 | // eslint-disable-next-line functional/prefer-readonly-type
22 | type XDGAppPathsWithLog = XDGAppPaths & { log: (dirOptions?: DirOptions | boolean) => string };
23 |
24 | // Extend appPaths with a "log" location
25 | (xdgAppPaths as XDGAppPathsWithLog).log = function log(dirOptions?: DirOptions | boolean) {
26 | const self = xdgAppPaths;
27 | dirOptions = dirOptions ?? { isolated: self.$isolated() };
28 | const isolated = typeof dirOptions === 'boolean' ? dirOptions : dirOptions.isolated || true;
29 | return path.join(self.state(isolated), (isolated ? '' : self.$name() + '-') + 'log');
30 | };
31 |
32 | console.log('appPaths:', inspect(xdgAppPaths));
33 | console.log('appPaths.state(false):', xdgAppPaths.state(false));
34 | console.log('appPaths.state(true):', xdgAppPaths.state(true));
35 | console.log(objectEntries(xdgAppPaths));
36 | console.log('appPaths.log(false):', (xdgAppPaths as XDGAppPathsWithLog).log(false));
37 | console.log('appPaths.log(true):', (xdgAppPaths as XDGAppPathsWithLog).log(true));
38 |
39 | delete process.env.XDG_CONFIG_HOME;
40 | // eslint-disable-next-line functional/no-let
41 | let p = xdgAppPaths('dross');
42 |
43 | console.log('p:', inspect(p));
44 | console.log(objectEntries(p));
45 |
46 | p = xdgAppPaths({ suffix: '-nodejs' });
47 |
48 | console.log('p:', inspect(p));
49 | console.log(objectEntries(p));
50 |
51 | p = xdgAppPaths({ name: 'extraordinaire', suffix: '-nodejs' });
52 |
53 | console.log('p:', inspect(p));
54 | console.log(objectEntries(p));
55 |
56 | p = xdgAppPaths({ name: 'fluffy', isolated: false });
57 |
58 | console.log('p:', inspect(p));
59 | console.log(objectEntries(p));
60 |
61 | /* eslint-enable @typescript-eslint/no-explicit-any , functional/immutable-data , no-console , security-node/detect-crlf , security/detect-object-injection */
62 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xdg-app-paths",
3 | "version": "8.3.0",
4 | "description": "Determine (XDG-compatible) paths for storing application files (cache, config, data, etc)",
5 | "license": "MIT",
6 | "repository": "rivy/js.xdg-app-paths",
7 | "author": {
8 | "name": "Roy Ivy III",
9 | "email": "rivy.dev@gmail.com"
10 | },
11 | "engines": {
12 | "node": ">= 4.0"
13 | },
14 | "packageManager": "yarn@1.22.19",
15 | "files": [
16 | "cjs",
17 | "dist/cjs",
18 | "dist/types",
19 | "CHANGELOG.mkd",
20 | "LICENSE",
21 | "README.md",
22 | "package.json"
23 | ],
24 | "type": "commonjs",
25 | "main": "./dist/cjs/mod.cjs.js",
26 | "module": "./dist/cjs/esm-wrapper/mod.esm.js",
27 | "types": "./dist/types/mod.d.ts",
28 | "exports": {
29 | ".": {
30 | "deno": "./src/mod.deno.ts",
31 | "import": "./dist/cjs/esm-wrapper/mod.esm.js",
32 | "require": "./dist/cjs/mod.cjs.js",
33 | "types": "./dist/types/mod.d.ts",
34 | "default": "./dist/cjs/mod.cjs.js"
35 | },
36 | "./package.json": "./package.json",
37 | "./cjs": {
38 | "require": "./dist/cjs/mod.cjs.js",
39 | "types": "./dist/cjs/mod.cjs.d.ts"
40 | }
41 | },
42 | "keywords": [
43 | "appdir",
44 | "application",
45 | "cache",
46 | "common",
47 | "config",
48 | "cross-platform",
49 | "data",
50 | "directory",
51 | "environment",
52 | "linux",
53 | "mac",
54 | "macos",
55 | "node4",
56 | "node6",
57 | "node-v4",
58 | "node-v6",
59 | "osx",
60 | "path",
61 | "paths",
62 | "portable",
63 | "runtime",
64 | "state",
65 | "unix",
66 | "user",
67 | "windows",
68 | "xdg"
69 | ],
70 | "scripts": {
71 | "# build # build/compile package": "",
72 | "build": "run-s --silent \"build:*\"",
73 | "build:cjs": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source \"rollup.*.config.js\" --source \"src/**\" --target build/.targets/build-cjs.succeeded \"run-s -n rebuild:cjs\"",
74 | "build:esm": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source \"rollup.*.config.js\" --source \"src/**\" --target build/.targets/build-esm.succeeded \"run-s -n rebuild:esm\"",
75 | "build:umd": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source \"rollup.*.config.js\" --source \"src/**\" --target build/.targets/build-umd.succeeded \"run-s -n rebuild:umd\"",
76 | "build:lab": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source \"rollup.*.config.js\" --source \"src/**\" --target build/.targets/build-lab.succeeded \"run-s -n rebuild:lab\"",
77 | "build:types": "exec-if-updated --source package.json --source tsconfig.json --source \"tsconfig/**\" --source \"rollup.*.config.js\" --source \"src/**\" --target build/.targets/build-types.succeeded \"run-s -n rebuild:types\"",
78 | "# clean # remove build artifacts": "",
79 | "clean": "shx rm -fr build dist",
80 | "# coverage # calculate and display (or send) code coverage [alias: 'cov']": "",
81 | "coverage": "run-s --silent +:max-node-8 && shx echo \"[coverage] WARN Code coverage skipped [for NodeJS < v10]\" 1>&2 || run-s \"+:coverage\"",
82 | "cov": "run-s coverage",
83 | "cov:html": "nyc report --reporter=html --report-dir=.coverage",
84 | "#* cov:send # use `--cov-send=...` to pass options to coverage uploader": "",
85 | "cov:send": "shx mkdir -p .coverage && nyc report --reporter=text-lcov > \".coverage/@coverage.lcov\" && cross-env-shell codecov --disable=gcov --file=\".coverage/@coverage.lcov\" $npm_config_cov_send",
86 | "cov:text": "nyc report",
87 | "cov:view": "run-s cov:html && cd .coverage && open-cli index.html",
88 | "dist": "run-s update",
89 | "# fix # fix package issues (automated/non-interactive)": "",
90 | "fix": "run-s fix:*",
91 | "# fix:lint # fix ESLint issues": "",
92 | "fix:lint": "eslint . --fix",
93 | "# fix:style # fix Prettier formatting issues": "",
94 | "fix:style": "prettier . --write --list-different",
95 | "# help # display help": "",
96 | "help": "run-s --silent _:help",
97 | "# lint # check for package code 'lint'": "",
98 | "lint": "run-s --silent +:max-node-8 && shx echo \"[lint] WARN Lint checks skipped [for NodeJS < v10]\" 1>&2 || run-p --print-name \"lint:*\"",
99 | "# lint:audit # check for `npm audit` violations in project code": "",
100 | "lint:audit": "run-s --silent -- npm audit --omit dev",
101 | "# lint:commits # check for commit flaws (using `commitlint` and `cspell`)": "",
102 | "lint:commits": "run-p --silent \"_:lint:commits:new:*\"",
103 | "# lint:editorconfig # check for EditorConfig format flaws (using `editorconfig-checker`)": "",
104 | "lint:editorconfig": "editorconfig-checker -config .ecrc.JS.json",
105 | "# lint:lint # check for code 'lint' (using `eslint`)": "",
106 | "lint:lint": "eslint .",
107 | "# lint:markdown # check for markdown errors (using `remark`)": "",
108 | "lint:markdown": "remark --quiet .",
109 | "# lint:spell # check for spelling errors (using `cspell`)": "",
110 | "lint:spell": "cspell {eg,examples,src,test}/**/* CHANGELOG{,.md,.mkd} README{,.md,.mkd} --no-summary --config \".vscode/cspell.json\"",
111 | "# lint:style # check for format imperfections (using `prettier`)": "",
112 | "lint:style": "prettier . --check --loglevel warn",
113 | "# prerelease # clean, rebuild, and fully test (useful prior to publish/release)": "",
114 | "prerelease": "run-s clean update verify",
115 | "# realclean # remove all generated files": "",
116 | "realclean": "run-s clean && shx rm -fr .coverage .nyc_output",
117 | "# rebuild # clean and (re-)build project": "",
118 | "rebuild": "run-s clean build",
119 | "rebuild:all": "run-s clean build update",
120 | "rebuild:cjs": "shx rm -fr build/cjs && tsc -p tsconfig/tsconfig.cjs.json && shx cp -r src/esm-wrapper build/cjs/src && shx mkdir -p build/.targets && shx touch build/.targets/build-cjs.succeeded",
121 | "rebuild:esm": "shx rm -fr build/esm && tsc -p tsconfig/tsconfig.esm.json && shx cp src/esm-wrapper/package.json build/esm/src && shx mkdir -p build/.targets && shx touch build/.targets/build-esm.succeeded",
122 | "rebuild:umd": "shx rm -fr build/umd && tsc -p tsconfig/tsconfig.umd.json && shx mkdir -p build/.targets && shx touch build/.targets/build-umd.succeeded",
123 | "rebuild:lab": "shx rm -fr build/lab && tsc -p tsconfig/tsconfig.lab.json && shx cp -r src/esm-wrapper build/lab/src && shx mkdir -p build/.targets && shx touch build/.targets/build-lab.succeeded",
124 | "rebuild:types": "shx rm -fr build/types && tsc -p tsconfig/tsconfig.types.json && shx mkdir -p build/.targets && shx touch build/.targets/build-types.succeeded",
125 | "# refresh # clean and rebuild/regenerate all project artifacts": "",
126 | "refresh": "run-s rebuild:all",
127 | "# refresh:dist # clean, rebuild, and regenerate project distribution": "",
128 | "refresh:dist": "run-s rebuild update:dist",
129 | "# retest # clean and (re-)test project": "",
130 | "retest": "run-s clean test",
131 | "# reset:hard # remove *all* generated files and reinstall dependencies": "",
132 | "reset:hard": "git clean -dfx && git reset --hard && npm install",
133 | "# show:deps # show package dependencies": "",
134 | "show:deps": "run-s --silent _:show:deps:prod _:show:deps:dev || shx true",
135 | "# test # test package": "",
136 | "test": "run-s --silent lint update:dist && run-p test:*",
137 | "# test:code # test package code (use `--test-code=...` to pass options to testing harness)": "",
138 | "test:code": "run-s --silent +:max-node-8 && cross-env-shell ava $npm_config_test_code || ( run-s --silent +:min-node-10 && cross-env-shell nyc --silent ava $npm_config_test_code )",
139 | "# test:types # test for type declaration errors (using `tsd`)": "",
140 | "test:types": "run-s --silent +:max-node-8 && shx echo \"[test:types] WARN Type testing skipped [for NodeJS < v10]\" 1>&2 || tsd",
141 | "# update # update/prepare for distribution [alias: 'dist']": "",
142 | "update": "run-s update:changelog update:dist",
143 | "# update:changelog # update CHANGELOG (using `git changelog ...`)": "",
144 | "update:changelog": "run-s --silent _:update:changelog && git diff --quiet --exit-code CHANGELOG.mkd || shx echo \"[update] info CHANGELOG updated\"",
145 | "# update:dist # update distribution content": "",
146 | "update:dist": "run-s --silent build && exec-if-updated --source \"build/**\" --target \"dist/**\" --target build/.targets/update-dist.succeeded \"run-s --silent _:update:dist:rebuild\"",
147 | "# verify # fully (and verbosely) test package": "",
148 | "verify": "cross-env npm_config_test_dist=true npm_config_test=--verbose run-s test",
149 | "## +:... == sub-scripts (may run 'visibly', but not user-facing)": "",
150 | "+:coverage": "run-s build test:code && ( is-ci && run-s cov:send ) || ( run-s --silent _:is-not-ci && run-s cov:view )",
151 | "+:max-node-8": "is-node-not-modern 10",
152 | "+:min-node-10": "is-node-modern 10",
153 | "## _:... == sub-scripts ('hidden'; generally should be run 'silently' using `run-s/run-p --silent ...`": "",
154 | "_:debug:env": "node -e \"console.log({env: process.env})\"",
155 | "_:exists:git-changelog": "node -e \"if (!require('command-exists').sync('git-changelog')){process.exit(1);};\" || ( shx echo \"WARN `git-changelog` missing (try `go get -u github.com/rivy-go/git-changelog/cmd/git-changelog`)\" & exit 1 )",
156 | "* _:help # print usage/TARGETs by matching lines containing leading double-quoted text like `# TARGET_NAME # HELP_TEXT`": "",
157 | "_:help": "< package.json node -e \"s = {p:'',e:'npm'}; if (new String(process.env.npm_execpath).match(/yarn.js$/)) { s = {p:'\\n',e:'yarn'}; }; console.log('%sUsage: \\`\\x1b[2m%s run TARGET\\x1b[m\\` or \\`\\x1b[2mnpx run-s TARGET [TARGET..]\\x1b[m\\`\\n\\nTARGETs:\\n', s.p, s.e); re = /^.*?\\x22(?:#\\s*)(\\w[^#\\x22]*)\\s+#+\\s+([^\\x22]+?)(\\s+#+)?\\x22.*$/; require('readline').createInterface({ input: process.stdin, output: process.stdout, terminal: false }).on('line', function(line){ if (match = re.exec(line)) { console.log('\\x1b[0;32m%s\\x1b[m %s', match[1].padEnd(19), match[2]); } }).on('close', () => { /^win/i.test(process.platform) || console.log(); });\"",
158 | "_:is-not-ci": "is-ci && exit 1 || exit 0",
159 | "_:lint:commits:all:spell": "node -e \"result=require('child_process').spawnSync('git log --color=never | cspell stdin --no-summary --config \".vscode/cspell.json\"',{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('[cspell] ERR! Unknown words in commit(s)\\n'+result.stdout+'\\n'+result.stderr); process.exit(1);} else {console.log(result.stdout);};\"",
160 | "* _:lint:commits:new:... * note: review from 'origin/last' or tag just prior to version-sorted latest, with fallback to first commit": "",
161 | "_:lint:commits:new:commitlint": "node -e \"result=require('child_process').spawnSync('( git tag --list [#v]* --contains origin/last --sort=v:refname || shx true ) && ( git describe --tags --abbrev=0 HEAD~1 || shx true ) && ( git rev-list --max-parents=0 HEAD --abbrev-commit --abbrev=16 || shx true )',{shell:true,encoding:'utf-8'}); o=result.stdout.split(/\\r?\\n/).filter((s)=>!!s); vs=o; v=vs[0]; result=require('child_process').spawnSync('commitlint --config .commitlint.config.js --from '+v,{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('[commitlint] ERR! Flawed commit(s) found (within \\'%s..HEAD\\')\\n'+result.stdout+'\\n'+result.stderr, v); process.exit(1);} else { (result.stdout.length > 0) && console.log(result.stdout);};\" || shx true",
162 | "_:lint:commits:new:spell": "node -e \"result=require('child_process').spawnSync('( git tag --list [#v]* --contains origin/last --sort=v:refname || shx true ) && ( git describe --tags --abbrev=0 HEAD~1 || shx true ) && ( git rev-list --max-parents=0 HEAD --abbrev-commit --abbrev=16 || shx true )',{shell:true,encoding:'utf-8'}); o=result.stdout.split(/\\r?\\n/).filter((s)=>!!s); vs=o; v=vs[0]; result=require('child_process').spawnSync('git log '+v+'.. --color=never | cspell stdin --no-summary --config \".vscode/cspell.json\"',{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('[cspell] ERR! Unknown words in commit(s) (within \\'%s..HEAD\\')\\n'+result.stdout+'\\n'+result.stderr, v); process.exit(1);} else {(result.stdout.length > 0) && console.log(result.stdout);};\" || shx true",
163 | "_:show:deps:dev": "npm --silent ls --only development || shx true",
164 | "_:show:deps:prod": "npm --silent ls --only production || shx true",
165 | "_:vcs-clean": "git diff --quiet",
166 | "_:vcs-clean-err": "run-s --silent _:vcs-clean || ( shx echo \"[vcs] ERR! Uncommitted changes\" 1>&2 & exit 1 )",
167 | "_:vcs-strictly-clean": "git status --porcelain | node -e \"process.stdin.on('data',function(_){process.exit(1);});\"",
168 | "_:vcs-strictly-clean-err": "run-s --silent _:vcs-strictly-clean || ( shx echo \"[vcs] ERR! Uncommitted changes and/or untracked files\" 1>&2 & exit 1 )",
169 | "_:update:changelog": "run-s --silent _:exists:git-changelog && git changelog > CHANGELOG.mkd || shx echo \"[update] WARN CHANGELOG not updated\" 1>&2",
170 | "_:update:dist.build": "shx rm -fr dist/cjs dist/esm && shx mkdir -p dist/cjs dist/esm && shx cp -r build/cjs/src/* dist/cjs && shx cp -r build/esm/src/* dist/esm",
171 | "_:update:dist.normalizeEOL": "eolConverter lf dist/**/*.{cjs,js,mjs,ts,json}",
172 | "_:update:dist.pack": "node -e \"delete process.env.npm_config_dry_run; name=require('./package.json').name; name=name.replace(/^@/,'').replace('/','-'); result=require('child_process').spawnSync('npm pack && shx mkdir -p dist && shx mv '+name+'-*.tgz dist/'+name+'.tgz',{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('[update] ERR! Unable to package (into *.tgz) for distribution\\n'+result.stdout+'\\n'+result.stderr); process.exit(1);} else {console.log(result.stdout);};\"",
173 | "_:update:dist.types": "shx mkdir -p dist && shx rm -fr dist/types && rollup --config .rollup.config.types.js && replace-in-file \"export { _default as default }\" \"export = _default\" dist/types/mod.cjs.d.ts --quiet && shx mkdir -p dist/cjs && shx cp dist/types/*.cjs.d.ts dist/cjs",
174 | "_:update:dist:rebuild": "shx rm -fr dist && run-s --silent _:update:dist.build _:update:dist.types _:update:dist.normalizeEOL _:update:dist.pack && shx mkdir -p dist/.targets && shx touch build/.targets/update-dist.succeeded",
175 | "_:version:spell:changelog_update": "run-s --silent _:exists:git-changelog && git changelog -u | cspell stdin --config \".vscode/cspell.json\" || shx echo \"[lint] WARN CHANGELOG update `cspell` exception\" 1>&2",
176 | "_:version:update:changelog": "run-s --silent _:exists:git-changelog && node -e \"v=require('./package.json').version; result=require('child_process').spawnSync('git changelog --next-tag-now --next-tag v'+v,{shell:true,encoding:'utf-8'}); if (result.status != 0) {console.error('ERR! '+result.stderr); process.exit(1);} else {m='fs';require(m).writeFileSync('CHANGELOG.mkd',result.stdout);};\" || shx echo \"[version] WARN CHANGELOG not updated\" 1>&2",
177 | "## npm lifecycle scripts ##": "",
178 | "prepublishOnly": "run-s clean update && cross-env npm_config_test_dist=true npm run test && run-s --silent update _:vcs-strictly-clean-err",
179 | "## npm-version scripts ##": "",
180 | "preversion": "run-s --silent _:version:spell:changelog_update && cross-env npm_config_test_dist=true npm run test",
181 | "version": "run-s --silent _:version:update:changelog && run-s lint:spell && run-s --silent update:dist && git add CHANGELOG.mkd dist"
182 | },
183 | "dependencies": {
184 | "xdg-portable": "^10.6.0"
185 | },
186 | "devDependencies:#": "* for testing, Node-v6 requires ava < v2 and nyc < v15",
187 | "devDependencies": {
188 | "@ava/typescript": "^1.1.1",
189 | "@commitlint/cli": "^11.0.0",
190 | "@commitlint/config-conventional": "^11.0.0",
191 | "@istanbuljs/nyc-config-typescript": "^1.0.1",
192 | "@types/node": "^14.14.20",
193 | "@typescript-eslint/eslint-plugin": "^4",
194 | "@typescript-eslint/parser": "^4",
195 | "ava": "^3.15.0",
196 | "codecov": "^3.5.0",
197 | "command-exists": "^1.2.9",
198 | "cross-env": "^7.0.3",
199 | "cross-spawn": "^7.0.3",
200 | "cspell": "^4.2.7",
201 | "editorconfig-checker": "^3.3.0",
202 | "eol-converter-cli": "^1.0.8",
203 | "eslint": "^7",
204 | "eslint-config-prettier": "^7",
205 | "eslint-plugin-eslint-comments": "^3",
206 | "eslint-plugin-functional": "^3",
207 | "eslint-plugin-import": "^2",
208 | "eslint-plugin-security": "^1",
209 | "eslint-plugin-security-node": "^1",
210 | "exec-if-updated": "https://cdn.jsdelivr.net/gh/rivy/js-cli.exec-if-updated@2.2.0/dist/pkg/exec-if-updated.tgz",
211 | "is-ci": "^2.0.0",
212 | "is-node-modern": "^1.0.0",
213 | "npm-run-all": "^4.1.5",
214 | "nyc": "^15.1.0",
215 | "open-cli": ">=6.0 <7.0",
216 | "prettier": "^2.1.1",
217 | "remark-cli": "=9.0.0",
218 | "remark-footnotes": "^3.0.0",
219 | "remark-preset-lint-consistent": "^4.0.0",
220 | "remark-preset-lint-markdown-style-guide": "^4.0.0",
221 | "remark-preset-lint-recommended": "^5.0.0",
222 | "remark-retext": "^4.0.0",
223 | "replace-in-file": "=6.3.0",
224 | "retext-english": "^3.0.4",
225 | "retext-passive": "^3.0.0",
226 | "retext-repeated-words": "^3.0.0",
227 | "retext-sentence-spacing": "^4.0.0",
228 | "retext-syntax-urls": "^2.0.0",
229 | "rollup": "^2.36.1",
230 | "rollup-plugin-dts": "^2.0.1",
231 | "rollup-plugin-typescript2": "^0.29.0",
232 | "shx": "^0.3.3",
233 | "ts-node": "^9.0.0",
234 | "tsd": "^0.14.0",
235 | "typedoc": "^0.20.27",
236 | "typescript": "~4.2.0",
237 | "unified": "^9.2.0"
238 | },
239 | "optionalDependencies:#": "* 'fsevents' included to avoid `npm ci` errors with early npm versions; ref: ",
240 | "optionalDependencies": {
241 | "fsevents": "*"
242 | },
243 | "ava": {
244 | "files": [
245 | "!**/*.test-d.ts"
246 | ],
247 | "timeout": "60s",
248 | "typescript": {
249 | "rewritePaths": {
250 | "src/": "build/lab/src/"
251 | }
252 | }
253 | },
254 | "nyc": {
255 | "extends": "@istanbuljs/nyc-config-typescript",
256 | "exclude": [
257 | "build/cjs/**",
258 | "build/esm/**",
259 | "build/umd/**",
260 | "dist/**",
261 | "eg/**",
262 | "test/**",
263 | "**/*.test.*",
264 | "**/*.spec.*"
265 | ],
266 | "reporter": [
267 | "html",
268 | "text"
269 | ],
270 | "lines": "100",
271 | "branches": "96",
272 | "statements": "100"
273 | },
274 | "tsd": {
275 | "directory": "test"
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/src/esm-wrapper/mod.esm.js:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import _ from '../mod.cjs.js';
4 | export * from '../mod.cjs.js';
5 | export default _;
6 |
--------------------------------------------------------------------------------
/src/esm-wrapper/package.json:
--------------------------------------------------------------------------------
1 | {"type": "module"}
2 |
--------------------------------------------------------------------------------
/src/lib/XDGAppPaths.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 | // # spell-checker:ignore APPDATA LOCALAPPDATA MacOS tempdir
3 | /* eslint-env es6, node */
4 | 'use strict';
5 |
6 | import { Platform } from '../platform-adapters/_base.js';
7 |
8 | // XDG references
9 | // # ref: @@
10 | // # ref: @@
11 | // # ref: @@
12 | // # ref: @@
13 | // # ref: @@
14 |
15 | /** Configuration options supplied to `XDGAppPaths` methods */
16 | // eslint-disable-next-line functional/prefer-type-literal
17 | interface DirOptions {
18 | /** Isolation flag; used to override the default isolation mode, when needed. */
19 | readonly isolated?: boolean | null;
20 | }
21 |
22 | /** Configuration options supplied when constructing `XDGAppPaths` */
23 | // eslint-disable-next-line functional/prefer-type-literal
24 | interface Options {
25 | /** Name of the application; used to generate isolated application paths.
26 | > When missing (`undefined`), `null`, or empty (`''`), it is generated automatically from the process main file name, where determinable.
27 | > "$eval" is used as a final fallback value when the application name cannot otherwise be determined.
28 | */
29 | readonly name?: string | null;
30 | /** Suffix which is appended to the application name when generating the application paths. */
31 | readonly suffix?: string | null;
32 | /** Default isolation flag (used when no isolation flag is supplied for `DirOptions`). */
33 | readonly isolated?: boolean | null;
34 | }
35 |
36 | /** `XDGAppPaths` (API) - Determine (XDG-compatible) paths for storing application files (cache, config, data, etc) */
37 | // eslint-disable-next-line functional/prefer-type-literal
38 | interface XDGAppPaths {
39 | /** Create an `XDGAppPaths` object (a preceding `new` is optional). */
40 | (options?: Options | string): XDGAppPaths;
41 |
42 | /** Create an `XDGAppPaths` object (`new` is optional). */
43 | // eslint-disable-next-line @typescript-eslint/no-misused-new
44 | new (options?: Options | string): XDGAppPaths;
45 |
46 | /* eslint-disable functional/no-method-signature */
47 |
48 | /** Returns the directory for non-essential data files.
49 | > Deletion of the data contained here might cause an application to slow down.
50 | */
51 | cache(dirOptions?: DirOptions | boolean): string;
52 |
53 | /** Returns the directory for config files.
54 | > Deletion of the data contained here might require the user to reconfigure an application.
55 | */
56 | config(dirOptions?: DirOptions | boolean): string;
57 |
58 | /** Returns the directory for data files.
59 | > Deletion of the data contained here might force the user to restore from backups.
60 | */
61 | data(dirOptions?: DirOptions | boolean): string;
62 |
63 | /** Returns the directory for runtime files; may return `undefined`.
64 | > Deletion of the data contained here might interfere with a currently executing application but should have no effect on future executions.
65 | */
66 | runtime(dirOptions?: DirOptions | boolean): string | undefined;
67 |
68 | /** Returns the directory for state files.
69 | > Deletion of the data contained here should not materially interfere with execution of an application.
70 | */
71 | state(dirOptions?: DirOptions | boolean): string;
72 |
73 | /** Returns a priority-sorted list of possible directories for configuration file storage (includes `paths.config()` as the first entry). */
74 | configDirs(dirOptions?: DirOptions | boolean): readonly string[];
75 |
76 | /** Returns a priority-sorted list of possible directories for data file storage (includes `paths.data()` as the first entry). */
77 | dataDirs(dirOptions?: DirOptions | boolean): readonly string[];
78 |
79 | /** Application name used for path construction (from supplied configuration or auto-generated). */
80 | $name(): string;
81 | /** Default isolation mode used by the particular `XDGAppPaths` instance. */
82 | $isolated(): boolean;
83 |
84 | /* eslint-enable functional/no-method-signature */
85 | }
86 |
87 | function isBoolean(t: T | boolean): t is boolean {
88 | return typeOf(t) === 'boolean';
89 | }
90 |
91 | function isObject(t: T | Record): t is Record {
92 | return typeOf(t) === 'object';
93 | }
94 |
95 | function isString(t: T): boolean {
96 | return typeOf(t) === 'string';
97 | }
98 |
99 | function typeOf(t: T): string {
100 | return typeof t;
101 | }
102 |
103 | function Adapt(adapter_: Platform.Adapter): { readonly XDGAppPaths: XDGAppPaths } {
104 | const { meta, path, xdg } = adapter_;
105 | // eslint-disable-next-line functional/no-class
106 | class XDGAppPaths_ {
107 | constructor(options_: Options | string = {}) {
108 | function XDGAppPaths(options: Options | string = {}): XDGAppPaths {
109 | return new XDGAppPaths_(options) as XDGAppPaths;
110 | }
111 |
112 | const options = (isObject(options_) ? options_ : { name: options_ }) as Options;
113 |
114 | const suffix = options.suffix ?? '';
115 | const isolated_ = options.isolated ?? true;
116 |
117 | // derive a suitable application name
118 | const namePriorityList: ReadonlyArray = [
119 | options.name,
120 | meta.pkgMainFilename(),
121 | meta.mainFilename(),
122 | ];
123 | const nameFallback = '$eval';
124 | const name = path.parse(
125 | (namePriorityList.find((e) => isString(e)) ?? nameFallback) + suffix
126 | ).name;
127 |
128 | XDGAppPaths.$name = function $name() {
129 | return name;
130 | };
131 | XDGAppPaths.$isolated = function $isolated() {
132 | return isolated_;
133 | };
134 |
135 | function isIsolated(dirOptions?: DirOptions | boolean): boolean {
136 | dirOptions = dirOptions ?? { isolated: isolated_ };
137 | const isolated = isBoolean(dirOptions) ? dirOptions : dirOptions.isolated ?? isolated_;
138 | return isolated;
139 | }
140 |
141 | function finalPathSegment(dirOptions?: DirOptions | boolean): string {
142 | return isIsolated(dirOptions) ? name : '';
143 | }
144 |
145 | XDGAppPaths.cache = function cache(dirOptions?: DirOptions | boolean) {
146 | return path.join(xdg.cache(), finalPathSegment(dirOptions));
147 | };
148 |
149 | XDGAppPaths.config = function config(dirOptions?: DirOptions | boolean) {
150 | return path.join(xdg.config(), finalPathSegment(dirOptions));
151 | };
152 |
153 | XDGAppPaths.data = function data(dirOptions?: DirOptions | boolean) {
154 | return path.join(xdg.data(), finalPathSegment(dirOptions));
155 | };
156 |
157 | XDGAppPaths.runtime = function runtime(dirOptions?: DirOptions | boolean) {
158 | return xdg.runtime()
159 | ? path.join(xdg.runtime() as string, finalPathSegment(dirOptions))
160 | : void 0;
161 | };
162 |
163 | XDGAppPaths.state = function state(dirOptions?: DirOptions | boolean) {
164 | return path.join(xdg.state(), finalPathSegment(dirOptions));
165 | };
166 |
167 | XDGAppPaths.configDirs = function configDirs(dirOptions?: DirOptions | boolean) {
168 | return xdg
169 | .configDirs()
170 | .map((s) => path.join(s, finalPathSegment(dirOptions))) as readonly string[];
171 | };
172 |
173 | XDGAppPaths.dataDirs = function dataDirs(dirOptions?: DirOptions | boolean) {
174 | return xdg
175 | .dataDirs()
176 | .map((s) => path.join(s, finalPathSegment(dirOptions))) as readonly string[];
177 | };
178 |
179 | return XDGAppPaths as XDGAppPaths;
180 | }
181 | }
182 |
183 | return { XDGAppPaths: new XDGAppPaths_() as XDGAppPaths };
184 | }
185 |
186 | export type { DirOptions, Options, XDGAppPaths };
187 | export { Adapt };
188 |
--------------------------------------------------------------------------------
/src/mod.cjs.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import { Adapt } from './lib/XDGAppPaths.js';
4 | import type { XDGAppPaths } from './lib/XDGAppPaths.js';
5 | import { adapter } from './platform-adapters/node.js';
6 |
7 | export = Adapt(adapter).XDGAppPaths as XDGAppPaths;
8 |
--------------------------------------------------------------------------------
/src/mod.deno.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 | // spell-checker:ignore Deno
3 |
4 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5 | // @ts-ignore
6 | import { Adapt } from '../dist/esm/lib/XDGAppPaths.js';
7 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
8 | // @ts-ignore
9 | import { DirOptions, Options, XDGAppPaths } from '../dist/types/mod.d.ts';
10 |
11 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12 | // @ts-ignore
13 | import { adapter } from './platform-adapters/deno.deno.ts';
14 |
15 | const _: XDGAppPaths = Adapt(adapter).XDGAppPaths as XDGAppPaths;
16 |
17 | export type { DirOptions, Options, XDGAppPaths };
18 | export default _;
19 |
--------------------------------------------------------------------------------
/src/mod.esm.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import { Adapt } from './lib/XDGAppPaths.js';
4 | import type { DirOptions, Options, XDGAppPaths } from './lib/XDGAppPaths.js';
5 | import { adapter } from './platform-adapters/node.js';
6 |
7 | const _: XDGAppPaths = Adapt(adapter).XDGAppPaths as XDGAppPaths;
8 |
9 | export type { DirOptions, Options, XDGAppPaths };
10 | export default _;
11 |
--------------------------------------------------------------------------------
/src/mod.test.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import test from 'ava';
4 |
5 | import mESM from './mod.esm.js';
6 |
7 | // eslint-disable-next-line @typescript-eslint/no-var-requires
8 | const mCJS = require('./mod.cjs.js');
9 |
10 | test('CJS <=> ESM', (t) => {
11 | t.deepEqual(JSON.stringify(mCJS), JSON.stringify(mESM));
12 |
13 | const api = [
14 | 'cache',
15 | 'config',
16 | 'data',
17 | 'runtime',
18 | 'state',
19 | 'configDirs',
20 | 'dataDirs',
21 | '$name',
22 | '$isolated',
23 | ];
24 |
25 | t.is(typeof mCJS, 'function');
26 | t.is(typeof mCJS, typeof mESM);
27 | t.is(Object.keys(mCJS).length, api.length);
28 | t.is(Object.keys(mCJS).length, Object.keys(mESM).length);
29 | api.forEach((key) => {
30 | /* eslint-disable @typescript-eslint/no-explicit-any , security/detect-object-injection */
31 | t.is(typeof mCJS[key], 'function');
32 | t.is(typeof mCJS[key], typeof (mESM as any)[key]);
33 | t.deepEqual(mCJS[key](), (mESM as any)[key]());
34 | /* eslint-enable @typescript-eslint/no-explicit-any , security/detect-object-injection */
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/src/platform-adapters/_base.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 | // eslint-disable-next-line @typescript-eslint/no-namespace
3 | export namespace Platform {
4 | export type ParsedPath = {
5 | readonly base: string;
6 | readonly dir: string;
7 | readonly ext: string;
8 | readonly name: string;
9 | readonly root: string;
10 | };
11 | export type Adapter = {
12 | readonly atImportPermissions: {
13 | /** Is general environment access granted at module import time?
14 | - note: used for graceful degradation, but this grant is *required* for unimpaired module functionality
15 | - always `true` for non-Deno platforms
16 | */
17 | readonly env?: boolean;
18 | /** Is general file system read access granted at module import time?
19 | - note: used for graceful degradation, but this grant is *required* for unimpaired module functionality
20 | - always `true` for non-Deno platforms
21 | */
22 | readonly read?: boolean;
23 | };
24 | readonly meta: {
25 | readonly mainFilename: () => string | undefined;
26 | readonly pkgMainFilename: () => string | undefined;
27 | };
28 | readonly path: {
29 | /** Path list delimiter */
30 | readonly delimiter: string;
31 | /** @function Returns all path segments, joined using the platform-specific separator, and normalized. */
32 | readonly join: (...paths: readonly string[]) => string;
33 | /** @function Returns the normalized path, resolving all `.` and `..` segments. */
34 | readonly normalize: (path: string) => string;
35 | /** @function Returns an object whose properties represent significant elements of the `path`. */
36 | readonly parse: (path: string) => ParsedPath;
37 | };
38 | readonly process: {
39 | /** OS/platform identity string */
40 | readonly platform: string;
41 | };
42 | readonly xdg: {
43 | /** @function Returns the directory path for user-specific non-essential (ie, cached) data files. */
44 | readonly cache: () => string;
45 | /** @function Returns the directory path for user-specific configuration files. */
46 | readonly config: () => string;
47 | /** @function Returns directory path for user-specific data files. */
48 | readonly data: () => string;
49 | /** @function Returns the directory path for user-specific non-essential runtime files (such as sockets, named pipes, etc); may be `undefined`. */
50 | readonly runtime: () => string | undefined;
51 | /** @function Returns the directory path for user-specific state files (non-essential and more volatile than configuration files). */
52 | readonly state: () => string;
53 | /** @function Returns a preference-ordered array of base directory paths to search for configuration files (includes `.config()` directory as first entry). */
54 | readonly configDirs: () => readonly string[];
55 | /** @function Returns a preference-ordered array of base directory paths to search for data files (includes `.data()` directory as first entry). */
56 | readonly dataDirs: () => readonly string[];
57 | };
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/src/platform-adapters/deno.deno.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 | // spell-checker:ignore Deno
3 |
4 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5 | // @ts-ignore // deno-type URL import
6 | import * as path from 'https://deno.land/std@0.134.0/path/mod.ts';
7 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
8 | // @ts-ignore // deno-type URL import
9 | import xdg from 'https://deno.land/x/xdg@v10.5.0/src/mod.deno.ts';
10 |
11 | /* eslint-disable @typescript-eslint/ban-ts-comment */
12 |
13 | // @ts-ignore // deno-type import
14 | import { Platform } from './_base.ts';
15 |
16 | // create a local reference to refer to `Deno` (for better linting without need for multiple `// @ts-ignore` directives)
17 | // @ts-ignore // Deno alias to suppress other false-positive TS warnings
18 | const deno = Deno;
19 |
20 | // Deno general permission(s) at time of import
21 | // * Deno.Permissions (stabilized in v1.8.0)
22 | const queryEnv = await deno?.permissions?.query({ name: 'env' });
23 | const allowEnv = (queryEnv?.state ?? 'granted') === 'granted';
24 | const queryRead = await deno?.permissions?.query({ name: 'read' });
25 | const allowRead = (queryRead?.state ?? 'granted') === 'granted';
26 |
27 | export const adapter: Platform.Adapter = {
28 | atImportPermissions: { env: allowEnv, read: allowRead },
29 | meta: {
30 | mainFilename: allowRead ? () => deno.mainModule : () => void 0,
31 | pkgMainFilename: () => void 0,
32 | },
33 | path,
34 | process: { platform: deno.build.os },
35 | xdg,
36 | };
37 |
38 | /* eslint-enable @typescript-eslint/ban-ts-comment */
39 |
--------------------------------------------------------------------------------
/src/platform-adapters/node.ts:
--------------------------------------------------------------------------------
1 | // deno-fmt-ignore-file ## prefer customized `prettier` formatting
2 |
3 | import * as path from 'path';
4 |
5 | import xdg from 'xdg-portable';
6 |
7 | import { Platform } from './_base.js';
8 |
9 | export const adapter: Platform.Adapter = {
10 | atImportPermissions: { env: true, read: true },
11 | meta: {
12 | mainFilename: () => {
13 | const requireMain =
14 | typeof require !== 'undefined' && require !== null && require.main
15 | ? require.main
16 | : { filename: void 0 };
17 | const requireMainFilename = requireMain.filename;
18 | const filename =
19 | // HACK: additional comparison `require?.main?.filename !== process.execArgv[0]` compensates for ESM scripts run via `ts-node`
20 | (requireMainFilename !== process.execArgv[0] ? requireMainFilename : void 0) ||
21 | // HACK: `process._eval` is undocumented; used here (again, for ESM) as evidence of `node -e ...` differentiating between immediate eval vs file-bound scripts
22 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
23 | (typeof (process as any)._eval === 'undefined' ? process.argv[1] : void 0);
24 | return filename;
25 | },
26 | pkgMainFilename: () => {
27 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
28 | return (process as any).pkg ? process.execPath : void 0;
29 | },
30 | },
31 | path,
32 | process,
33 | xdg,
34 | };
35 |
--------------------------------------------------------------------------------
/test/dist.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env es6, node */
2 | 'use strict';
3 |
4 | /* note: dynamic imports are used because 'dist' may not exist */
5 |
6 | const fs = require('fs');
7 | const path = require('path');
8 |
9 | const test = require('ava');
10 |
11 | const vNodeJS = process.versions.node.split('.');
12 | const vNodeJSMajor = +vNodeJS[0];
13 |
14 | // Distribution tests
15 |
16 | const packagePath = '../package.json';
17 |
18 | // eslint-disable-next-line security-node/detect-non-literal-require-calls
19 | const pkg = require(packagePath);
20 |
21 | const packageCJSPath = path.resolve(__dirname, packagePath, '..', pkg.exports['.'].require);
22 | const packageESMPath = path.resolve(__dirname, packagePath, '..', pkg.exports['.'].import);
23 |
24 | const packageAPI = [
25 | '$name',
26 | '$isolated',
27 | 'cache',
28 | 'config',
29 | 'data',
30 | 'runtime',
31 | 'state',
32 | 'configDirs',
33 | 'dataDirs',
34 | ];
35 |
36 | function isObject(obj) {
37 | return Object.prototype.toString.call(obj) === '[object Object]';
38 | }
39 |
40 | function flattenToValues(obj) {
41 | const values = [];
42 | if (isObject(obj) || Array.isArray(obj)) {
43 | Object.keys(obj).forEach((key) => {
44 | // eslint-disable-next-line security/detect-object-injection
45 | values.push(...flattenToValues(obj[key]));
46 | });
47 | } else values.push(obj);
48 | return values;
49 | }
50 |
51 | if (!process.env.npm_config_test_dist) {
52 | test.skip('skipped (enable with `npm test --test-dist`)', () => void 0);
53 | } else {
54 | const testID$CJStoESM = 'CJS/ESM equivalence';
55 | if (vNodeJSMajor < 12) {
56 | test.skip(testID$CJStoESM + ' (requires Node-v12+)', () => void 0);
57 | } else {
58 | test(testID$CJStoESM, async (t) => {
59 | // eslint-disable-next-line security/detect-non-literal-require , security-node/detect-non-literal-require-calls
60 | const mCJS = require(packageCJSPath);
61 | const mESM = (await import('file://' + packageESMPath)).default;
62 |
63 | t.deepEqual(mCJS, mESM);
64 |
65 | t.is(typeof mCJS, 'function');
66 | t.is(typeof mCJS, typeof mESM);
67 | t.is(Object.keys(mCJS).length, packageAPI.length);
68 | t.is(Object.keys(mCJS).length, Object.keys(mESM).length);
69 | packageAPI.forEach((key) => {
70 | /* eslint-disable security/detect-object-injection */
71 | t.is(typeof mCJS[key], 'function');
72 | t.is(typeof mCJS[key], typeof mESM[key]);
73 | t.deepEqual(mCJS[key](), mESM[key]());
74 | /* eslint-enable security/detect-object-injection */
75 | });
76 | });
77 | }
78 |
79 | test("package 'exports' consistency", (t) => {
80 | /* eslint-disable security/detect-non-literal-fs-filename */
81 | t.is(pkg.main, pkg.exports['.'].require);
82 | t.is(pkg.module, pkg.exports['.'].import);
83 | t.is(pkg.types, pkg.exports['.'].types);
84 |
85 | t.true(fs.existsSync(pkg.exports['.'].require));
86 | t.true(fs.existsSync(pkg.exports['.'].import));
87 | t.true(fs.existsSync(pkg.exports['.'].types));
88 |
89 | t.is(pkg.main, pkg.exports['.'].default);
90 |
91 | if (pkg.exports['./cjs']) {
92 | const pathRequire = pkg.exports['./cjs'].require;
93 | t.is(pkg.exports['.'].require, pathRequire);
94 | // const extension = path.extname(pathRequire);
95 | // const basename = path.basename(pathRequire, extension);
96 | // const dirname = path.dirname(pathRequire);
97 | // t.is(pkg.exports['./cjs'].types, path.posix.join(dirname, basename) + '.d.ts');
98 | t.true(fs.existsSync(pkg.exports['./cjs'].require));
99 | }
100 |
101 | // 'types' default to the Deno/ESM/TypeScript variant
102 | if (pkg.exports['./esm']) {
103 | const pathImport = pkg.exports['./esm'].import;
104 | t.is(pkg.exports['.'].import, pathImport);
105 | t.is(pkg.exports['.'].types, path.pkg.exports['./esm'].types);
106 | t.true(fs.existsSync(pkg.exports['./esm'].require));
107 | }
108 | /* eslint-enable security/detect-non-literal-fs-filename */
109 | });
110 |
111 | test("package 'exports' all exist", (t) => {
112 | const exports_ = pkg.exports;
113 | const paths = flattenToValues(exports_);
114 | t.log({ exportsPaths: paths });
115 | paths.forEach((p) => {
116 | const path_ = path.resolve(__dirname, packagePath, '..', p);
117 | // eslint-disable-next-line security/detect-non-literal-fs-filename
118 | const exists = fs.existsSync(path_);
119 | if (!exists) {
120 | t.log({ path_, exists });
121 | }
122 | t.true(exists);
123 | });
124 | });
125 |
126 | test("package 'exports' sub-paths support older tools", (t) => {
127 | // confirm package files/directories exist which correspond to advertised exports sub-paths
128 | // [why]: older tools import/require based on package directory structure, not 'exports'
129 | const exports_ = pkg.exports;
130 | const subPaths = Object.keys(exports_);
131 | t.log({ subPaths });
132 | // test for sub-path file/directory existence
133 | subPaths.forEach((p) => {
134 | const path_ = path.resolve(__dirname, packagePath, '..', p);
135 | // eslint-disable-next-line security/detect-non-literal-fs-filename
136 | const exists = fs.existsSync(path_);
137 | if (!exists) {
138 | t.log({ exists, path_ });
139 | }
140 | t.true(exists);
141 | });
142 | const files = pkg.files;
143 | // test that sub-path file/directory is included in 'files'
144 | subPaths.forEach((p) => {
145 | const included = p === '.' || files.includes(p.replace(/^.\//, ''));
146 | if (!included) {
147 | t.log({ included, p, files });
148 | }
149 | t.true(included);
150 | });
151 | });
152 |
153 | test('package version has matching Git/VCS version tag', (t) => {
154 | t.log({ version: pkg.version });
155 |
156 | const result = require('child_process').spawnSync('git rev-list refs/tags/v' + pkg.version, {
157 | shell: true,
158 | encoding: 'utf-8',
159 | });
160 | t.is(result.status, 0);
161 | });
162 | }
163 |
--------------------------------------------------------------------------------
/test/fixtures/cli-display-name.cjs.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console , security-node/detect-crlf */
2 | /* eslint-env es6, node */
3 |
4 | const p = require('../../build/cjs/src/mod.cjs.js');
5 |
6 | console.log(p.$name());
7 |
--------------------------------------------------------------------------------
/test/fixtures/cli-display-name.esm-wrapper.mjs:
--------------------------------------------------------------------------------
1 | /* eslint-env es6, node */
2 | /* eslint-disable no-console , security-node/detect-crlf */
3 |
4 | import p from '../../build/cjs/src/esm-wrapper/mod.esm.js';
5 |
6 | console.log(p.$name());
7 | // console.warn({ process });
8 |
--------------------------------------------------------------------------------
/test/fixtures/cli-display-name.esm.mjs:
--------------------------------------------------------------------------------
1 | /* eslint-env es6, node */
2 | /* eslint-disable no-console , security-node/detect-crlf */
3 |
4 | import p from '../../build/esm/src/mod.esm.js';
5 |
6 | console.log(p.$name());
7 | // console.warn({ process });
8 |
--------------------------------------------------------------------------------
/test/fixtures/cli-display-name.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console , security-node/detect-crlf */
2 |
3 | // `ts-node` cannot import modules with extensions => use CJS module
4 | // ## maint: [2021-02-16; rivy] await resolution of to return to direct TS import
5 | // import p from '../../src/mod.esm.js';
6 | import p from '../../build/cjs/src/mod.cjs.js';
7 |
8 | console.log(p.$name());
9 |
--------------------------------------------------------------------------------
/test/fixtures/cli-display-name.umd.js:
--------------------------------------------------------------------------------
1 | /* eslint-env es6, node */
2 | /* eslint-disable no-console , security-node/detect-crlf */
3 |
4 | const p = require('../../build/umd/src/mod.cjs.js');
5 |
6 | console.log(p.$name());
7 |
--------------------------------------------------------------------------------
/test/integration.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env es6, node */
2 | /* eslint complexity: ['error', { max: 10 }] */ // set maximum cyclomatic complexity to 10; ref:
3 | /* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
4 |
5 | // spell-checker:ignore (names) Deno ; (vars) ESM ESMs vNodeJSMajor vNodeJSminor ; (words) cyclomatic
6 |
7 | 'use strict';
8 |
9 | const fs = require('fs');
10 | const path = require('path');
11 | const util = require('util');
12 |
13 | const test = require('ava');
14 | const commandExists = require('command-exists');
15 | const spawn = require('cross-spawn');
16 |
17 | const modulePath = '../build/lab/src/mod.cjs.js'; // ? change to package.main?
18 | const packagePath = '../package.json';
19 |
20 | // eslint-disable-next-line security-node/detect-non-literal-require-calls
21 | const mod = require(modulePath);
22 | // eslint-disable-next-line security-node/detect-non-literal-require-calls
23 | const pkg = require(packagePath);
24 |
25 | const haveDeno = commandExists.sync('deno');
26 | const denoVersion =
27 | /* `-T` (interpret as TypeScript; available v1.0+); used for older `deno` versions (< v1.16.2) which cache eval compilation incorrectly; ref: */
28 | ((
29 | spawn.sync('deno', ['eval', '-T', '"console.log(Deno.version.deno)"'], {
30 | encoding: 'utf-8',
31 | shell: true,
32 | }).stdout || ''
33 | ).match(/(?<=^|\s)\d+(?:[.]\d+)*/ /* eslint-disable-line security/detect-unsafe-regex */) || [
34 | '0.0.0',
35 | ])[0];
36 |
37 | function versionCompare(a, b) {
38 | return a.localeCompare(b, /* locales */ void 0, { numeric: true });
39 | }
40 |
41 | const vNodeJS = process.versions.node.split('.');
42 | const vNodeJSMajor = +vNodeJS[0];
43 | const vNodeJSminor = +vNodeJS[1];
44 |
45 | // removal of `--experimental-modules` flag gate for ESM
46 | // ref: [NodeJS-v12.17 changes]
47 | // ref: [NodeJS-v13.2 changes]
48 | const settledSupportForESMs =
49 | vNodeJSMajor > 13 ||
50 | (vNodeJSMajor === 13 && vNodeJSminor >= 2) ||
51 | (vNodeJSMajor === 12 && vNodeJSminor >= 17);
52 |
53 | // Integration tests
54 |
55 | test('api', (t) => {
56 | const api = [
57 | '$name',
58 | '$isolated',
59 | 'cache',
60 | 'config',
61 | 'data',
62 | 'runtime',
63 | 'state',
64 | 'configDirs',
65 | 'dataDirs',
66 | ];
67 |
68 | t.is(typeof mod, 'function');
69 | t.deepEqual(Object.keys(mod).sort(), api.sort());
70 | api.forEach((key) => {
71 | // eslint-disable-next-line security/detect-object-injection
72 | t.is(typeof mod[key], 'function');
73 | });
74 | });
75 |
76 | // ensure *no-panic* static load for Deno
77 | if (!process.env.npm_config_test_dist) {
78 | test.skip('module load test (Deno)...skipped (enable with `npm test --test-dist`)', () => void 0);
79 | } else {
80 | const minDenoVersion = '1.19.0';
81 | if (!haveDeno) {
82 | test.skip('module load tests (Deno)...skipped (`deno` not found)', () => void 0);
83 | } else if (versionCompare(denoVersion, minDenoVersion) < 0) {
84 | test.skip(`module load tests (Deno)...skipped (using Deno v${denoVersion} [v${minDenoVersion}+ needed for use of \`--no-prompt\`])`, () =>
85 | void 0);
86 | } else {
87 | test('module loads without panic (no permissions and `--no-prompt`; Deno)', (t) => {
88 | const denoModulePath = pkg.exports['.'].deno;
89 |
90 | const command = 'deno';
91 | const args = ['run', '--no-prompt', denoModulePath];
92 | const options = { shell: true, encoding: 'utf-8' };
93 |
94 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
95 |
96 | if (!(error === null && status === 0)) {
97 | t.log({ denoModulePath, error, status, stdout, stderr });
98 | }
99 |
100 | t.deepEqual({ error, status }, { error: null, status: 0 });
101 | });
102 | }
103 | }
104 |
105 | test('correctly derive script name (JavaScript)', (t) => {
106 | const fixtureDirPath = 'test/fixtures';
107 | const extensions = ['.js', '.cjs', '.mjs'];
108 |
109 | const files = fs.readdirSync(fixtureDirPath);
110 |
111 | files
112 | .filter((file) => {
113 | return extensions.includes(path.extname(file));
114 | })
115 | .forEach((file) => {
116 | if (settledSupportForESMs || path.extname(file) === '.js') {
117 | const command = 'node';
118 | const script = path.join(fixtureDirPath, file);
119 | const args = [script];
120 | const options = { shell: true, encoding: 'utf-8' };
121 |
122 | t.log({ script });
123 |
124 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
125 |
126 | t.log({ error, status, stdout, stderr });
127 |
128 | t.deepEqual({ error, status }, { error: null, status: 0 });
129 |
130 | t.is(stdout.toString().trim(), path.parse(script).name);
131 | }
132 | });
133 | });
134 |
135 | test('correctly derive script name (TypeScript)', (t) => {
136 | const fixtureDirPath = 'test/fixtures';
137 | const extensions = ['.js', '.cjs', '.mjs', '.ts'];
138 |
139 | const files = fs.readdirSync(fixtureDirPath);
140 |
141 | files
142 | .filter((file) => {
143 | const extension = path.extname(file);
144 | const name = path.basename(file, extension);
145 | const nameExtension = path.extname(name);
146 | const isDenoTS = extension === '.ts' && nameExtension === '.deno';
147 | return extensions.includes(extension) && !isDenoTS;
148 | })
149 | .forEach((file) => {
150 | if (settledSupportForESMs || path.extname(file) === '.js' || path.extname(file) === '.ts') {
151 | const command = 'node';
152 | const script = path.join(fixtureDirPath, file);
153 | const args = ['node_modules/ts-node/dist/bin.js', script];
154 | const options = { shell: true, encoding: 'utf8' };
155 |
156 | t.log({ script });
157 |
158 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
159 |
160 | t.log({ error, status, stdout, stderr });
161 |
162 | t.deepEqual({ error, status }, { error: null, status: 0 });
163 |
164 | t.is(stdout.toString().trim(), path.parse(script).name);
165 | }
166 | });
167 | });
168 |
169 | // test examples when using `--test-dist` (ie, with version changes or prior to distribution)
170 | if (!process.env.npm_config_test_dist) {
171 | test.skip('examples are executable...skipped (enable with `npm test --test-dist`)', () => void 0);
172 | } else {
173 | const minDenoVersion = '1.8.0';
174 | if (!haveDeno) {
175 | test.skip('examples are executable (Deno)...skipped (`deno` not found)', () => void 0);
176 | } else if (versionCompare(denoVersion, minDenoVersion) < 0) {
177 | test.skip(`examples are executable (Deno)...skipped (using Deno v${denoVersion} [v${minDenoVersion}+ needed for use of stable permissions API])`, () =>
178 | void 0);
179 | } else {
180 | test('examples are executable without error (Deno)', (t) => {
181 | // t.timeout(30000); // 30s timeout
182 |
183 | const egDirPath = 'eg';
184 | const extensionRxs = [/.*[.]deno[.]ts$/i];
185 |
186 | const files = fs.readdirSync(egDirPath);
187 |
188 | files
189 | .filter((file) => {
190 | return extensionRxs.find((re) => path.basename(file).match(re));
191 | })
192 | .forEach((file) => {
193 | const command = 'deno';
194 | const script = path.join(egDirPath, file);
195 | const args = ['run', '--allow-all', script];
196 | const options = { shell: true, encoding: 'utf-8' };
197 |
198 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
199 |
200 | if (error === null && status === 0) {
201 | t.log(
202 | util.inspect(script, /* showHidden */ void 0, /* depth */ void 0, /* color */ true),
203 | `(exit_status=${status})`
204 | );
205 | } else {
206 | t.log({ script, error, status, stdout, stderr });
207 | }
208 |
209 | t.deepEqual({ error, status }, { error: null, status: 0 });
210 | });
211 | });
212 | }
213 |
214 | test('examples are executable without error (JavaScript)', (t) => {
215 | // t.timeout(30000); // 30s timeout
216 |
217 | const egDirPath = 'eg';
218 | const extensions = ['.js', '.cjs', '.mjs'];
219 |
220 | const files = fs.readdirSync(egDirPath);
221 |
222 | files
223 | .filter((file) => {
224 | return extensions.includes(path.extname(file));
225 | })
226 | .forEach((file) => {
227 | if (settledSupportForESMs || path.extname(file) === '.js') {
228 | const command = 'node';
229 | const script = path.join(egDirPath, file);
230 | const args = [script];
231 | const options = { shell: true, encoding: 'utf-8' };
232 |
233 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
234 |
235 | if (error === null && status === 0) {
236 | t.log(
237 | util.inspect(script, /* showHidden */ void 0, /* depth */ void 0, /* color */ true),
238 | `(exit_status=${status})`
239 | );
240 | } else {
241 | t.log({ script, error, status, stdout, stderr });
242 | }
243 |
244 | t.deepEqual({ error, status }, { error: null, status: 0 });
245 | }
246 | });
247 | });
248 |
249 | test('examples are executable without error (TypeScript)', (t) => {
250 | // t.timeout(30000); // 30s timeout
251 |
252 | const egDirPath = 'eg';
253 | const extensions = ['.js', '.cjs', '.mjs', '.ts'];
254 |
255 | const files = fs.readdirSync(egDirPath);
256 |
257 | files
258 | .filter((file) => {
259 | const extension = path.extname(file);
260 | const name = path.basename(file, extension);
261 | const nameExtension = path.extname(name);
262 | const isDenoTS = extension === '.ts' && nameExtension === '.deno';
263 | return extensions.includes(extension) && !isDenoTS;
264 | })
265 | .forEach((file) => {
266 | if (settledSupportForESMs || path.extname(file) === '.js' || path.extname(file) === '.ts') {
267 | const command = 'node';
268 | const script = path.join(egDirPath, file);
269 | const args = ['node_modules/ts-node/dist/bin.js', script];
270 | const options = { shell: true, encoding: 'utf8' };
271 |
272 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
273 |
274 | const basename = path.basename(file);
275 | const extension = path.extname(file);
276 | const name = path.basename(file, extension);
277 | const nameExtension = path.extname(name);
278 |
279 | if (error === null && status === 0) {
280 | t.log(
281 | util.inspect(script, /* showHidden */ void 0, /* depth */ void 0, /* color */ true),
282 | `(exit_status=${status})`
283 | );
284 | } else {
285 | t.log({ script, basename, name, extension, nameExtension });
286 | t.log({ script, error, status, stdout, stderr });
287 | }
288 |
289 | t.deepEqual({ error, status }, { error: null, status: 0 });
290 | }
291 | });
292 | });
293 | }
294 |
--------------------------------------------------------------------------------
/test/types.test-d.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'tsd';
2 |
3 | import xdgAppPaths from '../src/mod.esm';
4 |
5 | expectType(xdgAppPaths);
6 | expectType(xdgAppPaths());
7 | expectType(new xdgAppPaths());
8 |
9 | expectType(xdgAppPaths('MyApp'));
10 | expectType(xdgAppPaths({ name: 'MyApp', suffix: '-nodejs', isolated: false }));
11 | expectType(new xdgAppPaths('MyApp'));
12 | expectType(
13 | new xdgAppPaths({ name: 'MyApp', suffix: '-nodejs', isolated: false })
14 | );
15 |
16 | const paths = xdgAppPaths('MyApp');
17 |
18 | expectType(paths);
19 |
20 | expectType(paths.$name());
21 | expectType(paths.$isolated());
22 |
23 | expectType(paths.cache());
24 | expectType(paths.cache(false));
25 | expectType(paths.cache({ isolated: true }));
26 | expectType(paths.config());
27 | expectType(paths.config(true));
28 | expectType(paths.config({ isolated: false }));
29 | expectType(paths.data());
30 | expectType(paths.data(false));
31 | expectType(paths.data({ isolated: true }));
32 | expectType(paths.runtime());
33 | expectType(paths.runtime(true));
34 | expectType(paths.runtime({ isolated: false }));
35 | expectType(paths.state());
36 | expectType(paths.state(false));
37 | expectType(paths.state({ isolated: true }));
38 | expectType(paths.configDirs());
39 | expectType(paths.configDirs(true));
40 | expectType(paths.configDirs({ isolated: false }));
41 | expectType(paths.dataDirs());
42 | expectType(paths.dataDirs(false));
43 | expectType(paths.dataDirs({ isolated: true }));
44 |
--------------------------------------------------------------------------------
/test/unit.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable functional/immutable-data , functional/no-loop-statement , security-node/non-literal-reg-expr , security/detect-non-literal-regexp , security/detect-object-injection */
2 | /* eslint-env es6, node */
3 | // spell-checker:ignore (vars) ESM ESMs vNodeJSMajor vNodeJSminor
4 | 'use strict';
5 |
6 | const path = require('path');
7 |
8 | const test = require('ava');
9 | const spawn = require('cross-spawn');
10 |
11 | const module_ = require('../build/lab/src/mod.cjs.js');
12 |
13 | const isWinOS = /^win/i.test(process.platform);
14 |
15 | function isDefined(value) {
16 | return typeOf(value) !== 'undefined';
17 | }
18 |
19 | function regexpEscape(s) {
20 | return s.replace(/\W/g, '\\$&');
21 | }
22 |
23 | function typeOf(value) {
24 | return typeof value;
25 | }
26 |
27 | function xdgPathRegex(name) {
28 | return new RegExp(
29 | '(^|' +
30 | regexpEscape(path.sep) +
31 | ')' +
32 | regexpEscape(name) +
33 | '(' +
34 | // for windows, `name` may be embedded within the generated paths (instead of always trailing as in MacOS/*nix)
35 | (isWinOS ? regexpEscape(path.sep) + '|' : '') +
36 | '$)'
37 | );
38 | }
39 |
40 | const vNodeJS = process.versions.node.split('.');
41 | const vNodeJSMajor = +vNodeJS[0];
42 | const vNodeJSminor = +vNodeJS[1];
43 |
44 | // removal of `--experimental-modules` flag gate for ESM
45 | // ref: [NodeJS-v12.17 changes]
46 | // ref: [NodeJS-v13.2 changes]
47 | const settledSupportForESMs =
48 | vNodeJSMajor > 13 ||
49 | (vNodeJSMajor === 13 && vNodeJSminor >= 2) ||
50 | (vNodeJSMajor === 12 && vNodeJSminor >= 17);
51 |
52 | // # Unit tests
53 |
54 | test('default', (t) => {
55 | const isolated = true;
56 | const paths = module_;
57 | const regex = xdgPathRegex(paths.$name());
58 |
59 | t.is(paths.$isolated(), isolated);
60 |
61 | Object.keys(paths).forEach((key) => {
62 | const value = paths[key];
63 | const values = [].concat(value()); // convert value (single value or array) to a flat array
64 | t.log(key, ':', value());
65 | values.forEach((v) => {
66 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
67 | t.regex(v, regex, `${key}:${v}`);
68 | t.deepEqual(value(), value({}));
69 | t.deepEqual(value(), value({ isolated: null }));
70 | t.deepEqual(value(), value(isolated));
71 | t.deepEqual(value(), value({ isolated }));
72 | t.notDeepEqual(value(), value(!isolated));
73 | t.notDeepEqual(value(), value({ isolated: !isolated }));
74 | }
75 | });
76 | });
77 | });
78 |
79 | test('alternate constructor (via function())', (t) => {
80 | const isolated = true;
81 | const paths = module_();
82 | const regex = xdgPathRegex(paths.$name());
83 |
84 | t.is(paths.$isolated(), isolated);
85 |
86 | Object.keys(paths).forEach((key) => {
87 | const value = paths[key];
88 | const values = [].concat(value()); // convert value (single value or array) to a flat array
89 | t.log(key, ':', value());
90 | values.forEach((v) => {
91 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
92 | t.regex(v, regex, `${key}:${v}`);
93 | t.deepEqual(value(), value({}));
94 | t.deepEqual(value(), value({ isolated: null }));
95 | t.deepEqual(value(), value(isolated));
96 | t.deepEqual(value(), value({ isolated }));
97 | t.notDeepEqual(value(), value(!isolated));
98 | t.notDeepEqual(value(), value({ isolated: !isolated }));
99 | }
100 | });
101 | });
102 | });
103 |
104 | test('alternate constructor (via function(...))', (t) => {
105 | const name = 'albacore';
106 | const isolated = true;
107 | const paths = module_(name);
108 | const regex = xdgPathRegex(paths.$name());
109 |
110 | t.is(paths.$name(), name);
111 | t.is(paths.$isolated(), isolated);
112 |
113 | Object.keys(paths).forEach((key) => {
114 | const value = paths[key];
115 | const values = [].concat(value()); // convert value (single value or array) to a flat array
116 | t.log(key, ':', value());
117 | values.forEach((v) => {
118 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
119 | t.regex(v, regex, `${key}:${v}`);
120 | t.deepEqual(value(), value({}));
121 | t.deepEqual(value(), value({ isolated: null }));
122 | t.deepEqual(value(), value(isolated));
123 | t.deepEqual(value(), value({ isolated }));
124 | t.notDeepEqual(value(), value(!isolated));
125 | t.notDeepEqual(value(), value({ isolated: !isolated }));
126 | }
127 | });
128 | });
129 | });
130 |
131 | test('alternate constructor (via new())', (t) => {
132 | const isolated = true;
133 | const paths = new module_(); // aka, `new module_(undefined)`
134 | const regex = xdgPathRegex(paths.$name());
135 |
136 | t.is(paths.$isolated(), isolated);
137 |
138 | Object.keys(paths).forEach((key) => {
139 | const value = paths[key];
140 | const values = [].concat(value()); // convert value (single value or array) to a flat array
141 | t.log(key, ':', value());
142 | values.forEach((v) => {
143 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
144 | t.regex(v, regex, `${key}:${v}`);
145 | t.deepEqual(value(), value({}));
146 | t.deepEqual(value(), value({ isolated: null }));
147 | t.deepEqual(value(), value(isolated));
148 | t.deepEqual(value(), value({ isolated }));
149 | t.notDeepEqual(value(), value(!isolated));
150 | t.notDeepEqual(value(), value({ isolated: !isolated }));
151 | }
152 | });
153 | });
154 | });
155 |
156 | test('alternate constructor (via new(...))', (t) => {
157 | const isolated = true;
158 | const name = 'behemoth';
159 | const paths = new module_(name);
160 | const regex = xdgPathRegex(paths.$name());
161 |
162 | t.is(paths.$name(), name);
163 | t.is(paths.$isolated(), isolated);
164 |
165 | Object.keys(paths).forEach((key) => {
166 | const value = paths[key];
167 | const values = [].concat(value()); // convert value (single value or array) to a flat array
168 | t.log(key, ':', value());
169 | values.forEach((v) => {
170 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
171 | t.regex(v, regex, `${key}:${v}`);
172 | t.deepEqual(value(), value({}));
173 | t.deepEqual(value(), value({ isolated: null }));
174 | t.deepEqual(value(), value(isolated));
175 | t.deepEqual(value(), value({ isolated }));
176 | t.notDeepEqual(value(), value(!isolated));
177 | t.notDeepEqual(value(), value({ isolated: !isolated }));
178 | }
179 | });
180 | });
181 | });
182 |
183 | test('construct without require.main.filename', (t) => {
184 | const isolated = true;
185 | const name = 'beholder';
186 |
187 | const priorRequireMainFilename = require.main.filename;
188 | require.main.filename = void 0;
189 |
190 | // eslint-disable-next-line functional/no-let
191 | let paths = new module_(name);
192 | const regex = xdgPathRegex(paths.$name());
193 |
194 | t.is(paths.$name(), name);
195 | t.is(paths.$isolated(), isolated);
196 |
197 | Object.keys(paths).forEach((key) => {
198 | const value = paths[key];
199 | const values = [].concat(value()); // convert value (single value or array) to a flat array
200 | t.log(key, ':', value());
201 | values.forEach((v) => {
202 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
203 | t.regex(v, regex, `${key}:${v}`);
204 | t.deepEqual(value(), value({}));
205 | t.deepEqual(value(), value({ isolated: null }));
206 | t.deepEqual(value(), value(isolated));
207 | t.deepEqual(value(), value({ isolated }));
208 | t.notDeepEqual(value(), value(!isolated));
209 | t.notDeepEqual(value(), value({ isolated: !isolated }));
210 | }
211 | });
212 | });
213 |
214 | require.main.filename = null;
215 |
216 | paths = new module_(name);
217 |
218 | t.is(paths.$name(), name);
219 | t.is(paths.$isolated(), isolated);
220 |
221 | Object.keys(paths).forEach((key) => {
222 | const value = paths[key];
223 | const values = [].concat(value()); // convert value (single value or array) to a flat array
224 | t.log(key, ':', value());
225 | values.forEach((v) => {
226 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
227 | t.regex(v, regex, `${key}:${v}`);
228 | t.deepEqual(value(), value(isolated));
229 | t.deepEqual(value(), value({ isolated }));
230 | t.notDeepEqual(value(), value(!isolated));
231 | t.notDeepEqual(value(), value({ isolated: !isolated }));
232 | }
233 | });
234 | });
235 |
236 | require.main.filename = priorRequireMainFilename;
237 | });
238 |
239 | test('chosen application name', (t) => {
240 | const isolated = true;
241 | const name = 'crux';
242 | const paths = module_(name);
243 | const regex = xdgPathRegex(name);
244 |
245 | t.is(paths.$name(), name);
246 | t.is(paths.$isolated(), isolated);
247 |
248 | Object.keys(paths).forEach((key) => {
249 | const value = paths[key];
250 | const values = [].concat(value()); // convert value (single value or array) to a flat array
251 | t.log(key, ':', value());
252 | values.forEach((v) => {
253 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
254 | t.regex(v, regex, `${key}:${v}`);
255 | t.deepEqual(value(), value({}));
256 | t.deepEqual(value(), value({ isolated: null }));
257 | t.deepEqual(value(), value(isolated));
258 | t.deepEqual(value(), value({ isolated }));
259 | t.notDeepEqual(value(), value(!isolated));
260 | t.notDeepEqual(value(), value({ isolated: !isolated }));
261 | }
262 | });
263 | });
264 | });
265 |
266 | test('chosen suffix', (t) => {
267 | const isolated = true;
268 | const suffix = '-nodejs';
269 | const paths = module_({ suffix });
270 | const regex = xdgPathRegex(paths.$name());
271 |
272 | t.is(paths.$isolated(), isolated);
273 |
274 | Object.keys(paths).forEach((key) => {
275 | const value = paths[key];
276 | const values = [].concat(value()); // convert value (single value or array) to a flat array
277 | t.log(key, ':', value());
278 | values.forEach((v) => {
279 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
280 | t.regex(v, regex, `${key}:${v}`);
281 | t.deepEqual(value(), value({}));
282 | t.deepEqual(value(), value({ isolated: null }));
283 | t.deepEqual(value(), value(isolated));
284 | t.deepEqual(value(), value({ isolated }));
285 | t.notDeepEqual(value(), value(!isolated));
286 | t.notDeepEqual(value(), value({ isolated: !isolated }));
287 | }
288 | });
289 | });
290 | });
291 |
292 | test('chosen application name + suffix', (t) => {
293 | const isolated = true;
294 | const name = 'debacle';
295 | const suffix = '-nodejs';
296 | const paths = module_({ name, suffix });
297 | const regex = xdgPathRegex(paths.$name());
298 |
299 | t.is(paths.$name(), name + suffix);
300 | t.is(paths.$isolated(), isolated);
301 |
302 | Object.keys(paths).forEach((key) => {
303 | const value = paths[key];
304 | const values = [].concat(value()); // convert value (single value or array) to a flat array
305 | t.log(key, ':', value());
306 | values.forEach((v) => {
307 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
308 | t.regex(v, regex, `${key}:${v}`);
309 | t.deepEqual(value(), value({}));
310 | t.deepEqual(value(), value({ isolated: null }));
311 | t.deepEqual(value(), value(isolated));
312 | t.deepEqual(value(), value({ isolated }));
313 | t.notDeepEqual(value(), value(!isolated));
314 | t.notDeepEqual(value(), value({ isolated: !isolated }));
315 | }
316 | });
317 | });
318 | });
319 |
320 | test('correct paths with only XDG_*_HOME set', (t) => {
321 | const envVars = {
322 | cache: 'XDG_CACHE_HOME',
323 | config: 'XDG_CONFIG_HOME',
324 | data: 'XDG_DATA_HOME',
325 | state: 'XDG_STATE_HOME',
326 | };
327 | delete process.env.XDG_CONFIG_DIRS;
328 | delete process.env.XDG_DATA_DIRS;
329 | Object.keys(envVars).forEach((key) => {
330 | const env = envVars[key];
331 | process.env[env] = path.join('.', env);
332 | });
333 |
334 | const isolated = true;
335 | const name = 'excalibur';
336 | const paths = module_(name);
337 | const regex = xdgPathRegex(paths.$name());
338 |
339 | t.is(paths.$name(), name);
340 | t.is(paths.$isolated(), isolated);
341 |
342 | Object.keys(paths).forEach((key) => {
343 | const value = paths[key];
344 | const values = [].concat(value()); // convert value (single value or array) to a flat array
345 | t.log(key, ':', value());
346 | values.forEach((v) => {
347 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
348 | t.regex(v, regex, `${key}:${v}`);
349 | t.deepEqual(value(), value({}));
350 | t.deepEqual(value(), value({ isolated: null }));
351 | t.deepEqual(value(), value(isolated));
352 | t.deepEqual(value(), value({ isolated }));
353 | t.notDeepEqual(value(), value(!isolated));
354 | t.notDeepEqual(value(), value({ isolated: !isolated }));
355 | }
356 | });
357 | });
358 |
359 | Object.keys(envVars).forEach((env) => {
360 | const expectedPath = path.join(process.env[envVars[env]], name);
361 | t.is(paths[env](), expectedPath);
362 | });
363 |
364 | const configDirs = paths.configDirs();
365 | t.is(configDirs.length, 1);
366 | t.is(configDirs[0], paths.config());
367 | t.deepEqual(paths.configDirs(isolated)[0], paths.config(isolated));
368 | t.deepEqual(paths.configDirs({ isolated })[0], paths.config({ isolated }));
369 | t.deepEqual(paths.configDirs(!isolated)[0], paths.config(!isolated));
370 | t.deepEqual(paths.configDirs({ isolated: !isolated })[0], paths.config({ isolated: !isolated }));
371 |
372 | const dataDirs = paths.dataDirs();
373 | t.is(dataDirs.length, 1);
374 | t.is(dataDirs[0], paths.data());
375 | t.deepEqual(paths.dataDirs(isolated)[0], paths.data(isolated));
376 | t.deepEqual(paths.dataDirs({ isolated })[0], paths.data({ isolated }));
377 | t.deepEqual(paths.dataDirs(!isolated)[0], paths.data(!isolated));
378 | t.deepEqual(paths.dataDirs({ isolated: !isolated })[0], paths.data({ isolated: !isolated }));
379 | });
380 |
381 | test('correct "isolated" paths with only XDG_*_HOME set', (t) => {
382 | const envVars = {
383 | cache: 'XDG_CACHE_HOME',
384 | config: 'XDG_CONFIG_HOME',
385 | data: 'XDG_DATA_HOME',
386 | state: 'XDG_STATE_HOME',
387 | };
388 | delete process.env.XDG_CONFIG_DIRS;
389 | delete process.env.XDG_DATA_DIRS;
390 | for (const key of Object.keys(envVars)) {
391 | const env = envVars[key];
392 | process.env[env] = path.join('.', env);
393 | }
394 |
395 | const name = 'foundling';
396 | const isolated = true;
397 | const paths = module_({ name, isolated });
398 | const regex = xdgPathRegex(paths.$name());
399 |
400 | t.is(paths.$name(), name);
401 | t.is(paths.$isolated(), isolated);
402 |
403 | Object.keys(paths).forEach((key) => {
404 | const value = paths[key];
405 | const values = [].concat(value()); // convert value (single value or array) to a flat array
406 | t.log(key, ':', value());
407 | values.forEach((v) => {
408 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
409 | t.regex(v, regex, `${key}:${v}`);
410 | t.deepEqual(value(), value({}));
411 | t.deepEqual(value(), value({ isolated: null }));
412 | t.deepEqual(value(), value(isolated));
413 | t.deepEqual(value(), value({ isolated }));
414 | t.notDeepEqual(value(), value(!isolated));
415 | t.notDeepEqual(value(), value({ isolated: !isolated }));
416 | }
417 | });
418 | });
419 |
420 | Object.keys(envVars).forEach((env) => {
421 | const expectedPath = path.join(process.env[envVars[env]], name);
422 | t.is(paths[env](), expectedPath);
423 | });
424 |
425 | const configDirs = paths.configDirs();
426 | t.is(configDirs.length, 1);
427 | t.is(configDirs[0], paths.config());
428 | t.deepEqual(paths.configDirs(isolated)[0], paths.config(isolated));
429 | t.deepEqual(paths.configDirs({ isolated })[0], paths.config({ isolated }));
430 | t.deepEqual(paths.configDirs(!isolated)[0], paths.config(!isolated));
431 | t.deepEqual(paths.configDirs({ isolated: !isolated })[0], paths.config({ isolated: !isolated }));
432 |
433 | const dataDirs = paths.dataDirs();
434 | t.is(dataDirs.length, 1);
435 | t.is(dataDirs[0], paths.data());
436 | t.deepEqual(paths.dataDirs(isolated)[0], paths.data(isolated));
437 | t.deepEqual(paths.dataDirs({ isolated })[0], paths.data({ isolated }));
438 | t.deepEqual(paths.dataDirs(!isolated)[0], paths.data(!isolated));
439 | t.deepEqual(paths.dataDirs({ isolated: !isolated })[0], paths.data({ isolated: !isolated }));
440 | });
441 |
442 | test('correct non-"isolated" paths with only XDG_*_HOME set', (t) => {
443 | const envVars = {
444 | cache: 'XDG_CACHE_HOME',
445 | config: 'XDG_CONFIG_HOME',
446 | data: 'XDG_DATA_HOME',
447 | state: 'XDG_STATE_HOME',
448 | };
449 | delete process.env.XDG_CONFIG_DIRS;
450 | delete process.env.XDG_DATA_DIRS;
451 | Object.keys(envVars).forEach((key) => {
452 | const env = envVars[key];
453 | process.env[env] = path.join('.', env);
454 | });
455 |
456 | const name = 'gremlins';
457 | const isolated = false;
458 | const paths = module_({ name, isolated });
459 |
460 | Object.keys(paths).forEach((key) => {
461 | const value = paths[key];
462 | t.log(key, ':', value());
463 | });
464 |
465 | t.is(paths.$name(), name);
466 | t.is(paths.$isolated(), isolated);
467 |
468 | Object.keys(envVars).forEach((env) => {
469 | const expectedPath = process.env[envVars[env]];
470 | t.is(paths[env](), expectedPath);
471 | });
472 |
473 | const configDirs = paths.configDirs();
474 | t.is(configDirs.length, 1);
475 | t.is(configDirs[0], paths.config());
476 | t.deepEqual(paths.configDirs(isolated)[0], paths.config(isolated));
477 | t.deepEqual(paths.configDirs({ isolated })[0], paths.config({ isolated }));
478 | t.deepEqual(paths.configDirs(!isolated)[0], paths.config(!isolated));
479 | t.deepEqual(paths.configDirs({ isolated: !isolated })[0], paths.config({ isolated: !isolated }));
480 |
481 | const dataDirs = paths.dataDirs();
482 | t.is(dataDirs.length, 1);
483 | t.is(dataDirs[0], paths.data());
484 | t.deepEqual(paths.dataDirs(isolated)[0], paths.data(isolated));
485 | t.deepEqual(paths.dataDirs({ isolated })[0], paths.data({ isolated }));
486 | t.deepEqual(paths.dataDirs(!isolated)[0], paths.data(!isolated));
487 | t.deepEqual(paths.dataDirs({ isolated: !isolated })[0], paths.data({ isolated: !isolated }));
488 | });
489 |
490 | test('correct paths with XDG_* set', (t) => {
491 | const envVars = {
492 | cache: 'XDG_CACHE_HOME',
493 | config: 'XDG_CONFIG_HOME',
494 | data: 'XDG_DATA_HOME',
495 | runtime: 'XDG_RUNTIME_DIR',
496 | state: 'XDG_STATE_HOME',
497 | configDirs: 'XDG_CONFIG_DIRS',
498 | dataDirs: 'XDG_DATA_DIRS',
499 | };
500 | Object.keys(envVars).forEach((key) => {
501 | const env = envVars[key];
502 | process.env[env] = path.join('.', env);
503 | });
504 |
505 | const isolated = true;
506 | const name = 'howling';
507 | const paths = module_(name);
508 | const regex = xdgPathRegex(paths.$name());
509 |
510 | t.is(paths.$name(), name);
511 | t.is(paths.$isolated(), isolated);
512 |
513 | Object.keys(paths).forEach((key) => {
514 | const value = paths[key];
515 | const values = [].concat(value()); // convert value (single value or array) to a flat array
516 | t.log(key, ':', value());
517 | values.forEach((v) => {
518 | if (!key.match(/^(\$.*)$/) && isDefined(v)) {
519 | t.regex(v, regex, `${key}:${v}`);
520 | t.deepEqual(value(), value({}));
521 | t.deepEqual(value(), value({ isolated: null }));
522 | t.deepEqual(value(), value(isolated));
523 | t.deepEqual(value(), value({ isolated }));
524 | t.notDeepEqual(value(), value(!isolated));
525 | t.notDeepEqual(value(), value({ isolated: !isolated }));
526 | }
527 | });
528 | });
529 |
530 | const configDirs = paths.configDirs();
531 | t.is(configDirs.length, 2);
532 | t.is(configDirs[0], paths.config());
533 | t.is(configDirs[1], path.join(envVars.configDirs, name));
534 | t.deepEqual(paths.configDirs(isolated)[0], paths.config(isolated));
535 | t.deepEqual(paths.configDirs({ isolated })[0], paths.config({ isolated }));
536 | t.deepEqual(paths.configDirs(!isolated)[0], paths.config(!isolated));
537 | t.deepEqual(paths.configDirs({ isolated: !isolated })[0], paths.config({ isolated: !isolated }));
538 | t.deepEqual(paths.configDirs(isolated)[1], path.join(envVars.configDirs, name));
539 | t.deepEqual(paths.configDirs({ isolated })[1], path.join(envVars.configDirs, name));
540 | t.notDeepEqual(paths.configDirs(!isolated)[1], path.join(envVars.configDirs, name));
541 | t.notDeepEqual(paths.configDirs({ isolated: !isolated })[1], path.join(envVars.configDirs, name));
542 |
543 | const dataDirs = paths.dataDirs();
544 | t.is(dataDirs.length, 2);
545 | t.is(dataDirs[0], paths.data());
546 | t.is(dataDirs[1], path.join(envVars.dataDirs, name));
547 | t.deepEqual(paths.dataDirs(isolated)[0], paths.data(isolated));
548 | t.deepEqual(paths.dataDirs({ isolated })[0], paths.data({ isolated }));
549 | t.deepEqual(paths.dataDirs(!isolated)[0], paths.data(!isolated));
550 | t.deepEqual(paths.dataDirs({ isolated: !isolated })[0], paths.data({ isolated: !isolated }));
551 | t.deepEqual(paths.dataDirs(isolated)[1], path.join(envVars.dataDirs, name));
552 | t.deepEqual(paths.dataDirs({ isolated })[1], path.join(envVars.dataDirs, name));
553 | t.notDeepEqual(paths.dataDirs(!isolated)[1], path.join(envVars.dataDirs, name));
554 | t.notDeepEqual(paths.dataDirs({ isolated: !isolated })[1], path.join(envVars.dataDirs, name));
555 | });
556 |
557 | test('correct "isolated" paths with XDG_* set', (t) => {
558 | const envVars = {
559 | cache: 'XDG_CACHE_HOME',
560 | config: 'XDG_CONFIG_HOME',
561 | data: 'XDG_DATA_HOME',
562 | runtime: 'XDG_RUNTIME_DIR',
563 | state: 'XDG_STATE_HOME',
564 | configDirs: 'XDG_CONFIG_DIRS',
565 | dataDirs: 'XDG_DATA_DIRS',
566 | };
567 | Object.keys(envVars).forEach((key) => {
568 | const env = envVars[key];
569 | process.env[env] = path.join('.', env);
570 | });
571 |
572 | const name = 'ignoble';
573 | const isolated = true;
574 | const paths = module_({ name, isolated });
575 | const regex = xdgPathRegex(paths.$name());
576 |
577 | t.is(paths.$name(), name);
578 | t.is(paths.$isolated(), isolated);
579 |
580 | Object.keys(paths).forEach((key) => {
581 | const value = paths[key];
582 | const values = [].concat(value()); // convert value (single value or array) to a flat array
583 | t.log(key, ':', value());
584 | values.forEach((v) => {
585 | if (!key.match(/^(\$.*)$/) && isDefined(v)) {
586 | t.regex(v, regex, `${key}:${v}`);
587 | t.deepEqual(value(), value({}));
588 | t.deepEqual(value(), value({ isolated: null }));
589 | t.deepEqual(value(), value(isolated));
590 | t.deepEqual(value(), value({ isolated }));
591 | t.notDeepEqual(value(), value(!isolated));
592 | t.notDeepEqual(value(), value({ isolated: !isolated }));
593 | }
594 | });
595 | });
596 |
597 | const configDirs = paths.configDirs();
598 | t.is(configDirs.length, 2);
599 | t.is(configDirs[0], paths.config());
600 | t.is(configDirs[1], path.join(envVars.configDirs, name));
601 | t.deepEqual(paths.configDirs(isolated)[0], paths.config(isolated));
602 | t.deepEqual(paths.configDirs({ isolated })[0], paths.config({ isolated }));
603 | t.deepEqual(paths.configDirs(!isolated)[0], paths.config(!isolated));
604 | t.deepEqual(paths.configDirs({ isolated: !isolated })[0], paths.config({ isolated: !isolated }));
605 | t.deepEqual(paths.configDirs(isolated)[1], path.join(envVars.configDirs, name));
606 | t.deepEqual(paths.configDirs({ isolated })[1], path.join(envVars.configDirs, name));
607 | t.notDeepEqual(paths.configDirs(!isolated)[1], path.join(envVars.configDirs, name));
608 | t.notDeepEqual(paths.configDirs({ isolated: !isolated })[1], path.join(envVars.configDirs, name));
609 |
610 | const dataDirs = paths.dataDirs();
611 | t.is(dataDirs.length, 2);
612 | t.is(dataDirs[0], paths.data());
613 | t.is(dataDirs[1], path.join(envVars.dataDirs, name));
614 | t.deepEqual(paths.dataDirs(isolated)[0], paths.data(isolated));
615 | t.deepEqual(paths.dataDirs({ isolated })[0], paths.data({ isolated }));
616 | t.deepEqual(paths.dataDirs(!isolated)[0], paths.data(!isolated));
617 | t.deepEqual(paths.dataDirs({ isolated: !isolated })[0], paths.data({ isolated: !isolated }));
618 | t.deepEqual(paths.dataDirs(isolated)[1], path.join(envVars.dataDirs, name));
619 | t.deepEqual(paths.dataDirs({ isolated })[1], path.join(envVars.dataDirs, name));
620 | t.notDeepEqual(paths.dataDirs(!isolated)[1], path.join(envVars.dataDirs, name));
621 | t.notDeepEqual(paths.dataDirs({ isolated: !isolated })[1], path.join(envVars.dataDirs, name));
622 | });
623 |
624 | test('correct non-"isolated" paths with XDG_* set', (t) => {
625 | const envVars = {
626 | cache: 'XDG_CACHE_HOME',
627 | config: 'XDG_CONFIG_HOME',
628 | data: 'XDG_DATA_HOME',
629 | runtime: 'XDG_RUNTIME_DIR',
630 | state: 'XDG_STATE_HOME',
631 | configDirs: 'XDG_CONFIG_DIRS',
632 | dataDirs: 'XDG_DATA_DIRS',
633 | };
634 | Object.keys(envVars).forEach((key) => {
635 | const env = envVars[key];
636 | process.env[env] = path.join('.', env);
637 | });
638 |
639 | const name = 'jackals';
640 | const isolated = false;
641 | const paths = module_({ name, isolated });
642 |
643 | t.is(paths.$name(), name);
644 | t.is(paths.$isolated(), isolated);
645 |
646 | Object.keys(paths).forEach((key) => {
647 | const value = paths[key];
648 | t.log(key, ':', value());
649 | });
650 |
651 | Object.keys(envVars).forEach((env) => {
652 | const expectedPath = process.env[envVars[env]];
653 | if (!env.endsWith('Dirs')) {
654 | t.is(paths[env](), expectedPath);
655 | }
656 | });
657 |
658 | const configDirs = paths.configDirs();
659 | t.is(configDirs.length, 2);
660 | t.is(configDirs[0], paths.config());
661 | t.is(configDirs[1], envVars.configDirs);
662 | t.deepEqual(paths.configDirs(isolated)[0], paths.config(isolated));
663 | t.deepEqual(paths.configDirs({ isolated })[0], paths.config({ isolated }));
664 | t.deepEqual(paths.configDirs(!isolated)[0], paths.config(!isolated));
665 | t.deepEqual(paths.configDirs({ isolated: !isolated })[0], paths.config({ isolated: !isolated }));
666 | t.deepEqual(paths.configDirs(isolated)[1], envVars.configDirs);
667 | t.deepEqual(paths.configDirs({ isolated })[1], envVars.configDirs);
668 | t.notDeepEqual(paths.configDirs(!isolated)[1], envVars.configDirs);
669 | t.notDeepEqual(paths.configDirs({ isolated: !isolated })[1], envVars.configDirs);
670 |
671 | const dataDirs = paths.dataDirs();
672 | t.is(dataDirs.length, 2);
673 | t.is(dataDirs[0], paths.data());
674 | t.is(dataDirs[1], envVars.dataDirs);
675 | t.deepEqual(paths.dataDirs(isolated)[0], paths.data(isolated));
676 | t.deepEqual(paths.dataDirs({ isolated })[0], paths.data({ isolated }));
677 | t.deepEqual(paths.dataDirs(!isolated)[0], paths.data(!isolated));
678 | t.deepEqual(paths.dataDirs({ isolated: !isolated })[0], paths.data({ isolated: !isolated }));
679 | t.deepEqual(paths.dataDirs(isolated)[1], envVars.dataDirs);
680 | t.deepEqual(paths.dataDirs({ isolated })[1], envVars.dataDirs);
681 | t.notDeepEqual(paths.dataDirs(!isolated)[1], envVars.dataDirs);
682 | t.notDeepEqual(paths.dataDirs({ isolated: !isolated })[1], envVars.dataDirs);
683 | });
684 |
685 | test('correctly derive anonymous (CJS)', (t) => {
686 | const command = 'node';
687 | process.env.TEST_MODULE_PATH = './build/lab/src/mod.cjs.js';
688 | const script =
689 | '"p = require(\'' + process.env.TEST_MODULE_PATH + '\'); console.log(p.$name({}));"';
690 | const args = ['-e', isWinOS ? script : script.replace('$name', '\\$name')];
691 | const options = { shell: true, encoding: 'utf-8' };
692 |
693 | t.log({ script });
694 |
695 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
696 |
697 | t.log({ error, status, stdout, stderr });
698 |
699 | t.deepEqual({ error, status }, { error: null, status: 0 });
700 |
701 | t.is(stdout.toString().trim(), '$eval');
702 | });
703 |
704 | if (settledSupportForESMs) {
705 | test('correctly derive anonymous (ESM/[import CJS])', (t) => {
706 | const command = 'node';
707 | process.env.TEST_MODULE_PATH = './build/lab/src/mod.cjs.js';
708 | const script =
709 | '"import p from \'' + process.env.TEST_MODULE_PATH + '\'; console.log(p.$name({}));"';
710 | const args = [
711 | '--input-type=module',
712 | '-e',
713 | isWinOS ? script : script.replace('$name', '\\$name'),
714 | ];
715 | const options = { shell: true, encoding: 'utf-8' };
716 |
717 | t.log({ script });
718 |
719 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
720 |
721 | t.log({ error, status, stdout, stderr });
722 |
723 | t.deepEqual({ error, status }, { error: null, status: 0 });
724 |
725 | t.is(stdout.toString().trim(), '$eval');
726 | });
727 |
728 | test('correctly derive anonymous (ESM/[esm-wrapper])', (t) => {
729 | const command = 'node';
730 | process.env.TEST_MODULE_PATH = './build/lab/src/esm-wrapper/mod.esm.js';
731 | const script =
732 | '"import p from \'' + process.env.TEST_MODULE_PATH + '\'; console.log(p.$name({}));"';
733 | const args = [
734 | '--input-type=module',
735 | '-e',
736 | isWinOS ? script : script.replace('$name', '\\$name'),
737 | ];
738 | const options = { shell: true, encoding: 'utf-8' };
739 |
740 | t.log({ script });
741 |
742 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
743 |
744 | t.log({ error, status, stdout, stderr });
745 |
746 | t.deepEqual({ error, status }, { error: null, status: 0 });
747 |
748 | t.is(stdout.toString().trim(), '$eval');
749 | });
750 |
751 | test('correctly derive anonymous (ESM)', (t) => {
752 | const command = 'node';
753 | process.env.TEST_MODULE_PATH = './build/esm/src/mod.esm.js';
754 | const script =
755 | '"import p from \'' + process.env.TEST_MODULE_PATH + '\'; console.log(p.$name({}));"';
756 | const args = [
757 | '--input-type=module',
758 | '-e',
759 | isWinOS ? script : script.replace('$name', '\\$name'),
760 | ];
761 | const options = { shell: true, encoding: 'utf-8' };
762 |
763 | t.log({ script });
764 |
765 | const { error, status, stdout, stderr } = spawn.sync(command, args, options);
766 |
767 | t.log({ error, status, stdout, stderr });
768 |
769 | t.deepEqual({ error, status }, { error: null, status: 0 });
770 |
771 | t.is(stdout.toString().trim(), '$eval');
772 | });
773 | }
774 |
775 | test('construct with "pkg" packaged application', (t) => {
776 | const isolated = true;
777 |
778 | const priorProcessPkg = process.pkg;
779 | process.pkg = {};
780 |
781 | const paths = new module_();
782 | const regex = xdgPathRegex(paths.$name());
783 |
784 | t.is(paths.$name(), path.parse(process.execPath).name);
785 | t.is(paths.$isolated(), isolated);
786 |
787 | Object.keys(paths).forEach((key) => {
788 | const value = paths[key];
789 | const values = [].concat(value()); // convert value (single value or array) to a flat array
790 | t.log(key, ':', value());
791 | values.forEach((v) => {
792 | if (!key.match(/^((\$.*)|runtime)$/) && isDefined(v)) {
793 | t.regex(v, regex, `${key}:${v}`);
794 | t.deepEqual(value(), value({}));
795 | t.deepEqual(value(), value({ isolated: null }));
796 | t.deepEqual(value(), value(isolated));
797 | t.deepEqual(value(), value({ isolated }));
798 | t.notDeepEqual(value(), value(!isolated));
799 | t.notDeepEqual(value(), value({ isolated: !isolated }));
800 | }
801 | });
802 | });
803 |
804 | process.pkg = priorProcessPkg;
805 | });
806 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "incremental": false,
4 | "target": "es3",
5 | "outDir": "build/cjs",
6 | // "rootDir": "src", // interferes with `tsd`; see ; disabling builds exactly the same files/structure except placing *.tsbuildinfo files into the respective subdirectories
7 | "moduleResolution": "node",
8 | "module": "CommonJS",
9 | "newLine": "lf",
10 | "declaration": true /* Enables automatic generation of type declarations */,
11 | "inlineSourceMap": true,
12 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
13 | "resolveJsonModule": true /* Include modules imported with .json extension.; note: UMD generation requires 'false' */,
14 |
15 | "strict": true /* Enable all strict type-checking options. */,
16 |
17 | /* Strict Type-Checking Options */
18 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
19 | // "strictNullChecks": true /* Enable strict null checks. */,
20 | // "strictFunctionTypes": true /* Enable strict checking of function types. */,
21 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
22 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
23 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
24 |
25 | /* Additional Checks */
26 | "noUnusedLocals": true /* Report errors on unused locals. */,
27 | "noUnusedParameters": true /* Report errors on unused parameters. */,
28 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
29 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
30 |
31 | /* Debugging Options */
32 | "traceResolution": false /* Report module resolution log messages. */,
33 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */,
34 | "listFiles": false /* Print names of files part of the compilation. */,
35 | "pretty": true /* Stylize errors and messages using color and context. */,
36 |
37 | /* Experimental Options */
38 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
39 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
40 |
41 | "types": ["node"],
42 | "typeRoots": ["node_modules/@types", "src/types", "dist/types", "vendor/types"],
43 |
44 | "allowJs": true,
45 | "noEmit": true,
46 | "isolatedModules": true /* Enables warnings for code which may be interpreted incorrectly by single-file transpilation tools */,
47 |
48 | "removeComments": true
49 | },
50 | "include": ["src/**/*", "eg/**/*", "test/**/*"],
51 | "exclude": ["src/esm-wrapper/**", "node_modules/**"],
52 | "compileOnSave": false
53 | }
54 |
--------------------------------------------------------------------------------
/tsconfig/tsconfig.cjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../build/cjs",
5 | "rootDir": "..",
6 | "declaration": false, // generate side-by-side type declarations
7 | "module": "CommonJS",
8 | "noEmit": false
9 | },
10 | "exclude": [
11 | "../eg/**",
12 | "../src/esm-wrapper/**",
13 | "../src/**/*.deno.ts",
14 | "../src/**/*.esm.ts",
15 | "../src/**/*.spec.*",
16 | "../src/**/*.test.*",
17 | "../test/**",
18 | "../node_modules/**"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/tsconfig/tsconfig.eslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true
5 | },
6 | "include": ["../**/*"],
7 | "exclude": ["../dist/**"]
8 | }
9 |
--------------------------------------------------------------------------------
/tsconfig/tsconfig.esm.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../build/esm",
5 | "rootDir": "..",
6 | "declaration": false, // generate side-by-side type declarations
7 | "module": "es2015",
8 | "noEmit": false
9 | },
10 | "exclude": [
11 | "../eg/**",
12 | "../src/esm-wrapper/**",
13 | "../src/**/*.cjs.ts",
14 | "../src/**/*.deno.ts",
15 | "../src/**/*.spec.*",
16 | "../src/**/*.test.*",
17 | "../test/**",
18 | "../node_modules/**"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/tsconfig/tsconfig.lab.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../build/lab",
5 | "rootDir": "..",
6 | "declaration": true, // generate side-by-side type declarations
7 | "module": "CommonJS",
8 | "noEmit": false,
9 | "removeComments": false
10 | },
11 | "exclude": [
12 | "../eg/**",
13 | "../src/esm-wrapper/**",
14 | "../src/**/*.deno.ts",
15 | "../test/**/*.js",
16 | "../test/**/*.test-d.ts",
17 | "../test/fixtures/**/*",
18 | "../node_modules/**"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/tsconfig/tsconfig.types.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | // generate (only) type declaration files to 'build/types'
5 | "outDir": "../build/types",
6 | "rootDir": "..",
7 | "declaration": true, // generate type declarations
8 | "emitDeclarationOnly": true,
9 | "noEmit": false,
10 | "removeComments": false
11 | },
12 | "exclude": [
13 | "../eg/**",
14 | "../src/esm-wrapper/**",
15 | "../src/**/*.deno.ts",
16 | "../src/**/*.spec.*",
17 | "../src/**/*.test.*",
18 | "../test/**",
19 | "../node_modules/**"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/tsconfig/tsconfig.umd.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../build/umd",
5 | "rootDir": "..",
6 | "declaration": false, // generate side-by-side type declarations
7 | "module": "UMD",
8 | "noEmit": false,
9 | "resolveJsonModule": false /* Include modules imported with .json extension.; UMD generation requires 'false' */
10 | },
11 | "exclude": [
12 | "../eg/**",
13 | "../src/esm-wrapper/**",
14 | "../src/**/*.deno.ts",
15 | "../src/**/*.esm.ts",
16 | "../src/**/*.spec.*",
17 | "../src/**/*.test.*",
18 | "../test/**",
19 | "../node_modules/**"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/.gitattributes:
--------------------------------------------------------------------------------
1 | # treat third-party code/tools directory as binary by default
2 | # * note: use `git diff --text ...` to override and show differences as text
3 | * binary
4 | .gitattributes !binary
5 |
--------------------------------------------------------------------------------