plugin-build-guide-block 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client-v2.d.ts +2 -0
- package/client-v2.js +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client-v2/73.6b8b2eda7d969c69.js +10 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/externalVersion.js +9 -8
- package/dist/node_modules/sanitize-html/index.js +2 -2
- package/dist/node_modules/sanitize-html/package.json +1 -1
- package/dist/server/actions/build.js +5 -2
- package/package.json +8 -4
- package/src/client-v2/index.tsx +1 -0
- package/src/client-v2/plugin.tsx +24 -0
- package/src/server/actions/build.ts +6 -2
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.browser.cjs +0 -34
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.browser.js +0 -34
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.cjs +0 -35
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.d.ts +0 -56
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.js +0 -35
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.native.js +0 -26
- package/dist/node_modules/sanitize-html/node_modules/nanoid/async/package.json +0 -12
- package/dist/node_modules/sanitize-html/node_modules/nanoid/bin/nanoid.cjs +0 -55
- package/dist/node_modules/sanitize-html/node_modules/nanoid/index.browser.cjs +0 -34
- package/dist/node_modules/sanitize-html/node_modules/nanoid/index.browser.js +0 -34
- package/dist/node_modules/sanitize-html/node_modules/nanoid/index.cjs +0 -45
- package/dist/node_modules/sanitize-html/node_modules/nanoid/index.d.cts +0 -91
- package/dist/node_modules/sanitize-html/node_modules/nanoid/index.d.ts +0 -91
- package/dist/node_modules/sanitize-html/node_modules/nanoid/index.js +0 -45
- package/dist/node_modules/sanitize-html/node_modules/nanoid/nanoid.js +0 -1
- package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.cjs +0 -21
- package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.d.ts +0 -33
- package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.js +0 -21
- package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/package.json +0 -6
- package/dist/node_modules/sanitize-html/node_modules/nanoid/package.json +0 -88
- package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/index.cjs +0 -3
- package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/index.js +0 -3
- package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/package.json +0 -6
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/at-rule.d.ts +0 -115
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/at-rule.js +0 -25
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/comment.d.ts +0 -67
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/comment.js +0 -13
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/container.d.ts +0 -452
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/container.js +0 -439
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.d.ts +0 -248
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.js +0 -100
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/declaration.d.ts +0 -148
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/declaration.js +0 -24
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/document.d.ts +0 -68
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/document.js +0 -33
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.d.ts +0 -9
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.js +0 -54
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/input.d.ts +0 -194
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/input.js +0 -248
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.d.ts +0 -190
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.js +0 -550
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/list.d.ts +0 -57
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/list.js +0 -58
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/map-generator.js +0 -359
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.d.ts +0 -46
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.js +0 -135
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/node.d.ts +0 -536
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/node.js +0 -381
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parse.d.ts +0 -9
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parse.js +0 -42
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parser.js +0 -610
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.d.mts +0 -72
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.d.ts +0 -441
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.js +0 -101
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/previous-map.d.ts +0 -81
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/previous-map.js +0 -142
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/processor.d.ts +0 -115
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/processor.js +0 -67
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/result.d.ts +0 -206
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/result.js +0 -42
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/root.d.ts +0 -86
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/root.js +0 -61
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/rule.d.ts +0 -113
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/rule.js +0 -27
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringifier.d.ts +0 -46
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringifier.js +0 -353
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringify.d.ts +0 -9
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringify.js +0 -11
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/symbols.js +0 -5
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/terminal-highlight.js +0 -70
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/tokenize.js +0 -266
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warn-once.js +0 -13
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warning.d.ts +0 -147
- package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warning.js +0 -37
- package/dist/node_modules/sanitize-html/node_modules/postcss/node_modules/.bin/nanoid +0 -15
- package/dist/node_modules/sanitize-html/node_modules/postcss/node_modules/.bin/nanoid.cmd +0 -7
- package/dist/node_modules/sanitize-html/node_modules/postcss/package.json +0 -88
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"sanitize-html","version":"2.17.
|
|
1
|
+
{"name":"sanitize-html","version":"2.17.5","description":"Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis","sideEffects":false,"main":"index.js","files":["index.js"],"repository":{"type":"git","url":"https://github.com/apostrophecms/apostrophe.git","directory":"packages/sanitize-html"},"homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packages/sanitize-html#readme","keywords":["html","parser","sanitizer","sanitize"],"author":"Apostrophe Technologies, Inc.","license":"MIT","dependencies":{"deepmerge":"^4.2.2","escape-string-regexp":"^4.0.0","htmlparser2":"^10.1.0","is-plain-object":"^5.0.0","parse-srcset":"^1.0.2","postcss":"^8.3.11","launder":"^1.7.1"},"devDependencies":{"eslint":"^9.39.1","mocha":"^11.7.5","sinon":"^9.0.2","eslint-config-apostrophe":"^6.0.2"},"apostropheTestConfig":{"requiresMongo":false},"scripts":{"test":"npm run lint && mocha","lint":"eslint ."},"_lastModified":"2026-06-17T05:00:41.121Z"}
|
|
@@ -316,6 +316,9 @@ function toPlainText(value) {
|
|
|
316
316
|
}
|
|
317
317
|
return JSON.stringify(value);
|
|
318
318
|
}
|
|
319
|
+
function stripThink(text) {
|
|
320
|
+
return text.replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, "").trim();
|
|
321
|
+
}
|
|
319
322
|
function stripFence(text) {
|
|
320
323
|
return text.replace(/^```(?:json|markdown|md|html)?\s*/i, "").replace(/```\s*$/i, "").trim();
|
|
321
324
|
}
|
|
@@ -374,7 +377,7 @@ function createFallbackPlan(guideTitle, targetChapterCount) {
|
|
|
374
377
|
}
|
|
375
378
|
function normalizePlan(rawText, guideTitle, targetChapterCount) {
|
|
376
379
|
const targetCount = clampChapterCount(targetChapterCount);
|
|
377
|
-
const cleanText = stripFence(rawText);
|
|
380
|
+
const cleanText = stripFence(stripThink(rawText));
|
|
378
381
|
const jsonStart = cleanText.indexOf("{");
|
|
379
382
|
const jsonEnd = cleanText.lastIndexOf("}");
|
|
380
383
|
const jsonText = jsonStart >= 0 && jsonEnd > jsonStart ? cleanText.slice(jsonStart, jsonEnd + 1) : cleanText;
|
|
@@ -479,7 +482,7 @@ Source documents:
|
|
|
479
482
|
${documentsText.slice(0, MAX_SOURCE_CHARS)}`)
|
|
480
483
|
);
|
|
481
484
|
const response = await provider.chatModel.invoke(messages);
|
|
482
|
-
return stripFence(toPlainText(response.content));
|
|
485
|
+
return stripFence(stripThink(toPlainText(response.content)));
|
|
483
486
|
}
|
|
484
487
|
async function markdownToCleanHtml(markdown) {
|
|
485
488
|
const renderedHtml = await import_marked.marked.parse(markdown, { async: true });
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"displayName.zh-CN": "构建指南区块",
|
|
6
6
|
"description": "Generate user guides, tutorials and help books from documents using AI, then render the result as a block (HTML or Markdown).",
|
|
7
7
|
"description.vi-VN": "Tạo hướng dẫn người dùng, tutorial và help book từ tài liệu bằng AI, hiển thị kết quả dưới dạng block (HTML hoặc Markdown).",
|
|
8
|
-
"version": "1.1.
|
|
8
|
+
"version": "1.1.7",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"client.js",
|
|
22
22
|
"server.js",
|
|
23
23
|
"client.d.ts",
|
|
24
|
-
"server.d.ts"
|
|
24
|
+
"server.d.ts",
|
|
25
|
+
"client-v2.js",
|
|
26
|
+
"client-v2.d.ts"
|
|
25
27
|
],
|
|
26
28
|
"dependencies": {
|
|
27
29
|
"dompurify": "^3.1.2",
|
|
@@ -40,7 +42,9 @@
|
|
|
40
42
|
"@nocobase/plugin-ai": "2.x",
|
|
41
43
|
"@nocobase/plugin-file-manager": "2.x",
|
|
42
44
|
"@langchain/core": "*",
|
|
43
|
-
"axios": "*"
|
|
45
|
+
"axios": "*",
|
|
46
|
+
"@nocobase/client-v2": "2.x",
|
|
47
|
+
"@nocobase/flow-engine": "2.x"
|
|
44
48
|
},
|
|
45
49
|
"nocobase": {
|
|
46
50
|
"supportedVersions": [
|
|
@@ -48,4 +52,4 @@
|
|
|
48
52
|
],
|
|
49
53
|
"editionLevel": 0
|
|
50
54
|
}
|
|
51
|
-
}
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './plugin';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Plugin, Application } from '@nocobase/client-v2';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
export class PluginBuildGuideBlockClient extends Plugin<Record<string, never>, Application> {
|
|
5
|
+
async load() {
|
|
6
|
+
this.pluginSettingsManager.addMenuItem({
|
|
7
|
+
key: 'ai-build-guide',
|
|
8
|
+
title: this.t('Build Guide Block'),
|
|
9
|
+
icon: 'ReadOutlined',
|
|
10
|
+
aclSnippet: 'pm.ai-build-guide',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
this.pluginSettingsManager.addPageTabItem({
|
|
14
|
+
menuKey: 'ai-build-guide',
|
|
15
|
+
key: 'index',
|
|
16
|
+
title: this.t('Build Guide Block'),
|
|
17
|
+
|
|
18
|
+
componentLoader: () => import('../client/UserGuideManager').then(m => ({ default: m.UserGuideManager })),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default PluginBuildGuideBlockClient;
|
|
@@ -328,6 +328,10 @@ function toPlainText(value: unknown) {
|
|
|
328
328
|
return JSON.stringify(value);
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
+
function stripThink(text: string) {
|
|
332
|
+
return text.replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, '').trim();
|
|
333
|
+
}
|
|
334
|
+
|
|
331
335
|
function stripFence(text: string) {
|
|
332
336
|
return text
|
|
333
337
|
.replace(/^```(?:json|markdown|md|html)?\s*/i, '')
|
|
@@ -398,7 +402,7 @@ function createFallbackPlan(guideTitle: string, targetChapterCount: number): Gui
|
|
|
398
402
|
|
|
399
403
|
function normalizePlan(rawText: string, guideTitle: string, targetChapterCount: number): GuidePlan {
|
|
400
404
|
const targetCount = clampChapterCount(targetChapterCount);
|
|
401
|
-
const cleanText = stripFence(rawText);
|
|
405
|
+
const cleanText = stripFence(stripThink(rawText));
|
|
402
406
|
const jsonStart = cleanText.indexOf('{');
|
|
403
407
|
const jsonEnd = cleanText.lastIndexOf('}');
|
|
404
408
|
const jsonText = jsonStart >= 0 && jsonEnd > jsonStart ? cleanText.slice(jsonStart, jsonEnd + 1) : cleanText;
|
|
@@ -514,7 +518,7 @@ Source documents:
|
|
|
514
518
|
${documentsText.slice(0, MAX_SOURCE_CHARS)}`),
|
|
515
519
|
);
|
|
516
520
|
const response = await provider.chatModel.invoke(messages);
|
|
517
|
-
return stripFence(toPlainText(response.content));
|
|
521
|
+
return stripFence(stripThink(toPlainText(response.content)));
|
|
518
522
|
}
|
|
519
523
|
|
|
520
524
|
async function markdownToCleanHtml(markdown: string) {
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes))
|
|
2
|
-
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
3
|
-
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
|
|
4
|
-
let step = -~((1.6 * mask * defaultSize) / alphabet.length)
|
|
5
|
-
return async (size = defaultSize) => {
|
|
6
|
-
let id = ''
|
|
7
|
-
while (true) {
|
|
8
|
-
let bytes = crypto.getRandomValues(new Uint8Array(step))
|
|
9
|
-
let i = step
|
|
10
|
-
while (i--) {
|
|
11
|
-
id += alphabet[bytes[i] & mask] || ''
|
|
12
|
-
if (id.length === size) return id
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
let nanoid = async (size = 21) => {
|
|
18
|
-
let id = ''
|
|
19
|
-
let bytes = crypto.getRandomValues(new Uint8Array(size))
|
|
20
|
-
while (size--) {
|
|
21
|
-
let byte = bytes[size] & 63
|
|
22
|
-
if (byte < 36) {
|
|
23
|
-
id += byte.toString(36)
|
|
24
|
-
} else if (byte < 62) {
|
|
25
|
-
id += (byte - 26).toString(36).toUpperCase()
|
|
26
|
-
} else if (byte < 63) {
|
|
27
|
-
id += '_'
|
|
28
|
-
} else {
|
|
29
|
-
id += '-'
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return id
|
|
33
|
-
}
|
|
34
|
-
module.exports = { nanoid, customAlphabet, random }
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
let random = async bytes => crypto.getRandomValues(new Uint8Array(bytes))
|
|
2
|
-
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
3
|
-
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
|
|
4
|
-
let step = -~((1.6 * mask * defaultSize) / alphabet.length)
|
|
5
|
-
return async (size = defaultSize) => {
|
|
6
|
-
let id = ''
|
|
7
|
-
while (true) {
|
|
8
|
-
let bytes = crypto.getRandomValues(new Uint8Array(step))
|
|
9
|
-
let i = step
|
|
10
|
-
while (i--) {
|
|
11
|
-
id += alphabet[bytes[i] & mask] || ''
|
|
12
|
-
if (id.length === size) return id
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
let nanoid = async (size = 21) => {
|
|
18
|
-
let id = ''
|
|
19
|
-
let bytes = crypto.getRandomValues(new Uint8Array(size))
|
|
20
|
-
while (size--) {
|
|
21
|
-
let byte = bytes[size] & 63
|
|
22
|
-
if (byte < 36) {
|
|
23
|
-
id += byte.toString(36)
|
|
24
|
-
} else if (byte < 62) {
|
|
25
|
-
id += (byte - 26).toString(36).toUpperCase()
|
|
26
|
-
} else if (byte < 63) {
|
|
27
|
-
id += '_'
|
|
28
|
-
} else {
|
|
29
|
-
id += '-'
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return id
|
|
33
|
-
}
|
|
34
|
-
export { nanoid, customAlphabet, random }
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
let crypto = require('crypto')
|
|
2
|
-
let { urlAlphabet } = require('../url-alphabet/index.cjs')
|
|
3
|
-
let random = bytes =>
|
|
4
|
-
new Promise((resolve, reject) => {
|
|
5
|
-
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
|
|
6
|
-
if (err) {
|
|
7
|
-
reject(err)
|
|
8
|
-
} else {
|
|
9
|
-
resolve(buf)
|
|
10
|
-
}
|
|
11
|
-
})
|
|
12
|
-
})
|
|
13
|
-
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
14
|
-
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
|
15
|
-
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
|
16
|
-
let tick = (id, size = defaultSize) =>
|
|
17
|
-
random(step).then(bytes => {
|
|
18
|
-
let i = step
|
|
19
|
-
while (i--) {
|
|
20
|
-
id += alphabet[bytes[i] & mask] || ''
|
|
21
|
-
if (id.length === size) return id
|
|
22
|
-
}
|
|
23
|
-
return tick(id, size)
|
|
24
|
-
})
|
|
25
|
-
return size => tick('', size)
|
|
26
|
-
}
|
|
27
|
-
let nanoid = (size = 21) =>
|
|
28
|
-
random(size).then(bytes => {
|
|
29
|
-
let id = ''
|
|
30
|
-
while (size--) {
|
|
31
|
-
id += urlAlphabet[bytes[size] & 63]
|
|
32
|
-
}
|
|
33
|
-
return id
|
|
34
|
-
})
|
|
35
|
-
module.exports = { nanoid, customAlphabet, random }
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate secure URL-friendly unique ID. The non-blocking version.
|
|
3
|
-
*
|
|
4
|
-
* By default, the ID will have 21 symbols to have a collision probability
|
|
5
|
-
* similar to UUID v4.
|
|
6
|
-
*
|
|
7
|
-
* ```js
|
|
8
|
-
* import { nanoid } from 'nanoid/async'
|
|
9
|
-
* nanoid().then(id => {
|
|
10
|
-
* model.id = id
|
|
11
|
-
* })
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* @param size Size of the ID. The default size is 21.
|
|
15
|
-
* @returns A promise with a random string.
|
|
16
|
-
*/
|
|
17
|
-
export function nanoid(size?: number): Promise<string>
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* A low-level function.
|
|
21
|
-
* Generate secure unique ID with custom alphabet. The non-blocking version.
|
|
22
|
-
*
|
|
23
|
-
* Alphabet must contain 256 symbols or less. Otherwise, the generator
|
|
24
|
-
* will not be secure.
|
|
25
|
-
*
|
|
26
|
-
* @param alphabet Alphabet used to generate the ID.
|
|
27
|
-
* @param defaultSize Size of the ID. The default size is 21.
|
|
28
|
-
* @returns A function that returns a promise with a random string.
|
|
29
|
-
*
|
|
30
|
-
* ```js
|
|
31
|
-
* import { customAlphabet } from 'nanoid/async'
|
|
32
|
-
* const nanoid = customAlphabet('0123456789абвгдеё', 5)
|
|
33
|
-
* nanoid().then(id => {
|
|
34
|
-
* model.id = id //=> "8ё56а"
|
|
35
|
-
* })
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export function customAlphabet(
|
|
39
|
-
alphabet: string,
|
|
40
|
-
defaultSize?: number
|
|
41
|
-
): (size?: number) => Promise<string>
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Generate an array of random bytes collected from hardware noise.
|
|
45
|
-
*
|
|
46
|
-
* ```js
|
|
47
|
-
* import { random } from 'nanoid/async'
|
|
48
|
-
* random(5).then(bytes => {
|
|
49
|
-
* bytes //=> [10, 67, 212, 67, 89]
|
|
50
|
-
* })
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* @param bytes Size of the array.
|
|
54
|
-
* @returns A promise with a random bytes array.
|
|
55
|
-
*/
|
|
56
|
-
export function random(bytes: number): Promise<Uint8Array>
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto'
|
|
2
|
-
import { urlAlphabet } from '../url-alphabet/index.js'
|
|
3
|
-
let random = bytes =>
|
|
4
|
-
new Promise((resolve, reject) => {
|
|
5
|
-
crypto.randomFill(Buffer.allocUnsafe(bytes), (err, buf) => {
|
|
6
|
-
if (err) {
|
|
7
|
-
reject(err)
|
|
8
|
-
} else {
|
|
9
|
-
resolve(buf)
|
|
10
|
-
}
|
|
11
|
-
})
|
|
12
|
-
})
|
|
13
|
-
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
14
|
-
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
|
15
|
-
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
|
16
|
-
let tick = (id, size = defaultSize) =>
|
|
17
|
-
random(step).then(bytes => {
|
|
18
|
-
let i = step
|
|
19
|
-
while (i--) {
|
|
20
|
-
id += alphabet[bytes[i] & mask] || ''
|
|
21
|
-
if (id.length === size) return id
|
|
22
|
-
}
|
|
23
|
-
return tick(id, size)
|
|
24
|
-
})
|
|
25
|
-
return size => tick('', size)
|
|
26
|
-
}
|
|
27
|
-
let nanoid = (size = 21) =>
|
|
28
|
-
random(size).then(bytes => {
|
|
29
|
-
let id = ''
|
|
30
|
-
while (size--) {
|
|
31
|
-
id += urlAlphabet[bytes[size] & 63]
|
|
32
|
-
}
|
|
33
|
-
return id
|
|
34
|
-
})
|
|
35
|
-
export { nanoid, customAlphabet, random }
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { getRandomBytesAsync } from 'expo-random'
|
|
2
|
-
import { urlAlphabet } from '../url-alphabet/index.js'
|
|
3
|
-
let random = getRandomBytesAsync
|
|
4
|
-
let customAlphabet = (alphabet, defaultSize = 21) => {
|
|
5
|
-
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
|
6
|
-
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
|
7
|
-
let tick = (id, size = defaultSize) =>
|
|
8
|
-
random(step).then(bytes => {
|
|
9
|
-
let i = step
|
|
10
|
-
while (i--) {
|
|
11
|
-
id += alphabet[bytes[i] & mask] || ''
|
|
12
|
-
if (id.length === size) return id
|
|
13
|
-
}
|
|
14
|
-
return tick(id, size)
|
|
15
|
-
})
|
|
16
|
-
return size => tick('', size)
|
|
17
|
-
}
|
|
18
|
-
let nanoid = (size = 21) =>
|
|
19
|
-
random(size).then(bytes => {
|
|
20
|
-
let id = ''
|
|
21
|
-
while (size--) {
|
|
22
|
-
id += urlAlphabet[bytes[size] & 63]
|
|
23
|
-
}
|
|
24
|
-
return id
|
|
25
|
-
})
|
|
26
|
-
export { nanoid, customAlphabet, random }
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
let { nanoid, customAlphabet } = require('..')
|
|
4
|
-
|
|
5
|
-
function print(msg) {
|
|
6
|
-
process.stdout.write(msg + '\n')
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function error(msg) {
|
|
10
|
-
process.stderr.write(msg + '\n')
|
|
11
|
-
process.exit(1)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
15
|
-
print(`
|
|
16
|
-
Usage
|
|
17
|
-
$ nanoid [options]
|
|
18
|
-
|
|
19
|
-
Options
|
|
20
|
-
-s, --size Generated ID size
|
|
21
|
-
-a, --alphabet Alphabet to use
|
|
22
|
-
-h, --help Show this help
|
|
23
|
-
|
|
24
|
-
Examples
|
|
25
|
-
$ nanoid --s 15
|
|
26
|
-
S9sBF77U6sDB8Yg
|
|
27
|
-
|
|
28
|
-
$ nanoid --size 10 --alphabet abc
|
|
29
|
-
bcabababca`)
|
|
30
|
-
process.exit()
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let alphabet, size
|
|
34
|
-
for (let i = 2; i < process.argv.length; i++) {
|
|
35
|
-
let arg = process.argv[i]
|
|
36
|
-
if (arg === '--size' || arg === '-s') {
|
|
37
|
-
size = Number(process.argv[i + 1])
|
|
38
|
-
i += 1
|
|
39
|
-
if (Number.isNaN(size) || size <= 0) {
|
|
40
|
-
error('Size must be positive integer')
|
|
41
|
-
}
|
|
42
|
-
} else if (arg === '--alphabet' || arg === '-a') {
|
|
43
|
-
alphabet = process.argv[i + 1]
|
|
44
|
-
i += 1
|
|
45
|
-
} else {
|
|
46
|
-
error('Unknown argument ' + arg)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (alphabet) {
|
|
51
|
-
let customNanoid = customAlphabet(alphabet, size)
|
|
52
|
-
print(customNanoid())
|
|
53
|
-
} else {
|
|
54
|
-
print(nanoid(size))
|
|
55
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
let { urlAlphabet } = require('./url-alphabet/index.cjs')
|
|
2
|
-
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
|
|
3
|
-
let customRandom = (alphabet, defaultSize, getRandom) => {
|
|
4
|
-
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
|
|
5
|
-
let step = -~((1.6 * mask * defaultSize) / alphabet.length)
|
|
6
|
-
return (size = defaultSize) => {
|
|
7
|
-
let id = ''
|
|
8
|
-
while (true) {
|
|
9
|
-
let bytes = getRandom(step)
|
|
10
|
-
let j = step
|
|
11
|
-
while (j--) {
|
|
12
|
-
id += alphabet[bytes[j] & mask] || ''
|
|
13
|
-
if (id.length === size) return id
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
let customAlphabet = (alphabet, size = 21) =>
|
|
19
|
-
customRandom(alphabet, size, random)
|
|
20
|
-
let nanoid = (size = 21) =>
|
|
21
|
-
crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
|
|
22
|
-
byte &= 63
|
|
23
|
-
if (byte < 36) {
|
|
24
|
-
id += byte.toString(36)
|
|
25
|
-
} else if (byte < 62) {
|
|
26
|
-
id += (byte - 26).toString(36).toUpperCase()
|
|
27
|
-
} else if (byte > 62) {
|
|
28
|
-
id += '-'
|
|
29
|
-
} else {
|
|
30
|
-
id += '_'
|
|
31
|
-
}
|
|
32
|
-
return id
|
|
33
|
-
}, '')
|
|
34
|
-
module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { urlAlphabet } from './url-alphabet/index.js'
|
|
2
|
-
let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
|
|
3
|
-
let customRandom = (alphabet, defaultSize, getRandom) => {
|
|
4
|
-
let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
|
|
5
|
-
let step = -~((1.6 * mask * defaultSize) / alphabet.length)
|
|
6
|
-
return (size = defaultSize) => {
|
|
7
|
-
let id = ''
|
|
8
|
-
while (true) {
|
|
9
|
-
let bytes = getRandom(step)
|
|
10
|
-
let j = step
|
|
11
|
-
while (j--) {
|
|
12
|
-
id += alphabet[bytes[j] & mask] || ''
|
|
13
|
-
if (id.length === size) return id
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
let customAlphabet = (alphabet, size = 21) =>
|
|
19
|
-
customRandom(alphabet, size, random)
|
|
20
|
-
let nanoid = (size = 21) =>
|
|
21
|
-
crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
|
|
22
|
-
byte &= 63
|
|
23
|
-
if (byte < 36) {
|
|
24
|
-
id += byte.toString(36)
|
|
25
|
-
} else if (byte < 62) {
|
|
26
|
-
id += (byte - 26).toString(36).toUpperCase()
|
|
27
|
-
} else if (byte > 62) {
|
|
28
|
-
id += '-'
|
|
29
|
-
} else {
|
|
30
|
-
id += '_'
|
|
31
|
-
}
|
|
32
|
-
return id
|
|
33
|
-
}, '')
|
|
34
|
-
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
let crypto = require('crypto')
|
|
2
|
-
let { urlAlphabet } = require('./url-alphabet/index.cjs')
|
|
3
|
-
const POOL_SIZE_MULTIPLIER = 128
|
|
4
|
-
let pool, poolOffset
|
|
5
|
-
let fillPool = bytes => {
|
|
6
|
-
if (!pool || pool.length < bytes) {
|
|
7
|
-
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
|
|
8
|
-
crypto.randomFillSync(pool)
|
|
9
|
-
poolOffset = 0
|
|
10
|
-
} else if (poolOffset + bytes > pool.length) {
|
|
11
|
-
crypto.randomFillSync(pool)
|
|
12
|
-
poolOffset = 0
|
|
13
|
-
}
|
|
14
|
-
poolOffset += bytes
|
|
15
|
-
}
|
|
16
|
-
let random = bytes => {
|
|
17
|
-
fillPool((bytes -= 0))
|
|
18
|
-
return pool.subarray(poolOffset - bytes, poolOffset)
|
|
19
|
-
}
|
|
20
|
-
let customRandom = (alphabet, defaultSize, getRandom) => {
|
|
21
|
-
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
|
22
|
-
let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
|
23
|
-
return (size = defaultSize) => {
|
|
24
|
-
let id = ''
|
|
25
|
-
while (true) {
|
|
26
|
-
let bytes = getRandom(step)
|
|
27
|
-
let i = step
|
|
28
|
-
while (i--) {
|
|
29
|
-
id += alphabet[bytes[i] & mask] || ''
|
|
30
|
-
if (id.length === size) return id
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
let customAlphabet = (alphabet, size = 21) =>
|
|
36
|
-
customRandom(alphabet, size, random)
|
|
37
|
-
let nanoid = (size = 21) => {
|
|
38
|
-
fillPool((size -= 0))
|
|
39
|
-
let id = ''
|
|
40
|
-
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
41
|
-
id += urlAlphabet[pool[i] & 63]
|
|
42
|
-
}
|
|
43
|
-
return id
|
|
44
|
-
}
|
|
45
|
-
module.exports = { nanoid, customAlphabet, customRandom, urlAlphabet, random }
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate secure URL-friendly unique ID.
|
|
3
|
-
*
|
|
4
|
-
* By default, the ID will have 21 symbols to have a collision probability
|
|
5
|
-
* similar to UUID v4.
|
|
6
|
-
*
|
|
7
|
-
* ```js
|
|
8
|
-
* import { nanoid } from 'nanoid'
|
|
9
|
-
* model.id = nanoid() //=> "Uakgb_J5m9g-0JDMbcJqL"
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* @param size Size of the ID. The default size is 21.
|
|
13
|
-
* @returns A random string.
|
|
14
|
-
*/
|
|
15
|
-
export function nanoid(size?: number): string
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Generate secure unique ID with custom alphabet.
|
|
19
|
-
*
|
|
20
|
-
* Alphabet must contain 256 symbols or less. Otherwise, the generator
|
|
21
|
-
* will not be secure.
|
|
22
|
-
*
|
|
23
|
-
* @param alphabet Alphabet used to generate the ID.
|
|
24
|
-
* @param defaultSize Size of the ID. The default size is 21.
|
|
25
|
-
* @returns A random string generator.
|
|
26
|
-
*
|
|
27
|
-
* ```js
|
|
28
|
-
* const { customAlphabet } = require('nanoid')
|
|
29
|
-
* const nanoid = customAlphabet('0123456789абвгдеё', 5)
|
|
30
|
-
* nanoid() //=> "8ё56а"
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export function customAlphabet(
|
|
34
|
-
alphabet: string,
|
|
35
|
-
defaultSize?: number
|
|
36
|
-
): (size?: number) => string
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Generate unique ID with custom random generator and alphabet.
|
|
40
|
-
*
|
|
41
|
-
* Alphabet must contain 256 symbols or less. Otherwise, the generator
|
|
42
|
-
* will not be secure.
|
|
43
|
-
*
|
|
44
|
-
* ```js
|
|
45
|
-
* import { customRandom } from 'nanoid/format'
|
|
46
|
-
*
|
|
47
|
-
* const nanoid = customRandom('abcdef', 5, size => {
|
|
48
|
-
* const random = []
|
|
49
|
-
* for (let i = 0; i < size; i++) {
|
|
50
|
-
* random.push(randomByte())
|
|
51
|
-
* }
|
|
52
|
-
* return random
|
|
53
|
-
* })
|
|
54
|
-
*
|
|
55
|
-
* nanoid() //=> "fbaef"
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* @param alphabet Alphabet used to generate a random string.
|
|
59
|
-
* @param size Size of the random string.
|
|
60
|
-
* @param random A random bytes generator.
|
|
61
|
-
* @returns A random string generator.
|
|
62
|
-
*/
|
|
63
|
-
export function customRandom(
|
|
64
|
-
alphabet: string,
|
|
65
|
-
size: number,
|
|
66
|
-
random: (bytes: number) => Uint8Array
|
|
67
|
-
): () => string
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* URL safe symbols.
|
|
71
|
-
*
|
|
72
|
-
* ```js
|
|
73
|
-
* import { urlAlphabet } from 'nanoid'
|
|
74
|
-
* const nanoid = customAlphabet(urlAlphabet, 10)
|
|
75
|
-
* nanoid() //=> "Uakgb_J5m9"
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
export const urlAlphabet: string
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Generate an array of random bytes collected from hardware noise.
|
|
82
|
-
*
|
|
83
|
-
* ```js
|
|
84
|
-
* import { customRandom, random } from 'nanoid'
|
|
85
|
-
* const nanoid = customRandom("abcdef", 5, random)
|
|
86
|
-
* ```
|
|
87
|
-
*
|
|
88
|
-
* @param bytes Size of the array.
|
|
89
|
-
* @returns An array of random bytes.
|
|
90
|
-
*/
|
|
91
|
-
export function random(bytes: number): Uint8Array
|